February 9th, 2009 at 9:57 pm by Dr. Drang
It’s been over a year since I posted these scripts for getting
- the URL of the frontmost Safari document;
- a shortened version (using metamark.net) of the frontmost Safari document; and
- a shortened version of a URL on the clipboard.
Oddly, it wasn’t until today that someone—@ptujec in this tweet, to be exact—pointed out that the shortening scripts don’t work when the URL contains certain characters. Even more odd, I never ran into this problem myself, even though I use these scripts (or variants of these scripts—see below) almost daily. Still, I had to find the problem and correct it.
At first, I thought the problem was AppleScript misinterpreting an ampersand (&) in the original URL. Nope. Then I thought it was insufficient quoting in the argument passed to
curl. Nope, although the argument should be quoted for safety. The problem, which would have been avoided if I had paid more attention to the Metamark API, was that the special characters in the original URL weren’t being escaped before sending it to Metamark for shortening.
So I wrote a quick Python script for URL-escaping, which I called
1: #!/usr/bin/python 2: 3: from urllib import quote 4: from sys import argv 5: 6: if argv: 7: print quote(argv,'/:')
It replaces every character in the URL other than
with a code that looks like
nn is the hex code for the character. The original URL is the first argument to the command; the escaped version of the URL is printed to STDOUT.
With this utility made executable and saved in my
~/bin directory, I rewrote the AppleScripts.
surl now looks like this:
1: tell application "Safari" 2: set longURL to URL of front document 3: end tell 4: 5: set safeURL to do shell script "~/bin/escapeurl " & "'" & longURL & "'" 6: set cmd to "curl 'http://metamark.net/api/rest/simple?long_url=" & safeURL & "'" 7: 8: set shortURL to do shell script cmd 9: set the clipboard to shortURL as text 10: 11: tell application "Play Sound" 12: play "HD:System:Library:Sounds:Glass.aiff" 13: end tell 14: 15: open location "x-launchbar:hide" -- delete this line if you're using Quicksilver instead of LaunchBar.
The significant addition is Line 5, which escapes the original URL by calling the little Python script. Similarly,
scurl looks like this:
1: set longURL to the clipboard 2: set safeURL to do shell script "~/bin/escapeurl " & "'" & longURL & "'" 3: set cmd to "curl 'http://metamark.net/api/rest/simple?long_url=" & safeURL & "'" 4: 5: set shortURL to do shell script cmd 6: set the clipboard to shortURL as text 7: 8: tell application "Play Sound" 9: play "HD:System:Library:Sounds:Glass.aiff" 10: end tell 11: 12: open location "x-launchbar:hide" -- delete this line if you're using Quicksilver instead of LaunchBar.
TextExpander AppleScript snippets work by replacing the abbreviation—I use
;surl for this one, with the leading semicolon—with the output of the script. There’s no need to put the shortened URL onto the clipboard, so that line from the standalone script has been deleted. Because the creation of the shortened URL is obvious when the abbreviation is replaced by the output of the script, the clause that plays a sound has also been deleted. So has the LaunchBar-specific line at the end, because this version of the script isn’t run via LaunchBar.
Similarly, the TextExpander version of the
scurl script looks like this:
and has an abbreviation of
I think these changes will allow
scurl to handle any URL you throw at them. Thanks to @ptujec for bringing this bug to my attention.