Many Pies

Many Pies

Tuesday, October 20, 2009

Weather forecast via twitter - wycombeweather

Ages ago I thought it would be handy to have a local weather forecast delivered to my phone, for free. Then twitter came along and it looked like that might provide a possibility. By this time I'd come across the BBC weather RSS feeds.

I tried a couple of "RSS to twitter" services and both worked once and then never again. Google app engine looked like a good way of finding a server to do the stuff to join RSS to twitter. So I cobbled together bits of Python code and came up with this. (Update: September 2010 - updated to use oauth library. You'll need to register your app via dev.twitter.com to get the four keys below. )

(Paste in code from feedparser.org. Comment out the main program stuff.)
(Paste in outh stuff from http://github.com/mikeknapp/AppEngine-OAuth-Library/blob/master/oauth.py)


# Cobbled together from
# http://highscalability.com/using-google-appengine-little-micro-scalability
# http://pydanny.blogspot.com/2008/04/feedparser-does-not-work-with-google.html
import wsgiref.handlers
import urllib
from google.appengine.api import urlfetch
import base64
import feedparser
import StringIO

from google.appengine.ext import webapp

def getWeather():
      content = urlfetch.fetch("http://feeds.bbc.co.uk/weather/feeds/rss/5day/id/2111.xml").content
      d = feedparser.parse(StringIO.StringIO(content))
      if d.bozo == 1:
           raise Exception("Can not parse given URL.")
      return d['entries'][0]['title']

class WeatherText(webapp.RequestHandler):
def get(self):
     self.response.headers['Content-Type'] = 'text/html'

     self.response.out.write(getWeather())
     self.response.out.write('
supported by backstage.bbc.co.uk')


class UpdateWeather(webapp.RequestHandler):
def get(self):
     self.response.headers['Content-Type'] = 'text/plain'

     message = getWeather()
#      self.response.out.write(d['entries'][0]['title'] )
#      message = datetime.now().ctime()
     payload= {'status' : message,}
#      payload= urllib.urlencode(payload, True) Removed when switching to oauth client
# Get rid of degree marks because they turn out as question marks in the final tweet
#      payload = payload.replace('%3F','') degree marks work on twitter, appear as "deg" in txt, still wrong when main URL viewed
#      self.response.out.write(payload)

# Your application Twitter application ("consumer") key and secret.
    # You'll need to register an application on Twitter first to get this
    # information: http://www.twitter.com/oauth
     application_key = "im_not_telling_you"
     application_secret = "nor_this"
  
    # Get these from http://dev.twitter.com/apps/your_app_number/my_token
     user_token = "this_is_a_secret"
     user_secret = "this_is_definitely_a_secret"
  
    # In the real world, you'd want to edit this callback URL to point to your
    # production server. This is where the user is sent to after they have
    # authenticated with Twitter.
     callback_url = "%s/verify" % self.request.host_url
  
     client = TwitterClient(application_key, application_secret, callback_url)
     result = client.make_request("http://api.twitter.com/1/statuses/update.xml", token=user_token, secret=user_secret, additional_params=payload, protected=False, method=urlfetch.POST)
# Removed when oauth implemented
#      base64string = base64.encodestring('%s:%s' % (login, password))[:-1]
#      headers = {'Authorization': "Basic %s" % base64string}
#
#      url = "http://twitter.com/statuses/update.xml"
#      result = urlfetch.fetch(url, payload=payload, method=urlfetch.POST, headers=headers)
#
     self.response.out.write(result.content)


def main():
  application = webapp.WSGIApplication([('/', WeatherText),
('/updateweather',UpdateWeather)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
  main()

 You can see the results at twitter.com/wycombeweather and wycombeweather.appspot.com. If you want to do it for your local UK weather you'll need to change the figure 2111 above and use your own twitter account.

1 comment:

Biff said...

Hi Paul
I've been trying to do something similar recently. I'm not that experienced in Python yet and am having trouble adapting your method. Would it be at all possible to see the .py file that you deployed to google app engine?
Congratulations on a tidy little app!
Richard