status

location
Washington, DC
Subscribe to GeoRSS Subscribe to KML


Programming

Git as a tool for distributed crisis management tools

Published in Open-Source, Programming


Through my help with VoteReport.in I have been diving much more into supporting and deploying the Ushahidi platform as part the front-end for user contributed reports. Ushahidi itself started out as a quick mashup a year ago and since then has blossomed into a much fuller platform that is being utilized in dozens of initiatives and projects.

Each of these projects evolves the platform, adding new customization capabilities, more input types, browser support, and more. These modifications may be happening in rapid succession without the main Ushahidi development team even being aware of these changes. And the system may even be running in a remote area with little connectivity.

Traditionally, this has meant that a deployment would download a copy of the current release version, or maybe a development snapshot if there was some emminent new feature that was very useful, and then go off, make modifications – probably on a live server, and maybe email these changes back way after the event in hopes that some of the changes are accepted back into the platform. Updates to the main code base wouldn’t be easily applied to these heavily modified derivatives – so essentially every deploy is a fork of the code.

How Git can save the day

Ushahidi Git.pngFortunately, Ushahidi chose Git as the code repository server, although the installation instructions still suggest that you download the code. Git is meant to support just this kind of distributed workflow and collaboration.

If you’re not familiar with Git, I highly recommend checking out Git Internals. But to summarize, it is a versioning control system that is fast, efficient, has local indexes (stored in a local .git directory) and can reference any number of remote indexes to share commits, branches, and files. Where in traditional systems there is an ‘official’ host repository – in Git all repositories are equal and can quickly connect and syncronize.

What this means in a system like Usahidi is that any deployment would first just get a local clone of the official Ushahidi repository to their local system and setup and get running. If they make changes to this code they can just do a commit into their local index. In order to share this code with other developers on this same deployment they could just provide them with the Git link to this repository, or make a branch and add a deployment specific “remote” index that multiple developers could all push into.

Along the way as new code is released in the Ushahidi repository, these deployments could merge in these changes to their local branches without losing their local modifications. And conversely, local modifications could be merged and pushed back into the Ushahidi master index very easily.

Moving sideways

Now lets think about some really powerful uses of the Git architecture. Since the entire index is stored locally in a .git folder – it is easy to put an Ushahidi deploy on a USB stick or archived folder, send it around, make modifications in the field and continue to commit these changes to a local repository even while offline. Then when connectivity is restored, or the USB stick can be brought back to a networked computer, the modifications that had been made, and tracked, could be pushed back to a deployment or Ushahidi instance.

And with arbitrary remote indexes – individual deployments could share code and modifications between themselves without having to go through an Ushahidi instance. Local networks around an incident, culture, language, or feature set could easily collaborate and iterate the code. Imagine if in Gaza, the Al Jazeera instance could have shared code to other local organizations running similar systems.

I think there are even more potential applications of Git to distributed architectures that would be useful for document and database sharing that occur in fast paced situations. However, Git itself will have to work on some of the usability and interface design issues that make it a difficult tool for novice users.


Rails interfaces to Mac Applications

Published in Apple, Rails


The new version of Mac OS X, Leopard, came with a much anticipated feature – an officially supported set of Ruby bridges to Cocoa (the Mac OS X Framework) and AppleScript. Digging around I couldn’t find the pre-installed versions, but it was easy enough to gem install rb-appscript

I’ve been playing around with the very complete examples over the last couple of days and am really impressed with how easy it is to build Cocoa apps in just a few lines of Ruby code and using the new InterfaceBuilder. You get full-fledged support of all OS X’s goodness without having to worry about Objective-C.

However, I hadn’t fully considered some of the implications of this until I was stumbled across the open-source OmniFocus-UI. It is a Rails app written as an iPhone interface to the Productivity application (GTD) OmniFocus. It essentially provides a very lightweight web interface to the application by way of the AppleScript interface. rb-appscript and RubyOSA are two Ruby AppleScript bridges that make AppleScript actually really nice to work with.

The fact that it’s a Rails app is almost silly. There is no database connection to speak of. All storage and primary functionality is handled by the app itself. OmniFocus-UI could probably be rewritten as a Camping or Merb application very easily with a much smaller footprint.

The way the Rails app works is that the controllers just route commands via rb-appscript. So when you want a list of contexts (organization of todos), the Rails app just needs to do the following in Ruby:

require 'appscript'
doc = Appscript.app("OmniFocus").default_document
doc.contexts.get.length

Or to see how many Inbox items you have:

doc.inbox_tasks.count

If instead you want to use RubyOSA, it’s really just the Class name that changes (and some more underlying bits):

require 'rbosa'
doc = OSA.app("OmniFocus").default_document	

What this means is, it’s very easy to build web interfaces on top of any AppleScript-able Mac application. The one difficulty, however, is configuring your Mac to make it easily externally accessible from anywhere on the Web. If you’re handy on IT, you can always setup port-forwarding on your router.

However, if you just want setup & forget, you should check out Prism (http://goprism.com) – which creates secure, private web accessible connections to your home computer.


Bug in open-uri when dealing with multiple headers

Published in Programming, Ruby


I just discovered a bug in Ruby’s open-uri library, caused by the Net::HTTP library, or at best really annoying behavior that will break when you try and use it. The problem lies in dealing with an HTTP request that returns multiple values for a field. This forum topic discusses that having multiple instances of a field is valid in HTTP1.1 (RFC2616).

So when you use Net::HTTP to fetch a document like this, it will create an array for every field, holding each value found for the field. That’s great. However, in open-uri#last_modified then gets this array and joins the values together to get a single string.

The example I ran into is the Last-Modified field. Given HTTP headers like this:

HTTP/1.1 200 OK
Server: Undisclosed-Webserver/0.1
Date: Tue, 14 Aug 2007 15:03:29 GMT
Last-modified: Tue, 14 Aug 2007 15:03:29 GMT
Content-type: application/vnd.google-earth.kml+xml
Last-modified: Wed, 08 Aug 2007 18:34:55 GMT
Connection: close  

And then calling response.each_header {|f,v| puts "#{f}: #{v}"} will result in Last-Modified: "Tue, 14 Aug 2007 15:21:22 GMT, Wed, 08 Aug 2007 18:34:55 GMT". Go ahead and try throwing Time.httpdate at that. You’ll get ArgumentError: not RFC 2616 compliant date:.

To simply recreate this bug, try the following ruby code:

require 'open-uri'
res = open("http://popsci.com/popsci/kml/popsci_future_environment.kml")
res.last_modified

A simple solution, or workaround, is to just get the hash and deal with it yourself: response.to_hash.each {|f,v| puts "#{f}: #{v}"} # => last-modified: "Tue, 14 Aug 2007 15:21:22 GMT

I’m not going to mention any names on this particular offending party that was silly to include 2 Last-Modified dates, but you know who you are.


TwitterVision (geo-twitter) API

Published in Neogeography, Programming


I haven’t gotten a chance to play with it much yet, as I’m still on travel, but Dave Troy released a simple, effective API to his TwitterVision work with geolocating twits.

The TwitterVision API looks like it was built on Rails, which means it is probably a very slick/simple addition for him to expose the data in XML, YAML, and JSON.

No sign of GeoRSS explicitly yet, so you can’t subscribe to just a feed of your friends’ locations, but that would again be something simple to add (and he does hint there is more coming), or for someone else to build on using his API.

One issue that still remains is if forcing a user to specify the “l:” prefix to a location is a usable/effective mechansism. Typing a colon (:) on a mobile phone isn’t the easiest thing to do, but at the same time using other characters such as a tilde (~) are often stripped out or munged by SMS gateways.

A more natural language parsing option would be interesting, but processing is intense with potentially very unclear results (‘Sitting at the bar’, ‘Leaving home to go into town’) and also privacy or desire of the user to sometimes not share their location.

Using simple symbols, like parenths: Caffeine good (Sweetwaters Cafe)
would be a good option, since the location may not actually be part of my message, but I do want to share it.

As for parsing, something like Geocodr would provide a very robust geocoding system where the system could parse both odd areas (Soma), buildings/areas (Empire State Building), or even events (Web2.0 Expo).

So the main points are to allow opt-in based on my desire to share location (or destination), simple to enter on a mobile/laptop/brain implant, and optional location specification outside of the actual primary message content. And the issue applies outside of just Twitter, which really just serves as a good context. How would this be done in voice command for directions or location?

But again, needs to be simple and understandable. Don’t you like simple problems?


Ruby on Rails case study

Published in Rails


Allan from the NonProfitTechBlog pointed me to this article on infoQ, Ruby on Rails case study: ChangingThePresent.org.

The article does a full walk-through, from concept, through development, and to scalability, deliverability, and maintainability, of a Ruby on Rails site/service.

Discussions (arguments) between the various languages and their frameworks are common. It’s helpful to see such a readable and poignant presentation of the entire process to address the various issues other developers bring up about the platform.

I have definitely seen the same effects he talks about in the article. Development and updates occur much faster. I can be more productive creating my ideas and getting them to a working prototype. The code is easy to read and small, so its also easy to maintain the code to optimize or extend with new features.

I’m not saying that the other languages or frameworks fail at this, I know that for me, it feels like its the fastest development I can do short of natural language requirements into code (“Make me a Map” )