Browse Source

Update locations!

Douglas William Thrift 14 years ago
parent
commit
c3866a15a1
2 changed files with 42 additions and 16 deletions
  1. 39 13
      locationbot.py
  2. 3 3
      locationbot.sql

+ 39 - 13
locationbot.py

@@ -6,12 +6,15 @@
 # $Id$
 
 from ConfigParser import NoOptionError, SafeConfigParser
+from datetime import datetime, timedelta
 import geojson
 import getpass
 import ircbot
 import irclib
 import os
+import psycopg2
 import sys
+import time
 import threading
 import urllib, urllib2
 import warnings
@@ -47,6 +50,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
 
 			self.__admins = config.get(nick, 'admins').split()
 			self.__channels = config.get(nick, 'channels').split()
+			self.__dsn = config.get(nick, 'dsn')
 			self.__hostname = config.get(nick, 'hostname')
 		except NoOptionError, error:
 			sys.exit(error)
@@ -67,19 +71,42 @@ class LocationBot(ircbot.SingleServerIRCBot):
 		return False
 
 	def __do_latitude(self):
-		#with self.__locations_lock:
-		#	self.__locations.append(('douglaswth', 'Isla Vista, CA, USA'))
+		now = datetime.utcnow()
 
-		#try:
-		#	url = 'http://www.google.com/latitude/apps/badge/api?' + urllib.urlencode({'user': 0, 'type': 'json'})
-		#	response = urllib2.urlopen(url)
-		#	geo = geojson.load(response, object_hook = geojson.GeoJSON.to_instance)
+		try:
+			while now < self.__latitude_next:
+				time.sleep((self.__latitude_next - now).seconds)
+
+				now = datetime.utcnow()
+		except AttributeError:
+			pass
+
+		self.__latitude_next = now.replace(minute = now.minute - now.minute % 5, second = 0, microsecond = 0) + timedelta(minutes = 5)
+		db = psycopg2.connect(self.__dsn)
+		cursor = db.cursor()
+
+		cursor.execute('select nick, channels, location, latitude from locationbot.nick where latitude is not null order by latitude')
+
+		locations = {}
+
+		for nick, channels, location, latitude in cursor.fetchall():
+			if latitude not in locations:
+				url = 'http://www.google.com/latitude/apps/badge/api?' + urllib.urlencode({'user': latitude, 'type': 'json'})
+				response = urllib2.urlopen(url)
+				geo = geojson.load(response, object_hook = geojson.GeoJSON.to_instance)
+
+				if len(geo.features):
+					locations[latitude] = geo.features[0].properties['reverseGeocode']
+
+					cursor.execute('update locationbot.nick set location = %s where latitude = %s', (locations[latitude], latitude))
+					db.commit()
 
-		#	print geo.features[0].properties['reverseGeocode']
-		#except urllib2.URLError, error:
-		#	print error
+			if channels and locations.get(latitude, location) != location:
+				with self.__locations_lock:
+					for channel in frozenset(channels).intersection(self.__channels):
+						self.__locations.append((nick, channel, locations[latitude]))
 
-		self.__latitude = threading.Timer(5 * 60, self.__do_latitude)
+		self.__latitude = threading.Timer((self.__latitude_next - datetime.utcnow()).seconds, self.__do_latitude)
 
 		self.__latitude.start()
 
@@ -203,9 +230,8 @@ class LocationBot(ircbot.SingleServerIRCBot):
 
 			if self.__locations_lock.acquire(False):
 				if self.__locations and sorted(self.__channels) == sorted(self.channels.keys()):
-					for nick, location in self.__locations:
-						for channel in self.__channels:
-							self.connection.notice(channel, '%s is in %s' % (nick, location))
+					for nick, channel, location in self.__locations:
+						self.connection.notice(channel, '%s is in %s' % (nick, location))
 
 					self.__locations = []
 

+ 3 - 3
locationbot.sql

@@ -13,8 +13,8 @@ create table locationbot.nick (
 	masks text[],
 	channels text[],
 	location text,
-	latitude bigint,
+	latitude bigint
 );
 
-create index locationbot.nick_location_index on locationbot.nick (location);
-create index locationbot.nick_latitude_index on locationbot.nick (latitude);
+create index nick_location_index on locationbot.nick (location);
+create index nick_latitude_index on locationbot.nick (latitude);