|
@@ -89,7 +89,8 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.__reloading = True
|
|
|
|
|
|
self.__quiting = False
|
|
|
- self.__variables = frozenset(['nick', 'secret', 'masks', 'channels', 'timezone', 'location', 'latitude'])
|
|
|
+ self.__variables = frozenset(['nick', 'secret', 'masks', 'channels', 'timezone', 'location', 'coordinates', 'latitude'])
|
|
|
+ self.__geocode = self.__variables.intersection(['location', 'coordinates'])
|
|
|
self.__lists = self.__variables.intersection(['masks', 'channels'])
|
|
|
self.__unsetable = self.__variables.difference(['nick', 'secret'])
|
|
|
|
|
@@ -196,28 +197,14 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
new_location = locations.get(latitude)
|
|
|
|
|
|
if latitude not in locations:
|
|
|
- url = 'http://www.google.com/latitude/apps/badge/api?' + urllib.urlencode({'user': latitude, 'type': 'json'})
|
|
|
-
|
|
|
- try:
|
|
|
- response = urllib2.urlopen(url)
|
|
|
- except urllib2.URLError, error:
|
|
|
- print error
|
|
|
- continue
|
|
|
-
|
|
|
- try:
|
|
|
- geo = json.load(response)
|
|
|
- except (TypeError, ValueError), error:
|
|
|
- print error
|
|
|
- continue
|
|
|
-
|
|
|
try:
|
|
|
- feature = geo['features'][0]
|
|
|
+ feature = json.load(urllib2.urlopen('http://www.google.com/latitude/apps/badge/api?' + urllib.urlencode({'user': latitude, 'type': 'json'})))['features'][0]
|
|
|
coordinates = tuple(reversed(feature['geometry']['coordinates']))
|
|
|
properties = feature['properties']
|
|
|
new_location = properties['reverseGeocode']
|
|
|
locations[latitude] = new_location
|
|
|
updated = datetime.fromtimestamp(properties['timeStamp'], pytz.utc)
|
|
|
- except (IndexError, KeyError), error:
|
|
|
+ except Exception, error:
|
|
|
print error
|
|
|
continue
|
|
|
|
|
@@ -389,7 +376,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
connection.privmsg(nick, '\x02variable value\x0f')
|
|
|
|
|
|
for variable, value in zip(variables, cursor.fetchone()):
|
|
|
- connection.privmsg(nick, '%-8s %s' % (variable, ' '.join(value) if isinstance(value, list) else value))
|
|
|
+ connection.privmsg(nick, '%-11s %s' % (variable, ' '.join(value) if isinstance(value, list) else '%f,%f' % value if isinstance(value, tuple) else value))
|
|
|
else:
|
|
|
def invalid(value, variable = variable):
|
|
|
connection.privmsg(nick, 'invalid %s ("%s")' % (variable, value))
|
|
@@ -412,10 +399,62 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
value = int(re.sub(r'^(?:http://(?:www\.)?google\.com/latitude/apps/badge/api\?user=)?([0-9]+)(?:&type=.*)?$', r'\1', value))
|
|
|
except ValueError:
|
|
|
return invalid(value)
|
|
|
- elif variable == 'location':
|
|
|
+ elif variable in self.__geocode:
|
|
|
cursor.execute('select channels, location from locationbot.nick where nick = %s', (login,))
|
|
|
|
|
|
- channels, location = cursor.fetchone()
|
|
|
+ channels, old_location = cursor.fetchone()
|
|
|
+ parameters = {'sensor': 'false'}
|
|
|
+
|
|
|
+ if variable == 'location':
|
|
|
+ parameters['address'] = value
|
|
|
+ else:
|
|
|
+ coordinates = value.split(None, 1)
|
|
|
+
|
|
|
+ if len(coordinates) == 1:
|
|
|
+ coordinates = coordinates[0].split(',', 1)
|
|
|
+
|
|
|
+ try:
|
|
|
+ coordinates = tuple(map(lambda a: float(a), coordinates))
|
|
|
+ except ValueError:
|
|
|
+ return invalid(value)
|
|
|
+
|
|
|
+ parameters['latlng'] = '%f,%f' % coordinates
|
|
|
+
|
|
|
+ geocode = json.load(urllib2.urlopen('http://maps.google.com/maps/api/geocode/json?' + urllib.urlencode(parameters)))
|
|
|
+ status = geocode['status']
|
|
|
+
|
|
|
+ if status != 'OK':
|
|
|
+ if status == 'ZERO_RESULTS':
|
|
|
+ return invalid(value)
|
|
|
+ else:
|
|
|
+ raise Exception(status)
|
|
|
+
|
|
|
+ results = geocode['results']
|
|
|
+ result = results[0]
|
|
|
+ new_location = result['formatted_address']
|
|
|
+
|
|
|
+ if variable == 'location':
|
|
|
+ location = result['geometry']['location']
|
|
|
+ coordinates = (location['lat'], location['lng'])
|
|
|
+ value = new_location
|
|
|
+ else:
|
|
|
+ types = frozenset([
|
|
|
+ 'country',
|
|
|
+ 'administrative_area_level_1',
|
|
|
+ 'administrative_area_level_2',
|
|
|
+ 'administrative_area_level_3',
|
|
|
+ 'colloquial_area',
|
|
|
+ 'locality',
|
|
|
+ 'sublocality',
|
|
|
+ 'neighborhood',
|
|
|
+ ])
|
|
|
+
|
|
|
+ for result in results:
|
|
|
+ if not types.isdisjoint(result['types']):
|
|
|
+ new_location = result['formatted_address']
|
|
|
+ break
|
|
|
+
|
|
|
+ value = coordinates
|
|
|
elif variable == 'nick':
|
|
|
_nick = value.split(None, 1)
|
|
|
|
|
@@ -426,7 +465,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
return invalid(value)
|
|
|
|
|
|
try:
|
|
|
- cursor.execute('update locationbot.nick set ' + variable + ' = ' + ('md5(%s)' if variable == 'secret' else '%s') + (', coordinates = null, updated = now()' if variable == 'location' else '') + ' where nick = %s', (value, login))
|
|
|
+ cursor.execute('update locationbot.nick set ' + ('location = %s, coordinates = point %s, updated = now()' if variable in self.__geocode else variable + ' = ' + ('md5(%s)' if variable == 'secret' else '%s')) + ' where nick = %s', (new_location, coordinates, login) if variable in self.__geocode else (value, login))
|
|
|
db.commit()
|
|
|
except psycopg2.IntegrityError:
|
|
|
if variable == 'nick':
|
|
@@ -436,10 +475,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
if variable == 'nick':
|
|
|
self.__logins[nick] = (value, nickmask)
|
|
|
- elif variable == 'location':
|
|
|
- self.__location(nick, channels, location, value)
|
|
|
+ elif variable in self.__geocode:
|
|
|
+ self.__location(nick, channels, old_location, new_location, coordinates)
|
|
|
|
|
|
- connection.privmsg(nick, 'variable ("%s") successfully set to value ("%s")' % (variable, ' '.join(value) if isinstance(value, list) else value))
|
|
|
+ connection.privmsg(nick, 'variable ("%s") successfully set to value ("%s")' % (variable, ' '.join(value) if isinstance(value, list) else '%f,%f' % value if isinstance(value, tuple) else value))
|
|
|
|
|
|
def __status(self, connection, nick, login, arguments):
|
|
|
_nick = arguments.split(None, 1)[0] if arguments else None
|
|
@@ -484,7 +523,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
db, cursor = self.__db()
|
|
|
|
|
|
- cursor.execute('update locationbot.nick set ' + variable + ' = null' + (', coordinates = null, updated = null' if variable == 'location' else '') + ' where nick = %s and ' + variable + ' is not null', (login,))
|
|
|
+ cursor.execute('update locationbot.nick set ' + ('location = null, coordinates = null, updated = null' if variable in self.__geocode else variable + ' = null') + ' where nick = %s and ' + variable + ' is not null', (login,))
|
|
|
db.commit()
|
|
|
connection.privmsg(nick, 'variable ("%s") %s unset' % (variable, 'successfuly' if cursor.rowcount == 1 else 'already'))
|
|
|
|
|
@@ -602,7 +641,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.__who(connection, nick)
|
|
|
else:
|
|
|
self.__unknown(connection, nick, command)
|
|
|
- except psycopg2.Error, error:
|
|
|
+ except Exception, error:
|
|
|
print error
|
|
|
|
|
|
connection.privmsg(nick, 'an error occurred')
|
|
@@ -679,6 +718,8 @@ if __name__ == '__main__':
|
|
|
|
|
|
try:
|
|
|
while bot.start():
|
|
|
+ import locationbot
|
|
|
+
|
|
|
try:
|
|
|
bot = reload(locationbot).LocationBot(bot)
|
|
|
except (ImportError, SyntaxError), error:
|