Applescript/Python script for url shortener

I had an Applescript to use the bit.ly url shortener. In fact I had two of them: one takes the current Firefox URL as input, and the other one takes the clipboard as input. Moreover I preferred the new j.mp instead of bit.ly because it saves 2 characters.

Actually j.mp is an alias for bit.ly,and you can get a shortened URL from a long URL by getting the contents of http://bit.ly/api?url=<long url>. But it only works properly if the long url is urlencoded (special characters replaced with %xx). Originally I just called curl to get the contents (the shortened URL) from the constructed URL but that gave problems with URLs containg characters like &. Doing the urlencoding in Applescript is nasty. In Python there just is a method for it so it is much easier. Also doing the equivalent of curl is very easy in Python.

You can use it with j.mp instead of bit.ly but then it returns a bit.ly URL instead of j.mp. This is not the case if you use it from a form on the web page http://j.mp. Fortunately, just replacing the bit.ly with j.mp in the output gives a valid URL.

I use the following Python script to do the work:

#!/usr/bin/env python

# Usage: urlshort shorterprefix url [x y]
# E.g. urlshort 'http://bit.ly/api?url=' 'http://pieter.vanoostrum.org'
# returns shortened url on stdout
# If x and y are given x is replaced by y in the short url

import sys, urllib

fd = urllib.urlopen(sys.argv[1] + urllib.quote(sys.argv[2]))
shorturl = fd.readline().strip()

if len(sys.argv) == 5:
   shorturl = shorturl.replace(sys.argv[3], sys.argv[4])
sys.stdout.write(shorturl)

I then call this python script in two Applescripts:

The first one gets the input URL from the top most window in Firefox:

tell application "Firefox" to set theURL to «class curl» of window 1

ignoring case
    if ((characters 1 through 4 of theURL as string) is not "http") then
        return "Malformed URL."
    else
        set curlCMD to ¬
            "urlshort 'http://j.mp/api?url=' '" & theURL & "' bit.ly j.mp"
        -- Run the script and get the result:
        set tinyURL to (do shell script curlCMD)

        set the clipboard to tinyURL
    end if
end ignoring

The other one takes the clipboard as input.

set the theURL to (the clipboard as string)

ignoring case
    if ((characters 1 through 4 of theURL as string) is not "http") then
        return "Malformed URL."
    else
        set curlCMD to ¬
            "urlshort 'http://j.mp/api?url=' '" & theURL & "' bit.ly j.mp"

        -- Run the script and get the result:
        set tinyURL to (do shell script curlCMD)

        set the clipboard to tinyURL
    end if
end ignoring

One thing that’s missing is some kind of feedback when the script is finished. I try to paste the resulting short URL sometimes before it is there. Sometimes I can see it from which window has focus, but that is fragile. I am thinking of using Growl. And also the common part of both scripts should be factored out. Certainly when I add Growl support. DRY! (Don’t repeat yourself)