Son of the Return of Dr. Twoot

I’ve spent three months in the Twitter wilderness, but now I’m back home. I finally fixed Dr. Twoot, my HTML/CSS/JavaScript/JQuery/Fluid-based Twitter client, so it works with the dreaded OAuth.

The fix didn’t go the way I planned, and Dr. Twoot has, unfortunately, become more complicated. I thought I’d be able to do all the OAuth stuff in JavaScript, but

So Dr. Twoot remained unusable, stuck with an obsolete Basic Authentication infrastructure, as I tried a variety of other clients. Echofon, HelTweetica, Hibari, Itsy, Kiwi, YoruFukurou, and maybe some others I can’t remember all got a tryout. They were all close to what I wanted, but because I didn’t write them, they didn’t fit me as well as Dr. Twoot had.

During the time I spent trying to do the OAuth stuff in JavaScript, I had run across the Python oauth2 library and used it as check against my JS code. I found it really easy to write with and wished I could do all of Dr. Twoot in Python. Eventually, I realized that I could use Python as an intermediary between Dr. Twoot and Twitter by writing a CGI script that

  1. takes requests from Dr. Twoot,
  2. sends them to Twitter wrapped in the proper authentication,
  3. accepts the response from Twitter, and
  4. passes the results back to Dr. Twoot.

The CGI script sits on my local machine, which is already running the Apache webserver. Conceptually, it looks like this:

With this structure, most of Dr. Twoot’s code remain untouched. Only the calls out to the Twitter API had to be redirected to the CGI script. The CGI script itself is pretty simple, built off an example given on Twitter’s page explaining the single access token method for OAuth.

 1:  #!/usr/bin/python
 3:  import oauth2 as oauth
 4:  import urllib
 5:  import cgi
 6:  import cgitb; cgitb.enable()
 8:  # You'll need to change these to the values you get from Twitter
 9:  # when you register your app.
10:  consumerKey = "123456789"
11:  consumerKeySecret = "123456789"
12:  accessToken = "123456789"
13:  accessTokenSecret = "123456789"
15:  # Pretty much stolen from
16:  def oauth_req(url, http_method="GET", post_body=None, http_headers=None):
17:    'Make a request and return the content of the response.'
19:    # Set up the client.
20:    consumer = oauth.Consumer(key=consumerKey, secret=consumerKeySecret)
21:    token = oauth.Token(key=accessToken, secret=accessTokenSecret)
22:    client = oauth.Client(consumer, token)
24:    # Make the request.
25:    resp, content = client.request(
26:      url, 
27:      method=http_method, 
28:      body=post_body, 
29:      headers=http_headers
30:    )
32:    return content
34:  # Get data POSTed to this script and sort it into the Twitter URL
35:  # and the data to POST to Twitter.
36:  form = cgi.FieldStorage()
37:  twitterURL = form['url'].value
38:  keylist = form.keys()
39:  del(keylist[keylist.index('url')])
40:  body = {}
41:  for k in keylist:
42:    body[k] = form[k].value
44:  # Make the requests.
45:  if len(keylist) == 0:
46:    answer = oauth_req(url = twitterURL)
47:  else:
48:    answer = oauth_req(url = twitterURL, http_method="POST", post_body=urllib.urlencode(body))
50:  # Return the results as JSON.
51:  print '''Content-Type: application/json
53:  %s''' % answer

To get the authentication credentials that go in Lines 10-13, I had to register myself and Dr. Twoot with Twitter, but that was pretty easy. The single access token method was designed for single-user applications like Dr. Twoot, and it avoids a lot of the usual back and forth dance that comes with OAuth. If you want to adapt Dr. Twoot for your own use, you’ll have to register to get your own credentials. It’s not as scary as it sounds.

Although it’s more complicated to set up, Dr. Twoot is as easy to use as it always was. It’s a site-specific browser (SSD) built with Fluid, and it launches just like any other application. The new CGI script is run by Apache automatically in the background; I don’t have to think about it at all.

One of the things I missed during the months using other clients (and—horrors!—the Twitter web site) was seeing @DrSamuelJohnson’s tweets appear in IM Fell, a webfont with an 18th century look.

That’s the kind of fun customization you can only do in a program you’ve built yourself.