Every month I have a different schedule. Not just a few days here or there, but a radically different work pattern. It’s something I’ve grown used to and something that’s second nature to me. It does, however, have it’s problems when it comes to arranging things with anyone who has more normal time constraints (i.e. the majority of the human race). The advent of online shared calendars has helped, but as work don’t provide my schedule as anything other than a text file I’ve had to be creative about getting things integrating 🙂
I moved away from running my own CalDev server a while ago and for the last year or so have been more than happy with Google Calendar. The ability to sync across all the devices that we need makes it a good choice and a few homegrown scripts allow me to parse the text file and generate entries. The Python GData library is good and makes it easy. Of course, not every service makes it that easy, as today has proven.
OAuth makes using websites easier and more secure, but it’s very much based around webpages and browsers. This is fine when it’s a webapp I’m working on, but when it’s a simple command line script it poses a few issues. After a period of trial and error – coupled with a liberal amount of abusing the search engine that’s a verb – I eventually solved my problem for TripIt. I’m not convinced it’s the right way to do it, but in case it helps anyone else in a similar situation I’ll outline it below.
As usual, step 1 is to get an unauthorised token. This is done as usual with a call to the TripIt API. I used the OAuth Python library rather than the Python tripit.py.
Use the TripIt APi to get the authorisation URL.
We need the user to use a browser and visit the authorisation page, but as the script runs on Linux and people have choice, I use gnome-open to open the URL in the browser the user is using. The URL is composed of the token and a callback URL – in this case set to localhost and a specified port.
Start a simple web server on the specified port on localhost to receive the response from TripIt when the user decides whether to grant access or not. The server is started to accept only a single request and blocks the progress until it has been received.
Exchange the token received so far for an authorised token.
I’ve got a simple test class written and working using the BaseHTTPServer and the handle_request() function. As I only need to handle a single GET response I’ve added a simple class that overrides BaseHTTPServer.BaseHTTPRequestHandler to return a simple page that tells the user to close the page. The oauth_token returned is returned and can be checked in this function. Rather than paste all of my code, I’ve pasted the relevant bits below.
import BaseHTTPServer ... class myTripitClass(): ... class oauthHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(s): """Respond to a GET request.""" ... s.send_response(200) s.end_headers() ... [ send a response telling the user to close the page... ] def startHttpServer(self): server_address = ('', 8123) httpd = BaseHTTPServer.HTTPServer(server_address, self.oauthHandler) httpd.handle_request()
I’ve omitted the code that’s not relevant. Filling in the blanks is left as an exercise for the reader 🙂
Presently I’m still developing so this is being run via a test script which looks as follows
from subprocess import Popen t = myTripitClass() if t.oauthGetUnauthorisedRequestToken(): url = t.oauthGetAuthorisationUrl() Popen(["/usr/bin/gnome-open", url]) t.startHttpServer() if t.oauthExchangeRequestTokenForAccessToken(): ... [ add code to do work here ]
Eventually this will be incorporated into the class (as you’d expect).
It works, but there may be better ways of doing it 🙂