Flickr and iPhoto across the Scripting Bridge
Now I'm running Mac OS X 10.5, I thought it might be fun to use this as an exercise in using Ruby to call Objective C, and hence the new Scripting Bridge. Together, this means you can call AppleEvents (the interprocess communication layer that underlies AppleScript) from a Ruby script, and that script can also access the rest of the ObjC APIs.
Getting started was pretty straightforward. There's a good overview on Apple's developer site which gets you going, and I lifted a small piece of code from Tom Insam's Shelf that allows you to see all the methods you can call on an ObjC object (which, handily, includes ones you can fetch from AppleEvents). (It's the dump routine from extractor.rb.) Pretty rapidly I could loop through my iPhoto library, pulling out dates and keywords, and I've had enough experience with rflickr to do the same with my remote photos, once I'd applied a couple of strategic patches. A bit of hash-munging and I had two data structures I could use to find matching photos (by datestamp) and tag them.
Unfortunately, this is where I hit a big speedbump. iPhoto 7's keyword adding interface has improved massively, but not, unfortunatly, from the scripting side. It's impossible to add a keyword that's not already defined, and even adding one that is requires that the photo be highlighted in the app. This is horrific - it potentially means that the user can interact with the program between the selection and the tagging and muck things up.
I also ran into what seemed to be a Scripting Bridge bug. Despite hitting the right syntax, the AppleEvent sent by Ruby (and Python - I tried both) ended up not working. I looked at the debugging output from all three, and it seems as if only AppleScript and Script Editor send the right parameters for a call that doesn't have a return value. In the end, I dropped back to using a shell call to osascript. Sigh. Maybe I'll change to using filesystem metadata.
Thankfully, tagging at the Flickr end was far easier (although their use of space-delimited tags means there's an annoying amount of faffy quoting), and now I have a script that will find the most recent 100 photos on Flickr, and see if they're in iPhoto. If so, it'll add the "flickr" tag to them (if necessary), while Flickr gets two machine tags (so they don't scare real people), one with the original file name and the other with the location of the current iPhoto image. (This isn't technically the same as the image that was uploaded, unfortunately, but it's still useful.)
The script is currently very much "programmer quality" - you need to be able to get a Flickr API key and know where to edit it into a Ruby script, plus it has a few caveats (as I said, it'll only do 100 photos, and it's also going to get confused if you have more than one image a second) - but if you're interested, feel free to download it and give it a go. (You can see the Flickr-side machine tags on most of my recent photos.) If you're at all interested in scripting applications, it might have a few useful tips, too.
So, what have we learnt?
- Flickr's API is pretty cool. Ruby's Flickr libraries are bitrotten.
- Scripting Bridge and language support in 10.5 is pretty cool too.
- Unfortunately, it's not entirely bug free, and the bugs are baffling.
- Some applications have rubbish scripting definitions.
- Tom Insam is full of useful hints for programming.
I think that'll do for one weekend.
Comments