One of the bits of feedback that has been acted on recently is support for setting the date of a moment, instead of just using the date on which the moment was submitted. This is done by setting a startDate field in the main JSON structure submitted to the API:
This means that things that happened in the past can now be added to a users history, which is quite convenient some application. As I happened to be renewing my Oyster (London's RFID transport card) season ticket when this was added to the API, I figured it might be fun to see if it was possible to push moments based on my Oyster journeys.
It turns out that the Oyster site does give you a view on your journey history, and allows exporting it via CSV, from the Journey History page.
The CSV itself contains the same data that is displayed - a date with start and end time, a string describing the journey, the charge, and the existing balance on the card.
Date,Start Time,End Time,Journey/Action,Charge,Credit,Balance,Note
05-Aug-2012,14:30,,"Bus journey, route 36",.00,,13.95,""
04-Aug-2012,10:52,11:19,"Kew Bridge to Clapham Junction",.00,,10.35,""
This seems like a workable set of data, so the next step was to get it into the History service. Because History is in preview at the moment, the released versions of the existing Google API clients don't necessarily include code for it, so instead I checked out the PHP version from the repository. It's worth mentioning that there is ongoing work on the structure of the client, so it may be that any code here needs some tweaking if anyone tries using it in the future.
The basic boiler plate can come straight from the various sample apps, but when creating the project in the API console be sure to add the Google+ API and the Google+ History API - and remember that at the moment you need to have signed up for the developer preview group to have access do so. Then, we request access for the scope in our OAuth setup.
Do actually do the authentication, we then redirect the user to the auth URL we can get from the client: with $client->createAuthUrl()
And when they're returned to us we can store their authentication token in the session:
For pushing the Oyster CSV I downloaded from their site I just used a simple upload form and passed the file location to the following function, which does all the actual work.
First thing we need to do is create classes for the services we're going to use, and open the uploaded file for reading.
Then, we loop over the rows of the file, using fgetcsv to parse the data into an array for us. Each moment needs to be represented as a new object, so we create that, and set the type to CheckInActivity. There's a list of the currently available activities in the documentation, and it seemed to fit best in this case to have the entry check in at the end station, or the bus route. That said, it might be nice to track the duration of the trip, or perhaps to check in to both start and end locations. Bus routes also add some slight trickiness as they aren't exactly a place - and we can't see from the data where someone got on to the bus, or where or when they got off, just that they were on a certain route.
Next up we grab the fields we care about. Each record has a single date, and associated in and out times (for train/underground journeys) or just a start time (for bus trips). Using strtotime we parse those into unix timestamps.
Now we have to setup our moment's target URL. Moments in History are private events (by default), but generally will be referencing a generally available URL. In this case I initially used the TFL bus route pages, but decided to switch to the Wikipedia pages for routes and stations as they are a bit more visual. Because the journey string is a standard format, we can detect what type of journey it is, as change our URL appropriately, in this case looking for the "route XXX" string and using that to build the wikipedia URL. We also set the startDate of our moment to the start date and time, which should be the time the person tapped in to the bus.
If the journey was on the train we get a little bit more information. The stations listed can, but don't always, contain other useful notes. For example, for London Victoria (one of the main train and underground stations in London) we get: "Victoria (platforms 9-19) [National Rail]". In this case we want to try and extract the [National Rail] part to allow us to distinguish between railway stations and underground stations, as they have a slightly different Wikipedia URL structure. For underground stations, we could also generate a url on the TFL site, but that does require maintaining a mapping between the station IDs and names.
In this case we log the journey against the arrival time, as we are checking in to the end station. Finally, we insert the moment, and check for exceptions.
At that point we can run the script and get the results in the Developer Preview UI! There's definitely many more interesting things to do with the data, but it was easy to play with!