2718.us blog » shell http://2718.us/blog Miscellaneous Technological Geekery Tue, 18 May 2010 02:42:55 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 Simplifying the Assembly of Localizations in Xcode http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/ http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/#comments Thu, 22 Apr 2010 20:11:51 +0000 2718.us http://2718.us/blog/?p=254 A comment on a bitbucket fork of Murky led me to “Automatically localize your nibs when building“, which suggests a great way to automate the hard developer-side stuff in localizing in Xcode–pulling the original strings from the XIB files and putting the translated strings back in.  You absolutely should read the original blog post there, because I cannot adequately explain the big-picture part of the idea with a short quote.

My one complaint with the setup described is that the script for the “Run Script” build phase described there is a maintenance headache that I could do without.  Here’s my solution:  Create two new build targets, both of the “Shell Script” type–these are targets that just run a shell script, so they are created with only a “Run Script” build phase.  I called my two new targets “Create/Update English .strings files” and “Create/Update l10n XIBs” but you can call them whatever you want.

In the “Create/Update English .strings files” target’s “Run Script” phase, the script is:

# Create/Update English .strings files
  1. for xibFile in "$PROJECT_DIR/English.lproj/"*.xib; do
  2.  ibtool –generate-strings-file "${xibFile}.strings" "$xibFile"
  3. done
  4. exit 0

This uses ibtool to create a strings file for every XIB in the English localization (from foo.xib, foo.xib.strings will be created).

In the “Create/Update l10n XIBs” target’s “Run Script” phase, the script is:

# Create/Update l10n XIBs
  1. originalResourceDirectory="$PROJECT_DIR/English.lproj"
  2. for localizedDirectory in "$PROJECT_DIR/"*.lproj; do
  3.  if [ localizedDirectory != originalResourceDirectory ]; then
  4.   for xibFile in "${originalResourceDirectory}/"*.xib; do
  5.    xibBaseName=$(basename "${xibFile}")
  6.    ibtool –strings-file "${localizedDirectory}/${xibBaseName}.strings" \
  7.     –write "${localizedDirectory}/${xibBaseName}" \
  8.     "$xibFile"
  9.   done
  10.  fi
  11. done
  12. exit 0

This goes through every .lproj directory except English.lproj and uses ibtool to apply the .xib.strings files in those localizations to the XIB files in English.lproj.

By having these as two separate targets, they aren’t run every time I build and each part can be run on its own, on demand.  By using the power of shell scripting, I avoid having to alter the scripts for every new localization or XIB.

]]>
http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/feed/ 0
More Hackery with Slug Asterisk http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/ http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/#comments Mon, 18 Aug 2008 05:29:32 +0000 2718.us http://2718.us/blog/?p=95 I wanted to make my slug running Asterisk do wakeup calls, since I currently pay $11/month for a daily wakeup call service and they’ll only try up to 4 times.  As my starting point, I was using this dialplan from the-asterisk-book.com:

  1. [hotel-intern]
  2. exten => _*77*XXXXXXXXXXXX,1,Answer()
  3. exten => _*77*XXXXXXXXXXXX,n,Set(year=${EXTEN:4:4})
  4. exten => _*77*XXXXXXXXXXXX,n,Set(month=${EXTEN:8:2})
  5. exten => _*77*XXXXXXXXXXXX,n,Set(day=${EXTEN:10:2})
  6. exten => _*77*XXXXXXXXXXXX,n,Set(hours=${EXTEN:12:2})
  7. exten => _*77*XXXXXXXXXXXX,n,Set(minutes=${EXTEN:14:2})
  8. exten => _*77*XXXXXXXXXXXX,n,NoOp(Wake-up call scheduled for ${CALLERID(num)} at ${hours}:${minutes} on ${day}.${month}.${year}.)
  9. exten => _*77*XXXXXXXXXXXX,n,System(echo -e "Channel: SIP/${CALLERID(num)}\\nContext: wake-up\\nExtension: 23" > /tmp/${UNIQUEID}.call)
  10. exten => _*77*XXXXXXXXXXXX,n,System(touch -t ${year}${month}${day}${hours}${minutes} /tmp/${UNIQUEID}.call)
  11. exten => _*77*XXXXXXXXXXXX,n,System(mv /tmp/${UNIQUEID}.call /var/spool/asterisk/outgoing/)
  12. exten => _*77*XXXXXXXXXXXX,n,Playback(rqsted-wakeup-for)
  13. exten => _*77*XXXXXXXXXXXX,n,SayNumber(${hours})
  14. exten => _*77*XXXXXXXXXXXX,n,SayNumber(${minutes})
  15. exten => _*77*XXXXXXXXXXXX,n,Hangup()
  16.  
  17. [wake-up]
  18. exten => 23,1,Answer()
  19. exten => 23,n,Wait(1)
  20. exten => 23,n,Playback(this-is-yr-wakeup-call)
  21. exten => 23,n,Wait(1)
  22. exten => 23,n,Hangup()

The problem is that my slug is unslung, running busybox for most basic *nix tools and busybox’s touch command doesn’t support the -t option, so I can’t set the modification time on the file to properly queue it.  My half-assed workaround is a shell script (because I couldn’t get the System() command to run the whole string, try as I might) that nohups a background shell process that sleeps for the difference in seconds between now and the wakeup time, then creates the call file.  Not great for far-future scheduling or for large numbers of calls and it won’t survive a reboot, but it’s a start.

#!/bin/sh
  1.  
  2. nohup sh -c "sleep $((`/bin/date –date="$1" +"%s"` – `/bin/date +"%s"`)) ; echo -e 'Channel: $2\\nContext: wake-up\\nExtension: 23' > /tmp/$3.call ; mv /tmp/$3.call /opt/var/spool/asterisk/outgoing/" >/dev/null &

My Asterisk diaplan macro passes the target time/date string as the first argument, the target channel as the second, and the ${UNIQUEID} as the third.  One further wrinkle:  busybox 1.3.1, which was what came with the unslung firmware I used, doesn’t have nohup, so it won’t work; busybox 1.10.3 is what ipkg installed into /opt/ and has nohup, but the date command in 1.10.3 didn’t seem to support –date (at all, or maybe just not properly), so nohup is a reference to the 1.10.3 busybox in /opt/bin while /bin/date is a reference to the original 1.3.1 busybox.  Stupid, but it works.

(Oh, and as I told the last person I saw wearing a t-shirt that said “If it’s stupid, but it works, then it isn’t stupid,” there’s definitely such a thing as works-but-stupid–this script hackery is such a thing.  The better solution, space permitting, is probably just to install the coreutils package so as to have proper non-busybox touch and date)

]]>
http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/feed/ 0