The Making of Darling Fireball

It’s post-“Halloween”:Wikipedia:Halloween, so I might as well own up to my own peculiar brand of trick or treating.

You might recall that, half a year back, I (well, nearly 140 characters’ worth) about John Gruber’s use of his IDN-based domain for posting Daring Fireball links on Twitter, since I couldn’t follow those links on a number of devices.

Which particular ones isn’t relevant – phones, my , the secret webpads I’ve been testing crammed with bastardized “Area 51”:Wikipedia:Area_51 technology defiled with Adobe AIR, you name it – most of what I used broke (and still breaks) when clicking on “@daringfireball’s”:Twitter:daringfireball links, and I decided I’d build a way to get around the hassle.

So, after a bout of inspiration, some rummaging in my tool-chest and checking the TOS to make sure that a parody was at least tolerated, “@darlingfireball”:Twitter:darlingfireball was born, and has been chugging along for a few months now.

Here are the obligatory “before” and “after” screenshots, for your perusal and (hopefully) amusement:

Before After

The ground rules were:

  • I’d only re-post tweets with links.
  • All the “normal” shortened versions would resolve to the exact same location.
  • The profile (username, look, and where possible, feel) would be as much as possible a visible and detailed parody (hence the “darling”, the pink, the hard-coded choice of as a shortener and the heart Unicode glyph).
  • Re-posting would be throttled and delayed so as to not compete with the original (the twisted little linkages that legal work has wrought in my neural pathways told me that it was best to do so).

The exercise consisted of a mere half hour tapping out the following script, and it’s proven to be useful to me for many reasons, including streamlining my snippets and learning a bit more about the API:

#!/usr/bin/env python
# encoding: utf-8

Created by Rui Carmo on 2009-07-21.
Copyright (c) 2009 __MyCompanyName__. All rights reserved.

import sys, os, re, codecs
import twitter, simplejson, sqlite3
import expander

trim = 140 # snug fit
ellipsis = u'\u2026'
separator = u' '

def main():
  e = expander.URLExpander()
  s = expander.URLShortener()
  db = sqlite3.connect("cache.db")
  c = db.cursor()
  c.execute('create table if not exists status (id text, status text, seen boolean)')
  c.execute('create unique index if not exists id on status (id asc)')
  api = twitter.Api(username='darlingfireball', password='********', input_encoding=None)
  items = api.GetUserTimeline('daringfireball')
  for i in items:
    c.execute('insert or ignore into status (id, status) values (?,?)', (, i.text))
  c.execute("select * from status where seen is NULL order by id asc")
  queue = []
  for row in c:
    (key, status, state) = row
  for i in queue:
    (key,status) = i
    match ="(http://.+)", status)
    if match:
      longurl = e.query(
      shorturl = s.query(longurl)
      # we got a valid shortened URL, so we're good to go
      if '' in shorturl:
        # remove original shortlink and replace the unicode markers, if any
        title = status.replace(,'').replace(u'\u2605',u'\u2665').replace(ellipsis,'').strip()
        # make sure it fits, and add an ellipsis and a space if necessary
        if len(title) > (trim + len(separator) + len(shorturl)):
          shortened = title[0:trim - len(ellipsis) - len(separator) - len(shorturl)] + ellipsis + separator + shorturl
          shortened = title + separator + shorturl
        status = api.PostUpdate(shortened,key)
        c.execute("update or replace status set seen=? where id=?", ('1',key))        

if __name__ == '__main__':

Removing very old tweets and compacting the database automatically are left as an exercise to the reader (I now do that every time I use SQLite as a persistent queue, but at the time I was going for a quick, fun hack).

Obviously, I’ll take it down if John objects in any way, but it has just reached the magical figure of 42 followers, so this has to be the answer to something for some people…