|
@@ -12,6 +12,7 @@ import ircbot
|
|
|
import irclib
|
|
|
import os
|
|
|
import psycopg2
|
|
|
+import psycopg2.extensions
|
|
|
import pytz
|
|
|
import re
|
|
|
import sys
|
|
@@ -95,11 +96,6 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
def __admin(self, nickmask):
|
|
|
return _or(lambda admin: irclib.mask_matches(nickmask, admin), self.__admins)
|
|
|
|
|
|
- def __db(self):
|
|
|
- db = psycopg2.connect(self.__dsn)
|
|
|
-
|
|
|
- return db, db.cursor()
|
|
|
-
|
|
|
def __channel(self, nick, exclude = None):
|
|
|
if exclude is not None:
|
|
|
exclude = irclib.irc_lower(exclude)
|
|
@@ -109,6 +105,20 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
return _or(lambda channel: channel.has_user(nick), channels)
|
|
|
|
|
|
+ def __coordinates(self, coordinates):
|
|
|
+ return ' http://maps.google.com/maps?q=%f,%f' % coordinates if coordinates else ''
|
|
|
+
|
|
|
+ def __db(self):
|
|
|
+ db = psycopg2.connect(self.__dsn)
|
|
|
+
|
|
|
+ def point(value, cursor):
|
|
|
+ if value is not None:
|
|
|
+ return tuple(map(lambda a: float(a), re.match(r'^\(([^)]+),([^)]+)\)$', value).groups()))
|
|
|
+
|
|
|
+ psycopg2.extensions.register_type(psycopg2.extensions.new_type((600,), 'point', point), db)
|
|
|
+
|
|
|
+ return db, db.cursor()
|
|
|
+
|
|
|
def __help(self, connection, nick, admin, login, arguments):
|
|
|
command = irclib.irc_lower(arguments.split(None, 1)[0].lstrip('!')) if arguments else None
|
|
|
commands = {
|
|
@@ -201,7 +211,9 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
continue
|
|
|
|
|
|
try:
|
|
|
- properties = geo['features'][0]['properties']
|
|
|
+ feature = geo['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)
|
|
@@ -209,10 +221,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
print error
|
|
|
continue
|
|
|
|
|
|
- cursor.execute('update locationbot.nick set location = %s, updated = %s where latitude = %s', (new_location, updated, latitude))
|
|
|
+ cursor.execute('update locationbot.nick set location = %s, coordinates = point %s, updated = %s where latitude = %s', (new_location, coordinates, updated, latitude))
|
|
|
db.commit()
|
|
|
|
|
|
- self.__location(nick, channels, old_location, new_location)
|
|
|
+ self.__location(nick, channels, old_location, new_location, coordinates)
|
|
|
except psycopg2.Error, error:
|
|
|
print error
|
|
|
|
|
@@ -221,11 +233,11 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
self.__latitude_timer.start()
|
|
|
|
|
|
- def __location(self, nick, channels, old_location, new_location):
|
|
|
+ def __location(self, nick, channels, old_location, new_location, coordinates = None):
|
|
|
if channels and new_location and new_location != old_location:
|
|
|
with self.__locations_lock:
|
|
|
for channel in self.__channels.intersection(channels):
|
|
|
- self.__locations.append((nick, channel, new_location))
|
|
|
+ self.__locations.append((nick, channel, new_location, coordinates))
|
|
|
|
|
|
def __login(self, connection, nickmask, nick, arguments = ''):
|
|
|
login = nick
|
|
@@ -414,7 +426,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
return invalid(value)
|
|
|
|
|
|
try:
|
|
|
- cursor.execute('update locationbot.nick set ' + variable + ' = ' + ('md5(%s)' if variable == 'secret' else '%s') + (', updated = now()' if variable == 'location' else '') + ' where nick = %s', (value, login))
|
|
|
+ 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))
|
|
|
db.commit()
|
|
|
except psycopg2.IntegrityError:
|
|
|
if variable == 'nick':
|
|
@@ -433,7 +445,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
_nick = arguments.split(None, 1)[0] if arguments else None
|
|
|
db, cursor = self.__db()
|
|
|
|
|
|
- cursor.execute('select nick, location, updated from locationbot.nick where ' + ('nick = %s and ' if _nick is not None else '') + 'location is not null order by updated desc', (_nick,))
|
|
|
+ cursor.execute('select nick, location, coordinates, updated from locationbot.nick where ' + ('nick = %s and ' if _nick is not None else '') + 'location is not null order by updated desc', (_nick,))
|
|
|
|
|
|
if cursor.rowcount == 0:
|
|
|
return connection.privmsg(nick, 'no location information for ' + ('"%s"' % _nick if _nick is not None else 'anybody'))
|
|
@@ -447,10 +459,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
else:
|
|
|
timezone = pytz.utc
|
|
|
|
|
|
- connection.privmsg(nick, '\x02nick location when\x0f')
|
|
|
+ connection.privmsg(nick, '\x02nick location when map\x0f')
|
|
|
|
|
|
- for _nick, location, updated in locations:
|
|
|
- connection.privmsg(nick, '%-23s %-36s %s' % (_nick, location, timezone.normalize(updated.astimezone(timezone)).strftime('%Y-%m-%d %H:%M %Z')))
|
|
|
+ for _nick, location, coordinates, updated in locations:
|
|
|
+ connection.privmsg(nick, '%-23s %-35s %-23s %s' % (_nick, location, timezone.normalize(updated.astimezone(timezone)).strftime('%Y-%m-%d %H:%M %Z'), self.__coordinates(coordinates)))
|
|
|
|
|
|
def __unknown(self, connection, nick, command):
|
|
|
connection.privmsg(nick, 'unknown command ("%s"); try "help"' % command)
|
|
@@ -472,7 +484,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
db, cursor = self.__db()
|
|
|
|
|
|
- cursor.execute('update locationbot.nick set ' + variable + ' = null' + (', updated = null' if variable == 'location' else '') + ' where nick = %s and ' + variable + ' is not null', (login,))
|
|
|
+ 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,))
|
|
|
db.commit()
|
|
|
connection.privmsg(nick, 'variable ("%s") %s unset' % (variable, 'successfuly' if cursor.rowcount == 1 else 'already'))
|
|
|
|
|
@@ -622,8 +634,8 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
while not self.__reloading:
|
|
|
if self.__locations_lock.acquire(False):
|
|
|
if self.__locations and self.__channels.issubset(self.channels.keys()):
|
|
|
- for nick, channel, location in self.__locations:
|
|
|
- self.connection.notice(channel, '%s is in %s' % (nick, location))
|
|
|
+ for nick, channel, location, coordinates in self.__locations:
|
|
|
+ self.connection.notice(channel, '%s is in %s' % (nick, location + self.__coordinates(coordinates)))
|
|
|
|
|
|
self.__locations = []
|
|
|
|