Work Completed By: Steve Woodward
One of the four elements of our contextual access concept requires access to service and information to be dependant on the physical context of the user trying to gain access.
This project is concerned with demonstrating how a users physical context i.e. where they are relative to our network and the nature of the device that they are using can be identified and made a component of their identity as they access our services.
If possible an example should be built to demonstrate how services can be restricted or altered based on this information, for example:
• Information is restricted to those outside of the uk
• Information is presented in a format most appropriate to the platform being used to request it.
DETAILS/LOCATION OF PRACTICAL DEMONSTRABLE OUTPUT
Details of where code, web pages etc can be found.
My app works out where you are, and displays news for the nearest Warwickshire area (Warwick, Stratford, Rugby, North Warks, Nun & Bed). It also displays the weather for the nearest area too. It works off IP address first; which isn't very accurate, but encourages you to create an ID and link that to a FireEagle account, which is where you can store your location centrally. The system will then connect to FireEagle to get your accurate location.
The final app can be accessed from http://strong-waterfall-41.heroku.com/. I can make the code (such as it is) available if anyone wants to have a look at it, possibly via github if I work it out.
Describe the degree to which the work was successful in addressing the project description. Include reasons why or why not.
Much as it would be nice to get the users' location without any button pushing needed from them, there's generally a manual process on the user's side before the app can tell where they are.
It wasn't unexpected that geolocation by IP address is untrustworthy - hence all these location services springing up. It's been interesting to see some location API stuff popping up recently from Google and Twitter, and with the latest version of Firefox also including geolocation stuff, it makes me think we'll be seeing more and more applications making use of the users' location.
SHORT TERM BENEFITS
What immediate impact could the output of this R&D work have on the organisation – could it provide benefits without compromising our strategic approach?
How the work carried out fits with our strategic direction or how it should contribute to our strategic thinking.
I think that this project mainly ends up building on the application work; including lessons about good version control, the speed of development in Ruby on Rails, and the importance of quick and easy deployment.
Location services could be good for mobile workers or for targetting services at the public ("we know you live in Rugby; therefore your nearest recycling centre is…").
OTHER NOTES ETC
…is to write an application which displays the news from the WCC website depending on where you are, and if we get time, the weather for your area too. I've picked this because I know the data - I originally wrote the news system in Lotus Notes, and I know it stores the geographical area (albeit at district level) against the news stories. I'm hoping that the techniques here could be generically applied to other data with a geographic element.
The application should, as far as possible, automatically try and work out where you are. There's a variety of ways of doing this - from the rather iffy but seamless location by IP to services which rely on you/your computer to feed location info to them (FireEagle, BrightKite). More on that below.
I'm also planning to change the display depending on whether the user is on a desktop browser or using a mobile device. Just to annoy BlackBerry types, I'm planning to include some extra enhancements for Mobile Safari users.
Brilliantly, and to make things extra difficult I've chosen to write the application in little-known, hush-hush open-source web application framework Ruby on Rails, which I've never used before this week.
It's billed as "web development that doesn't hurt" and as being "…optimized for programmer happiness and sustainable productivity", so we'll see if a klutz like me can make it run without the usual throwing books around the room and high levels of biscuit and tea abuse that it usually takes to get something done.
Because of the popularity of Ruby on Rails, I'm hoping there will be plenty of libraries available to do most of the heavy code lifting for me.
Location services and apps
How can we work out where the user is? There are some apps and services out there already, which is rather handy.
The classic method - and by classic I mean it doesn't work properly - is by IP address. I'm sitting at home on the settee in Coventry, and here's where whatsmyipaddress thinks I am:
…which is Yoxall in Staffordshire - not really close. IP address geolocation is generally fine for working out which country someone is in (>95% accuracy) but rather less accurate when it comes down to metropolitan area. Or even which county in this case.
This is BrightKite, badly timed screenshot when xcode was installing:
BrightKite is essentially a more location aware version of Twitter (more on that, later…). Generally you tell BrightKite where you are by checking in at a particular location - you supply the street/city by typing in the search bar at the top. You can also ask BrightKite to guess where you are, and it uses a Java applet, if you can remember such things, from Geode and Loki, to detect your location from your wifi signal. Witchcraft, I tell you.
Inevitably there's an iPhone OS app for BrightKite, which is can be set by the internal GPS system on the iPhone - here's a screenshot from my (GPS-less) iPod Touch;
Here's Yahoo!'s Fire Eagle with their mildly disturbing pin-on-fire logo. Fire Eagle thinks I'm actually in the house next door though.
It's worth mentioning how Skyhook works - from their FAQ:
Skyhook deploys vehicle-based signal scanning and data collection technologies, a common practice in the digital mapping and data collection industries. These Skyhook-equipped vehicles conduct systematic and comprehensive signal surveys by traveling every public road and highway in targeted coverage areas.
The recently released Firefox 3.5 is also location aware…
…is it going to find out where I am?
…er yes, it was so accurate I had to zoom out a bit, you could see what fruit I was eating.
Twitter have announced a new location API which "…will allow developers to add latitude and longitude to any tweet". I'm not sure how this fits into 140 characters/bytes, but it sounds promising.
More and more devices are becoming location aware, we could start to make more and more use of the hardware out there. More and more mobile phones are coming with GPS - many of the Blackberry devices do, and the Phone 3G/3GS do, and Nokia's new 3G netbook comes with GPS too - could this point a way forward for standard laptops and netbooks coming with GPS, just as they come with wifi and Bluetooth as standard now?
Handily there's a Ruby gem for FireEagle… installing that comes with the following dependencies:
May you have many happy mappings! Successfully installed ruby-hmac-0.3.2 Successfully installed oauth-0.3.5 Successfully installed libxml-ruby-1.1.3 Successfully installed happymapper-0.2.5 Successfully installed GeoRuby-1.3.4 Successfully installed fireeagle-0.8.0.1
Notice the appearance of OAuth, used to authenticate with the FireEagle site. There's a couple of other interesting things in here that I've yet to investigate; happymapper and GeoRuby. (It later turned out that happymapper is an XML helper/parser, not geo related).
Next thing was to sign-up for an application key with FireEagle. That's easy enough; once we signed the application up with FireEagle, we get a consumer key and a consumer secret, which is a part of OAuth for communication between the app WCC Local Demo and FireEagle.
I plugged the key, and the secret into my app using pelle's oauth-plugin, which near enough worked straight away, much to my surprise. With the initial oauth-consumer test page, the user is pushed onto the Yahoo! site, where they log-in, and from there they go onto the FireEagle site, where they have to accept authorisation for the app - here mine is already authorised, but you get the idea:
pelle's oauth-plugin includes an example class for FireEagle, and with a bit of fiddling (just a problem with capitalisation in the model) it worked, and my app now pulled back location info.
I have BrightKite and FireEagle linked together; if I used BrightKite to guess my location, it reckons that I'm in Stivichall, Coventry. It passes this on to FireEagle, but as it's a more general location rather than a specific point, asking FireEagle for co-ordinates actually returns two sets.
The problem being when we get two sets of co-ordinates back, our code gets confused when parsing them and plots me 3000 miles away. Really I'd like to get just one co-ordinate - I wondered if we could get the middle of these two, and if that would be sensible co-or to take.
So ff we plot those on a map using Google Maps, and draw a box round them to show the bounds….
I know next-to-nothing about map co-ordinates and the rest of it, but I thought that by adding the co-ordinates together and dividing by two I might get the middle of the box. The co-ordinate I got from that calculation is shown as the green arrow in the image above, which looks reasonable - not too far away from where I am.
What's the nearest?
The news is stored in the News database against areas; Rugby, Nuneaton and Bedworth, Warwick, Stratford, North Warwickshire. It'd be great to get live data out of the database via XML, but as far as I know there isn't a per-district feed. I could scrape the per-district HTML views but I've not had time, so for now we'll set up some dummy news stories inside our system, stored against the categories.
I've got hold of the lat and long for the centre of each area, and I stored this in my system. Searching for the nearest area is dead easy - the code looked something like this (need to check..)
nearest = area.find(:all, :origin => @lat, @long)
Once I'd found the nearest area, I did a search on the news in the database that was stored against that area, and displayed those news stories.
So putting that all together and after a bit of rejigging of the stylesheet:
Getting location from IP address
I thought that if the user hadn't logged in, then rather than send them off to a rather cold login-or-create-an-account page, we would guess their location based on their IP address. My home_controller was getting a bit messy at this point, so I spent a bit of time separating the code into functions and branching depending on whether the user was logged in. If they aren't logged in, we use one of the geocoders set up in a config file to get the location.
The code in the controller just looks like this:
location = Geocoders::MultiGeocoder.geocode('18.104.22.168')
and we get back a bunch of information - this is from our debug page section:
including city and latitude and longitude. We use the latitude and longitude to calculate the distance
So we ended up with this…
Getting the weather
I wanted to demonstrate that we could get some data from an external system if a feed was available. Just as a demonstration, I decided to get the weather for the nearest Warwickshire area. Being as they're reasonably close to each other you might expect they're not going to vary hugely, but they can get different weather.
I decided to use the BBC feeds - there's a bunch of information on their BBC Backstage site. I stored the BBC Weather location ID in the database for each location, and pinched a load of code from the Yahoo page on How to parse XML with Ruby, using REXML. It took me a bit of fiddling to understand the format of what was returned; my lack of knowledge of Ruby looping and arrays was really starting to show here, but I'd managed to get something out and displayed.
We get a simple string back which is a bit of a pain; the temperature and the day aren't separated out into different tags within the XML, but it always appears in a string in a regular format, so we could use easily split the string up to get hold of the separate bits… we could play about with this, displaying different graphics based on the temperature and the weather type.
Deploying code (using Heroku)
I need some way of getting my code onto the internet, so it can both talk to and be called back from the various geolocation services. Heroku markets itself as "the instant Ruby platform" - it's a host with a free basic account, and it sounds like it's easy to get up and running.
Heroku supply a gem which is installed on your development system. Using this gem, we can create an app on the Heroku server.
It was at this point that I started to run into problems with accessing the server using the WCC Public Wifi from my Macbook - I was getting errors with the gem timing out. I tried to run Heroku from my work laptop, and despite some fiddling with proxy settings, got the same result.
I'm sure we could have arranged something with the WCC firewall, but as time is tight I've reverted to working from home for now.
Heroku also relies on the popular version control system called Git. I installed Git on OS X using a too-complicated series of shell scripts, and also installed the associated helper bundles for my text editor TextMate - this means I get a nice graphical interface for Git, which is usually driven from the command line.
Once the app is set-up, deploying the code is as easy as it should be. Commit the changes to version control, and then run 'git push heroku' from the command line to push the changes up to the webserver. Dead quick.
Not quite as easy all round than Google App Engine, which provides the developer with an application for deploying/running/stop/viewing logs - hello:
…but definitely easier to set-up than my previous workflow with PHP and Subversion, where I used a shell script to export the latest version and then rsync'd with the server.
If we're ever going to be deploying code in this way we'll need to get something sustainable sorted out with our firewall for access to online services from the command line.
I did have trouble trying to get the db:push command to work for transferring the contents of the database from my dev box to live, with the command line reporting that I needed to make sure the Taps gem was installed - which I just had done, so I'm not sure what happened there.
Scraping data from the news site
I had a little extra time at the end so I had a look at scraping the news data from the various publicbygeoarea views from our News Stories database. The (now disappeared) _why the lucky stiff wrote a library called Hpricot for parsing out HTML.
It really didn't take much code to pull the data out of the website, and integrating it didn't take too long, so I ended up with using it on the site - there is no caching, so it does hit the WCC website each time:
Mobile version of the site
Currently it's just this page, and I'm not terribly convinced that my CSS is too hot - rotating my iPod Touch makes the page get out-of-line.
I'm not convinced that this project has said a huge amount about identity, but it's been interesting to try out a few of the location services.
I think that as GPS works its way into electronic devices, more and more applications will make use of users location in new and strange ways that no-one has thought of yet.
I've really enjoyed developing using Ruby on Rails. I've been impressed with the amount of libraries out there - Oauth and Geokit were particularly impressive - which has meant that my (albeit rough-looking) code has stayed pleasingly minimal. I expect that I've been programming in a PHP style rather than Ruby style, but that will come. Deployment using Heroku has been very quick and easy - it makes the difficulties we had deploying our previous intranet app seem rather ridiculous.
Having said that, due to the firewall I've been severely limited in getting out to web services and the host at work - I've had to do deployment and most of the development from home. If we were to continue with Rails development, we'd need to sort out access through the firewall for developers.
Second phase: Loki and Ernest Marples
I had some more time to work on the project - I was keen on looking at Loki, which purports to add location to any website. Loki is a website/service which uses a browser plugin to get location details from the Skyhook database:
You might have already spotted a flaw with Loki - it's that bit about getting your location from a database of wifi connections. I'm connected through the corporate (wired) network here, and as such Loki doesn't work in this case, saying that it can't find a wireless adaptor. Here's a screenshot of the slightly scary looking pop-up in the browser:
We could get round this by falling back to IP address lookup if no wireless adaptor is found. When connected through the public wifi here at WCC it's quite impressive - I'm around the H in Northgate Street in the map below, so it's not far out:
I really struggled with trying to integrate Loki into my Rails app in an Ajax fashion; I couldn't quickly fathom out how to do this in the Rails way.
My alternative was to try and ape the BBC weather website with the simple "enter your postcode", to give "find the nearest" information.
My app (at http://strong-waterfall-41.heroku.com/wcc) scrapes the current WCC homepage, splits it in two at a particular point in the generated HTML, and injects the "local information" section, as seen blow. The user types in their postcode, and a request is then sent off to the mysterious Ernest Marples postcode lookup service to get the co-ordinates.
We're then doing the usual "find the nearest" stuff using the Ruby gem GeoKit to display the news and weather local to the users' Warwickshire location. The app keeps the postcode in the session so that the user doesn't have to type it in each time.
Update: May 2010
The Ernest Marples postcode lookup service was discontinued earlier this year, but since the Ordnance Survey have been forced to open up their CodePoint dataset, a new service has popped up at http://uk-postcodes.com/. The test WCC home page will be updated to point to it.
Mozilla Labs - Geode follow up
W3C Geolocation API specification
All my answers would seem to be found in this document, all about the GeoKit gem
Great way of getting your app up onto the web with little faff for free. Also forces the developer to uses version control in the form of Git, which is no bad thing.
Consuming Oauth intelligently in Rails - Stakeventures.com
Really really easy way of setting up Oauth in your app.
Two new ways to location enable your app - Google Code
…unfortunately seems to require installation of Gears.