AppleScript for the rest of us
Of all the programming languages I have learned, there are two that have consistently made me feel stupid.
Prolog and AppleScript.
At least with Prolog, I found I could provide it with enough random facts and it would eventually barf back an answer of ‘yes’ for whether or not my assignment was done. And, of course, Prolog has good jokes (thanks, Ray!):
Q: How many prolog programmers does it take to change a light bulb?
A: No.
AppleScript, on the other hand, continues to baffle me. All those english like sentences just confuse me. I constantly try to write code that is, well, like code and it doesn’t work.
Fortunately, there is appscript, a python module that makes any AppleScriptable application into something I can talk to just like any other Python object. This quite effectively reduces AppleScript programming to a programming exercise that my tiny little mind can effectively metabolize.
Furthermore, I can use appscript from within the command line interpreter (read this first to make sure the command line python interpreter is actually useful).
While grabbing appscript, you might also want to download HTMLDictionary. It dumps an appscript compatible HTML document describing any random application’s scripting dictionary.
After installing appscript, fire up the python interpreter and grab a reference to the iTunes application (yes, start it with pythonw — appscript requires a windowmanager connection):
[albbum:~] bbum% pythonw
Python 2.3.5 (#1, Jan 13 2006, 20:13:11)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import appscript
>>> iTunes = appscript.app("iTunes")
>>> print iTunes
app(u'/Applications/iTunes.app')
Great! Now what?
Fortunately, appscript has a built in help() command that will answer exactly that question:
>>> iTunes.help()
================================================================================
Appscript Help (-t)
Reference: app(u'/Applications/iTunes.app')
--------------------------------------------------------------------------------
Description of reference
Terminology for application class
Class: application -- The application program
Properties:
current_encoder : k.encoder -- the currently selected encoder (MP3, AIFF, WAV, etc.)
current_EQ_preset : k.EQ_preset -- the currently selected equalizer preset
current_playlist : k.playlist (r/o) -- the playlist containing the currently targeted track
.....
visual_size : k.small | k.medium | k.large -- the size of the displayed visual
Elements:
browser_windows -- index | name | id
....
windows -- index | name | id
================================================================================
app(u'/Applications/iTunes.app')
Oddly, help() doesn’t seem to show the commands available on the application reference. Fortunately, HTMLDictionary does.
Now I can can poke around the library a bit:
>>> pl = iTunes.playlists[3] >>> for p in iTunes.playlists(): ... print p.name() ... Library Party Shuffle Purchased 90’s Music My Top Rated Recently Added Recently Played Top 25 Most Played Videos burny burny Podcasts
Including diving all the way down to the tracks:
>>> for t in pl.tracks(): ... print t.name() ... Munich Who Will Love Me Now (Jimmy Gomez Mix) Cover Me (Trouser Enthusiasts Remix) Change (Angelic Remix) ....
You get the idea. There are tons of cool things that could be done with this tool in hand. Obviously, combining AppleScript with something like Twisted to build a network enabled gateway to your desktop.
Or you could use PyObjC to build standard Cocoa apps that interact with other apps via AppleScript directly in your app’s code. Of course, this would allow access to any random framework on the system either through the Objective-C APIs directly from Python or by compiling simple wrapper classes in Obj-C around any C or C++ API.
Fun.


March 24th, 2006 at 5:53 am
I don’t know a bit about Python but all this really sounds interesting.
I assume it doesn’t really help you to do things which just tend to fail in AppleScript, though. Or is there some higher magic in this than using a different language to send AppleEvents?
March 24th, 2006 at 10:49 am
I believe the reason that help() is screwed up with iTunes has to do with the way it declares its applescript dictionary. iTunes has a lot of quirks in Applescript that have come over from its OS 9 heritage.
March 24th, 2006 at 12:15 pm
How does appscript compare to gensuitemodule? It’s been a while since I last used that and found that it was pretty darned slow. It took quite a while to read in my iTunes library (only about 5k songs) via applescript. I ended up just slurping the plist instead. I suspect that the slowdown is in the fact that I’m using applescript altogether, but if appscript is any faster, that would certainly be a nice option!
March 24th, 2006 at 5:51 pm
gensuitemodule is cruft; broken and outdated.
aete came along and was much better, but has been deprecated in favor of appscript.
appscript seems pretty speedy and I have yet to really break it. It is still obviously using apple events under the covers, so there is a bit of communication overhead. But I was able to pull a large list of songs out of iTunes without a noticeable pause.
March 24th, 2006 at 6:48 pm
You know how regex (and, in some cases, perl) is a write-only language?
Well AppleScript is a read only language. You can read the scripts and understand whet they are getting at, but not enough to actually edit them and have them still work.
March 25th, 2006 at 8:44 pm
Kevin, that’s only about 50% true. While python is certainly a lot nicer than applescript, once you have spent a bit of time with applescript, it’s usually possible to cobble things together to do what you want, especially with some judicious googling. Then again, sometimes it’s just completely baffling.
March 25th, 2006 at 11:39 pm
bbum just talks from my heart.
(Yes I also only got into it via the pyhton binding,
and yes prolog always answered NO to me)
But the concept behind applescript just rocks.
It’s all about sending complex queries
just in one turnaround.
Basically Applescript did Years ago,
what a good webservice api should do.
Actually I was quite impressed,
how flexible python actually is.
In Python, it looks like a simple object traversal,
but on the wire it makes for a complex applescript query in the end.
I believe there’s a lot to be learned for the systems that we build.
~eike
May 25th, 2006 at 3:10 pm
[…] And, of course, the above demonstrates how trivial it would be to make various physical gestures control other aspects of your machine. Since I don’t actually use multiple desktops, I replaced the notification stuff with a call out to applescript to play the next track in iTunes. […]