Joe Maller.com

AppleScript source links from TextMate

AppleScript’s URL Protocol Support allows the full source code of an AppleScript to be shared through an encoded URL. Here’s a short little TextMate Command for converting AppleScripts to encoded URLs.

Create a new command in TextMate’s AppleScript bundle with the following code:

#!/usr/bin/env ruby -KA -rcgi
src = CGI.escape(STDIN.read)
src = src.gsub('+', '%20')
src = 'applescript://com.apple.scripteditor?action=new&script=' + src
`echo -n "#{src}" | pbcopy`
print "The URL encoded AppleScript was copied to the clipboard"

There’s no reason this idea can’t be used for all sorts of stuff. So why not make it easier, it’s not AppleScript, but here’s that code in Script Editor for easier copying.

This is exceptionally fast, much faster than Apple’s provided encoding script. As an extreme example, converting the 558 lines of my iPhoto Date Reset script took just under a minute using Apple’s script. The little Ruby script in TextMate does it instantly. (running the AppleScript in Script Editor with the Event Log Window open took nearly 7 minutes.)

Update: I committed this command to the TextMate Bundles repository and it’s now included in the default set of Bundles shipping with TextMate. (And slightly improved by other TextMate bundle developers)


RFC 822 Dates with AppleScript

Here’s a little AppleScript subroutine which converts date objects into correctly formatted RFC date strings: RFCdate() (click to open in Script Editor)

This is a timesaver for anything related to RSS, which requires dates be in the RFC 822 format, ie. Wed, 24 May 2006 01:30:22 -0400


Shell scripts in AppleScript are illegible

I got my FXScript Compiler working on the new machine and pulling sources from Subversion without too much trouble. But I decided that my practice of embedding shell scripts in AppleScript kind of sucks. It’s just desperately ugly. Tools like sed are ugly enough on their own, slashing and escaping every other character just makes them completely impossible to dissect after a few months.

For example, I print the following in the header of each file’s source code before compiling:

[tab] // [tab] Version: r145
[tab] // [tab] build200604181617
[tab] // [tab] April 18, 2006

One echo statement looks like this ($d and $b are already set and $b is formatted):

echo -e "\t//\tVersion: $d\n$b\n\t//\t`date '+%B %d, %Y'`\n\n

Not exactly pretty, except in comparison to this:

echo -e "\\t//\\tVersion: $d\\n$b\\n\\t//\
\\t\`date '+%B %d, %Y'`\\n\\n"

Echo is using the -e argument because these are being piped through other commands.

The real killer is anything involving regular expressions. Say a matching pattern needs to match a string containng double-quotes inside a double-quoted sed pattern. Then this already slash-infested command:

sed -e "s/\([Ff]ilter[\t ]*"[^"]*\)"/.../"

becomes this:

do shell script "sed -e "s/\\([Ff]ilter[\\t ]*\
\\"[^\\"]*\\)\\"/.../""

No part of me wants anything to do with keeping track of that many backslashes. It’s slightly better when using sed with the -E extended regex flag, but still.

In the ongoing pursuit of long term legibility, I’m putting my shell scripts functions into individual files inside the XCode project. More on how that works later.

[I know the main page template doesn’t work right when long strings break the column width, it’s on my long-term to do list]


Joe’s iPhoto AppleScripts updated for iPhoto 6

I just posted updated versions of my iPhoto Date Manipulation AppleScripts which now work with iPhoto 6.

This is definitely the best version of iPhoto yet, but the biggest positive change regarding scripting is that dates are now read/write properties. Before dates were read-only strings whose format would sometimes vary. Because dates can now be set as AppleScript date objects my long nightmare of UI scripting can finally come to a end. No more need to internationalize ambiguous dates, no more counting interface splitter groups to figure out what was visible, no more “keystroke”, and no more appallingly slow performance.

Another good part is that all my date logic was abstracted using proper date objects, so that all translated perfectly. Once I noticed that dates were finally writable, it took very little time to update the specific routines to work with the new version.

Now I feel like it would actually be worth my time to create Automator actions, the absurdly delicate nature of UI scripting would have previously made that a nightmare.


Joe’s iPhoto AppleScripts updated

I just posted updated versions of my iPhoto AppleScripts which hopefully address many of the problems related to System Events errors.

As I was trying to nail down what caused System Events to throw occasional errors I found a bug which was my fault. If any other windows were open in iPhoto, (info, keywords, Keyword Assistant), iPhoto would sometimes throw an NSReceiver error. All extra windows will now be closed before setting any dates. Apologies for not catching that sooner or thinking to check whether other windows were open. Hopefully that oversight will account for the majority of NSReceiver errors.

All window references should now be numeric, even though I’m fairly sure the window is always called “iPhoto” despite the active user language. (I deduced that from running the application under a variety of languages while internationalizing the date handling, the window title was always “iPhoto” even if everything else was not English and using non-Roman characters.)

iPhoto is now more assertive about coming to front, this should make running from Script Editor easier since dialogs won’t be popping behind iPhoto.

Every System Events command is now wrapped in an try block and a loop. Errors will cause that function to be run again after restarting System Events. I did this in the functions to try and maintain portability, but it made the code much uglier.

Random notes:

iPhoto 5’s adjustment windows are wacky. They report themselves as “AXUnknown”, with a possibly English localized name “HUD”. These windows do not respond correctly to a close window command

iPhoto 4 and iPhoto 2 reversed the numeric index of the date and title fields in the info pane. I must the only person in the world who noticed that. If I remember correctly there was no iPhoto 3. iPhoto 2 is not currently supported, for whatever reason it wasn’t correctly incrementing selections via Apple Events. If it’s a quick fix, I might get that working at some point since I have access to a machine with that version.


More on the System Events AppleScript bugginess

After a ton of testing and waves of frustration, I think this is finally ready to test again.

UIcheck() System Events Test Script 2 (UIcheck-100605-1525.zip, 10k)

Again, please run this and let me know what your results are, including OS version and a vague hardware description.

A few observations:

The script is much larger, but the re-useable parts are fairly self-contained. Most of the size comes from error logging and timing functions. Please feel free to pilfer whatever you want from this example.

One of the biggest problems noted by the previous test script was -609 “Connection is invalid” errors. Thanks to a great post and followup by Bill Cheeseman on the CocoaBuilder site, I figured out why those were happening.

Essentially, AppleScript was sending commands to an application which wasn’t ready yet or that was shutting down. For whatever reason, AppleScript doesn’t necessarily clear the reference to an application that’s been sent a quit command. It’s possible, and quite likely that sending a command to an application immediately following a quit command won’t restart the application, it will cause a -619 connection error since AppleScript will try to send the command to the vanishing application.

Additional testing proved that hypothesis. Several other applications all threw -619 errors when cycled too quickly. So these errors weren’t the issue. There were still occasional “-50 Parameter error” errors, which seem to occur randomly whenever sending a command to System Events. These appear to be the most traceable problem I’ve found.

That noted, System Events seems incredibly slow to quit. On 10.3.9 it requies two tries almost every time. After testing some delay statements to pause the script, I ended up looping around a try statement which quits and re-launches the application. If the application responds correctly, the try doesn’t fail and the repeat is exited.

Hopefully this will continue to work. In testing I found the scripts seems sensative to humidity, mean looks, cute girls and smelly lunches. They’d work one day and fail inexplicably the next. This iteration however, seems to be working.

The next step is to build in an error-catching loop into the iPhoto date setting routines to make sure the script doesn’t fail and skip over any photos.

Previous posting on this topic is here: AppleScript System Events Bug

Update Thanks to everyone who helped test this, I’ve rolled these functions into my iPhoto AppleScripts which should be more robust now.


AppleScript System Events Bug

Despite the number of people successfully using my iPhoto AppleScripts, I’ve had a troubling number of people report problems as well. These weren’t just little problems, the scripts completely failed to run.

I asked several of these people to run the scripts from Script Editor and send me the error message they got when the scripts failed. All but one of the problems happened during a call to the System Events background application. Most infuriating was the fact that I couldn’t reproduce the problem. Today I managed to recreate what I believe is the problem.

The script below is a test script which pounds on System Events then tries to detect and recover from System Events crashes.

UIcheck() System Events Test Script (UIcheck.zip, 4k)

Please download the script and post your results in the comments. I’m seeing a consistent 3-9% failure rate for System Events on my PowerBook.

This is public domain, use at your own risk, etc. Please post improvements if you have them.

Update: Please post your OS version alongside any results.

Update 2: More on the System Events AppleScript bugginess Including a new test script.



« Previous PageNext Page »