As you see, I didn’t find any good here. This is going to be a bit of a personal rant about Apple’s technologies, so if you don’t care about Apple at all, and you subscribe to the idea that you don’t have to know what your competitors are up to, then you’re suggested not to read the post.
Situation — quite a long one, so feel free to skip.
If you follow my blog with stability you probably remember the print shop for which I had to work around NATs and which pays me about a fifth of what I’m worth — mostly because I still consider them friends. A couple of months ago they moved from their original telco and ISP (FastWeb), to the ex-monopolist telco and ISP (Telecom Italia), with quite a bit of relief from my side, as that meant dropping the whole charade of IPv6 over miredo, and just using DMZ to connected to the jumphost without caring about IPv6 dynamic hosts (which I actually had to resurrect for another customer, but let’s leave it at that).
I have kept warning my customer that they’d lose their fax number if they switched telco; but when the marketeer who sold them on the move explicitly assured them (twice) that both the fax and the phone numbers would be recovered, they decided to ignore the fact that I’ve been working in their best interest for the past few years. Turns out that I knew better: the fax number was dismissed by the original telco and lost in the transition. And faxes are (unfortunately) still a big deal in Italy.
Thankfully, I’ve been ready: a friend of mine operates a virtual telco with VoIP phone and fax lines, and I knew he had a decent service of fax to mail, and fax by mail gateway. I referred them to him quickly, and a new fax line was easily established. Or maybe not so easily. While receiving fax worked out of the box, sending them turned out to be a bit more complicated: only one PDF document at a time could be faxed, which was never an issue for me, but, most worrisome, the PDF documents produced by their (industrial) printer, a Xerox DocuPrint 700, caused the GhostScript used by the server for the conversion, to crash.
Given that fixing this on the server side is non-trivial (the crash is reproducible but it’s a very convoluted situation that causes it to happen, and Ubuntu Server has no updates for the ghostscript package), I had to find an alternative route to solve the problem. Given I’m a developer and scripter, the solution was obvious: I wanted to script the conversion of the files to something easier for GhostScript to digest, and while I was at it simplify the whole procedure by just asking the secretary for the destination fax number and the files she wanted to send.
Introducing the Bad and the Ugly
Apple provides two main technologies/techniques to script their Mac environments: the “old-fashioned” AppleScript, which is an “usual” scripting language, with the difference of being very well integrated, having a relatively natural language syntax, and being byte-compilable into applications; and since Tiger a shiny, GUI-based scripting system called Automator.
I had already a brief introduction to the former, but I needed something more to write the kind of script I wanted to provide to my customer, so I made good use of the Safari Books Online trial (I’m almost certainly going to subscribe, as it happens) and looked up a couple of titles on the topic: Learn AppleScript by Sanderson and Rosenthal, and Apple Automator with AppleScript by Myer. Then I dug into the topic for the whole afternoon.
Writing the first draft of the script was quite easy, but then I remembered that the only reason why I have GhostScript available on my laptop was because I used fink and other package managers there. The iMac used by the secretary wouldn’t have those at all (and I don’t intend on installing them just for this); plus there is no free distribution of GhostScript prebuilt for Mac, so I started looking at alternative approach.
A quick googling around can tell you that while there isn’t a direct scriptable application that can be used to merge and convert PDF documents, there is an Automator action to do so, so I started looking into that technology as well. The idea behind it is extremely cool: instead of writing code by the syntax, it allows you to build logic trains of actions with input and output. The basis for what I was needing, was actually easily described with a simple train: get the user to choose some files, transform all of them in PDF if they aren’t already; merge all of them in a single document, create a new email message with that file attached, and send it.
Of course it’s not as straightforward as it might appear at a first glance: the email needs to be fired at a particular address, for the fax to be sent, which depends on the fax itself; the produced merged PDF document needs to be stored in a temporary location and removed after the mail is properly sent, and so on. To make the tool more useful, Apple also provides support for both default and custom variables, all of it designed with drag’n’drop.
Since you probably see now that Automator at least appears cool, it is obviously not the Ugly of the story, but rather the Bad. While Automator allows to combine a series of trains, by saving results in variables and then retrieving them, it does not allow multiple inputs to an action: those strictly need to be passed as variable. But not all fields of an action can be set with a variable! Interestingly enough, you cannot set the name of the merged PDF document through a variable, although you can change the path it is generated in that way. You also cannot choose the destination of an email message through a variable, but you can change the subject. Oh and while you can choose which files to select, you have no way to restrict the selection to a given type of documents. It’s ludicrous!
So while Automator could possibly be helpful for the few people who have an idea of how (at a high level) applications work, but still have no clue about implementing one. I can’t think of many people like that, to be honest. On the other hand AppleScript is a powerful tool, which enabled me to complete the task I had to take care of quite nicely. Apple’s design of Applets and Droplets, with the ability to combine the two is one of the nicest things I have seen in a very long time. Unfortunately, it is just Ugly.
Don’t get me wrong, it’s not the syntax itself that is ugly; it actually reminds me enough of Ruby to actually be enjoyable to write. And the basic commands are easy to grasp even for one who’s not a hardcore programmer. The problem is that from a clean design that pre-dated OS X, the current situation is .. messy. Files are accessed by default using the so-called HFS path, which looks something like
Macintosh HD:Users:flame:something even though the OS is now almost entirely written with Unix paths in mind; if you wish to call into the Unix toolset (which I had to, to combine the PDFs, as I’ll tell), you got to convert this to the Unix-style path.
This by itself wouldn’t be that much of a limitation; a bother yes, but not a limitation as such. What makes it difficult to deal with is that even some of Apple’s own applications expect paths to be passed Unix style! This is the case for instance of Apple Mail 3.0, which made me waste two hours guessing why oh why I could ask Preview to open the file, but I was still unable to attach it to the outgoing mail message.
The ugliest part refers to merging the PDF files; as I said, using GhostScript was easy, but having GhostScript installed isn’t, so I avoided that solution. One obvious method would have been to ask Preview to merge the PDF files, given that it can do that. But Apple didn’t make Preview scriptable by default, and I wished to avoid tinkering with settings I would most likely forget about when (not if) I’d deploy the script again somewhere else.
Turns out that the implementation for Automator’s merge action boils down to a single Python script, which can easily be launched separately (Apple even provided usage documentation!). So at the end, the conversion is done through that, even though it means that I have to call into the Unix shell to complete the task, which takes a bit of time.
This all together makes AppleScript definitely the Ugly. But at least it’s something, I guess.
I remember KDE 3 having some support for this through kdialog and DCOP, I wonder how the situation is now; as far as I can tell, even though dbus should provide an even more complete interfacing to applications, it isn’t as easy to integrate workflows without being a developer, on GNOME 2. I wonder how GNOME 3 is dealing with this.