Tag Archives: AppleScript

Scripting iPhoto 09 with Ruby

I upgraded to Apple iLife 09. My main motivation was to get the new version of iPhoto, which adds support for face recognition and GPS integration.

When I fired up the new iPhoto, I discovered that the GPS data for my images in JPEG format had been read in correctly; but that all of my Canon raw CR2 files had been ignored, even though the photos of Hamburg mostly had GPS data.

I investigated whether iPhoto was scriptable. If I could add the GPS coordinates to the existing photos via AppleScript, I could take the GPS track logs and build an importer. Unfortunately, though, there’s no AppleScript interface to the GPS metadata, according to iPhoto’s AppleScript dictionary.

Experimenting further, I discovered that if I rooted around inside the iPhoto library (using right click and "Show contents"), copied the CR2 files out, and imported them into iPhoto again, that the GPS data would be processed correctly.

There was a snag, though. If I did that, I would lose all the names and descriptions I had entered in iPhoto. This was a solvable problem, though: iPhoto remembers the original filename, and has AppleScript properties that let you read and write the description/comment and name/title of any image.

The next small snag was that I don’t know AppleScript. I’ve tried to learn it, but I find it very annoying and syntaxy. I considered giving it another go, but I did a few quick Google searches and determined that AppleScript lacks hashes, arrays, and most other useful data structures that you might use to store and retrieve a set of captions for a large number of photographs indexed by filename.

Ruby to the rescue. When Apple created AppleScript, they did it by layering it on top of a lower level system called OSA or Open Scripting Architecture. This is a language-independent API, which means that you can glue any scripting language to it, and instantly be able to do anything in that language that you can do in AppleScript. There are a couple of projects which link OSA to Ruby; I picked RubyOSA , though a brief exploration of rb-appscript (a port of a Python bridge, spit ) suggests that it would have done the job too.

A quick sudo su and gem install ruby-osa , and I was ready to script iPhoto using Ruby. I built two scripts. The first, iphotodump.rb , dumps out all the titles and comments for the selected photos, storing them in data files using Ruby’s standard marshalling (persistence) mechanism. The second script, iphotorestore.rb , reverses the process: it reads in the data files, then scans through the selected images and restores the appropriate metadata by matching up the filenames of the original image files.

I ran iphotodump to dump out all the metadata for my Hamburg photos, deleted them from iPhoto, re-imported the CR2 files, then ran iphotorestore to restore the metadata. Problem solved.

I imagine there are other people out there with similar iPhoto-related metadata problems, so hopefully my scripts can point the way at solutions. With iPhoto glued to Ruby, there are all kinds of possibilities–for example, you have the power to do a full regular expression search and replace, with Perl-like regular expression power. I think I’m also going to write something to append the photo’s keywords to the description, so I can then go on a keyword deleting spree but still be able to find photos using search.

set this to the the subject of the top livejournal posting

I decided I could now face the SF movie footage. I started importing it… but there was a snag.

I’d used a wireless mono mic with the camcorder. Unfortunately, even when the camcorder is set to play mono audio, iMovie imports as stereo—so I get a bunch of movie files with sound in the left channel only.

I thought about this for a while, and experimented with QuickTime Pro until I found a sequence of actions that would achieve a conversion: Open the movie, extract the audio track to a second movie, export that to mono AIFF, go back to the movie and remove the audio track, add the mono AIFF file prepared earlier, export the movie to a DV stream, and then trash the AIFF file.

Kinda painful. I didn’t fancy doing it a couple of hundred times. So… AppleScript to the rescue! An hour or so later, I had learnt enough AppleScript to write an application which will batch-process a bunch of iMovie DV clips dropped onto it.

I think I may need more hard drive space, but we’ll worry about that later… I can always get a cheap external Firewire drive, I was kinda planning on doing so anyway.