AWS Automator Actions
Automator has always been one of those OS X features that I feel never gets enough attention, except when it’s in one of those “comparison” articles that always seems to mention it because it’s so unique and novel; but once the initial wave of First Look and Sneak Peek and Oh-my-God-I-can’t-believe-we’re-the-only-magazine-covering-this articles dies out, you never hear about it again, even though there is, in fact, a fairly active community of users and developers around it.
In fact, Snow Leopard added, with little fanfare, many useful features to Automator 2.1; the most interesting among these, I think, is the ability to run shell scripts in anything that emulates a shell, including Python (and Ruby, and Perl). Now, of course, there had been hand-made solutions to this before (Automator’s extendability being another not-often-touted feature) but having it built-in just makes distribution and adoption easier. Apple’s version, as well, seems a bit simpler since it doesn’t use the PyObjC bridge to pass around the full AppleScript event descriptor, instead just passing the text in through
stdin. Of course this means it’s strictly less powerful than Johnathan’s version, but let’s face it — if you really need to be using this bridge, it’s probably overkill for Automator anyway. Besides, it’s almost always possible to save whatever kind of data you need (an image, most commonly) to a temporary file in
/tmp and just pass the path to Python, anyway.
Anyway, although I’m not a heavy Automator user by any stretch (most people who can write proper scripts aren’t, after all), I’m a big proponent of it as an idea, particularly in the way it easily allows non-technical users to automate away a lot of the tedium that comprises the majority of many people’s computing experience. And even if you can script something in the traditional way, Automator is often the easiest way to Cocoa-ize a simple script so that it can grab selections from Finder, insert itself into the Services menu, etc. Yesterday I wanted to do something to this effect — an easy way to upload directory structures to S3, sort of as an impulse click rather than going through the trouble of opening up a client, etc., since it’s an operation Rachel and I perform manually all the time. It was delightfully simple to use Automator to pass in Finder selections to a simple Python script that did the heavy lifting. Without Automator, the boilerplate would have been many times longer than the remarkably simple script itself:
import os import sys AWS_ACCESS_KEY = sys.argv AWS_SECRET_KEY = sys.argv bucket_name = sys.argv.lower() return_url = "" files =  for f in sys.argv[4:]: files.append(f) sys.path.insert(0, '/sw/lib/python2.6/site-packages') import boto import boto.s3 as s3 from boto.s3.key import Key def recursively_upload(f, prefix = ''): if (os.path.isdir(f)): for ff in os.listdir(f): recursively_upload('/'.join([f, ff]), ''.join([prefix, f[f.rindex('/')+1:], '/'])) else: global return_url k = Key(bucket) k.key = ''.join([prefix, f[f.rindex('/')+1:]]) k.set_contents_from_filename(f, policy='public-read') return_url = "".join(["http://", bucket_name, ".s3.amazonaws.com/", k.key]) conn = boto.connect_s3(AWS_ACCESS_KEY, AWS_SECRET_KEY) bucket = conn.create_bucket(bucket_name, location=s3.connection.Location.DEFAULT) for f in files: recursively_upload(f) print return_url
The only gotcha is the
sys.path.insert(0, '/sw/lib/python2.6/site-packages') line, which is there because the sandboxed shell that Automator spawns has no access to
PYTHONPATH or anything; you have to programatically load third-party modules if you want them. The module, in this case, is boto, an AWS library for Python; you’ll have to change that line to the appropriate path for your installation if you want to run it (or, if you installed
boto-py26 through Fink, don’t do anything). When you combine the above script with the following Automator workflow:
Simply saving that in Automator automatically gives you what you see on the right here. Also, I took both these screenshots in just a few seconds with another Automator script that took just a few minutes to write that automatically takes a screenshot, uploads it to S3, and puts the link into your clipboard. Both of these scripts and workflows are available from my Codebook GitHub repository.
Of course, I think it would be infinitely better to have native Automator actions for common AWS operations, but that would require a solid Objective-C library first, of which there aren’t any yet 😦