Twitter bot: NZ police updates
I’ve subscribed to the email updates from our police for a while now. Given these updates were usually about things happening live, I thought it’d be useful to write something to post them into Twitter.
After about an hour of hacking, I had a quick and dirty script that did the job. There are three users you can follow if you are so inclined:
The script uses BeautifulSoup, a particularly excellent python library that ZachTwo reminded me about. I’d prefer it if the police released their updates in a better format, but screen-scraping will do for now.
Read on for the script. Consider it under a GPL licence.
#!/usr/bin/python
from BeautifulSoup import BeautifulSoup, SoupStrainer
import re
import urllib2
import tinyurl
import pickle
import twitter
import logging
logFile = '/tmp/twitter-police.log'
logging.basicConfig(filename=logFile, level=logging.DEBUG)
twitterDistrict = dict()
pickleFile = '/home/sam/.twitter-police.pickle'
twitterPass = 'secret password goes here'
twitterDistrict['Auckland City'] = twitter.Twitter('nzpolice_akl', twitterPass)
twitterDistrict['Wellington'] = twitter.Twitter('nzpolice_wgtn', twitterPass)
twitterDistrict['Canterbury'] = twitter.Twitter('nzpolice_chch', twitterPass)
twitterDistrict['Counties Manukau'] = twitterDistrict['Auckland City']
try:
lastId = pickle.load(open(pickleFile))
except EOFError:
lastId = 7600
logging.debug('Loading events from ID %d' % lastId)
class InvalidUpdate(Exception):
pass
def simplifyUpdate(node):
if len(node) == 0:
return ''
return node.contents[0]
def makeEvent(url):
result = dict()
logging.debug('Loading %s' % url)
updateContent = urllib2.urlopen(url).read()
soup = BeautifulSoup(updateContent)
updateMessage = soup.findAll('td', { 'class': 'updateMessage' })
for i in range(0, len(updateMessage), 2):
key = updateMessage[i].contents[0].contents
if len(key) == 1:
key = key[0][:-1]
value = updateMessage[i+1].contents
if key == 'Time' and value[0].contents[0] == u'12:00 1-01-1970':
raise InvalidUpdate()
if key == 'What happened':
result[key] = ' '.join(map(simplifyUpdate, value))
else:
result[key] = value[0].contents[0]
return result
def loadUpdate(id):
url = 'http://police.govt.nz/news/updates/update.html?id=%d' % id
event = makeEvent(url)
logging.info('Found %s update for %s' % (event['Location'], event['District']))
if twitterDistrict.has_key(event['District']):
logging.info('Posting to twitter')
api = twitterDistrict[event['District']]
postUrl = tinyurl.create_one(url)
suffix = '... %s' % postUrl
updateLength = 140 - len(suffix)
postBody = event['What happened'][0:updateLength] + suffix
api.statuses.update(status=postBody)
return True
try:
while loadUpdate(lastId):
lastId = lastId + 1
except InvalidUpdate:
pass
finally:
pickle.dump(lastId, open(pickleFile,'w'))
Clever!
The other upshot of this is that you can subscribe to this via RSS too, if you want it out of your twitterstream…
feed://twitter.com/statuses/user_timeline/18446406.rss
Sigurd Magnusson
9 Feb 09 at 8:29 pm
I too have subscribed to the email updates for a long time and get them sent to my phone as SMS. Twitter is a bonus – with the conversation or at least reply aspects.
Since I subscribed then have started working on a contract to the backend of Police Comms, sitting mere meters away form the live action. I used to put a stop watch on live -> media delays what with scanners and Police updates.
I’d love to see a real-time public comminication interface on our Police and Fire, and hope to see it happen before I leave here. Twitter maybe?
For now you’re doing a great job with the twitter bot http://www.police.govt.nz/news/updates – and Fire have http://incidents.fire.org.nz for an hour or so delay on events.
Must have a look at the code for my various bots that do 5 updates every 30 minutes using twitterfeed.com – this may be better, and less spammy.
Does it cope with updates to an alert?
JoMangee
11 Feb 09 at 9:43 am
Someone in the States created a fake police twitter account for the PD in Austin, TX – but they tweeted fake messages:
“Updates from the fake Twitter account included ‘warming up my radar gun for SXSW’ and ‘we’re looking to make more stops at SXSW this year than last,’ as well as references to police jargon codes that seemed to be stemming from a knowledge of gangsta rap lyrics rather than actual law enforcement.”
http://news.cnet.com/8301-13577_3-10204228-36.html
Not as useful as what you’ve done here.
Daniel
8 Apr 09 at 8:28 am