URL Extender SystemI was sifting through my previous blog after Jeffery Zeldman kindly sent a lot of visitors in that direction for some TextMate starter tips. Whilst milling around, I stumbled upon an old trick I used to use in Quicksilver (before I gave up on it1), but had forgotten about since.

It’s a very simple little shell command which uses curl to track down the destination of a shortened url (or any link with a redirect). It works with an assortment of services, including bit.ly, tinyurl.com, ow.ly, etc. It returns the destination address (the original url), and you can pass that on to whatever you like!

Side note: I’ve been working on a little site called JustTheLinks which makes liberal use of url-lengthening. It grabs all of your tweets from your home timeline which contain links, and creates a live-updated list with expanded urls and titles. It uses PHP’s curl to do the trick, so it’s the same concept. It’s “in-progress,” but feel free to check it out at http://justthelinks.com!

Anyway, I decided to update the Quicksilver action and adapt it for some other uses. I’m happy to report that it’s still quite useful as a command line script, a LaunchBar action or a System Service. This post has code for all three, so take your pick!

The curl command in this script has two options specified, -I and -s. -I tells it to fetch only the headers of the requested URI, and the -s tells it to suppress error messages (silent). The result is a short response which contains the location of the redirect, which is piped to awk. We look for the line in the response containing “Location” and print the second field of that line, which is the destination url. Here are a few ways I thought of to put it to use:

Terminal

The first thing I did was whip up a shell script to run from the command line. Just create a text file wherever you keep scripts2, or make a new directory somewhere for it. Paste in the code below, and name it something that makes sense to you. I went with follow, because it’s following the redirect path, and expand was taken (and lengthen didn’t seem as much fun to type…). The script looks for a single argument, which would be the shortened url, and if it doesn’t receive one it tries the clipboard. So, if you already have the url in your clipboard, which is a pretty safe bet in this case, you can just run the script with no arguments.

#!/bin/bash

if [ $# -eq 0 ]; then
  curl -Is `pbpaste` | awk '/Location/ { print $2 }'  
else
  curl -Is $1 | awk '/Location/ { print $2 }'
fi

LaunchBar

I heart LaunchBar. Like Quicksilver, you can easily build “actions” for it that act on different types of input. This one just acts on text you paste or send to it, and assumes it’s going to be a shortened URL. After it lengthens it, it just displays the result as large popup text. If you wanted to, you could easily have it open location or whatever, but the whole point is just to see where you’re going, right?

This just goes into ~/Library/Application Support/LaunchBar/Actions as a compiled AppleScript (scpt) file. Open AppleScript Editor and paste in the code below (or just click here to open it automatically in your editor). Save the file to the Actions folder and give it a name you’ll recognize. Mine’s called ‘Expand Shortened URL.scpt’. Clever, I know. Here’s the code:

on handle_string(message)

	tell application "LaunchBar"
		set _res to do shell script "curl -Is " & message & " | awk '/Location/ { print $2 }'"
		display in large type _res
	end tell

end handle_string

Snow Leopard Service

Lastly, here’s a System Service that you can run on selected text in any Cocoa application. I’ve previously posted a Service for shortening urls, so here’s the opposite. This one can actually take a whole block of text and will scan for any and all links in it, attempting to lengthen and replace any shortened urls in the text. Here’s how to build it:

  • Open Automator.app
  • Select “Service” from the new file menu
  • Set “Service receives selected” to “text” in “any application”
  • Check the “Replaces selected text” box
  • Find the “Run Shell Script” action on the left and drag it into your workflow on the right
  • Set the Shell to Ruby (in this case)
  • Paste in the code below
  • Save the file to the ~/Library/Services folder, named something like “Expand shortened urls in selection” (or something more interesting)

Now, when you select text in any Cocoa application (Safari, Mail, TextEdit, etc.), you’ll be able to find your Service in the Services submenu of either the application menu in the menubar, or in the contextual menu that comes up when you right click (ctrl-click) the selected text. When you run it, it will replace your text with a new version with any shortened urls in it expanded.

#!/usr/bin/env ruby -rjcode -Ku

require 'open-uri'

input = STDIN.read
links = input.scan(/\b((?:https?:\/\/)(?:www\.)?([^\/]+)\/[a-zA-Z0-9]+[^\s`!()\[\]{};:'".,<>?])/im)
links.each {|link|
  result = %x{curl -Is #{link[0]} | awk '/Location/ { print $2 }'}
  input = input.gsub(/#{link[0]}/,result.strip)
}
print input

How often will you need any of these little experiments? Probably not very often. Most of the time, I’m more than happy to just follow a shortened link and trust that the description it came with will hold true. Every once in a while, though, I come across a link of unknown origin that I’d prefer to run through something like this. Hopefully you’ll be able to find a use for it, too. It’s a cool little snippet.

  1. Sorry, Quicksilver fans. It used to be my absolute, must-have, favorite thing in the world, but it got too crashy on Snow Leopard, and then development just kind of died. LaunchBar is way better these days. 

  2. I keep a ‘scripts’ folder in my home directory (~/scripts) and put that in my PATH environment variable in my .bash_profile. Then, I can run my scripts from anywhere but don’t have to muck around in /usr/local/bin or any such thing.