From 6ae70537c08a149dacd4cee6244b4f481c6bd727 Mon Sep 17 00:00:00 2001 From: Ryan Hitchman Date: Tue, 7 Jan 2014 13:41:07 -0800 Subject: [PATCH] .near: show closest users to you --- plugins/tag.py | 37 ++++++++++++++++++++++++++++++++++++- plugins/weather.py | 36 +++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/plugins/tag.py b/plugins/tag.py index b249434..0653feb 100644 --- a/plugins/tag.py +++ b/plugins/tag.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import math import random import re import threading @@ -128,7 +129,7 @@ def get_nicks_by_tagset(db, chan, tagset): nicks = [munge(x[0], 1) for x in sorted(nicks)] if not nicks: - return 'no tags found in intersection of "%s"' % tagset + return 'no nicks found with tags "%s"' % tagset return 'nicks tagged "%s": ' % tagset + winnow(nicks) @@ -173,6 +174,40 @@ def tagged(inp, chan='', db=None): return get_nicks_by_tagset(db, chan, inp) +def distance(lat1, lon1, lat2, lon2): + deg_to_rad = math.pi / 180 + lat1 *= deg_to_rad + lat2 *= deg_to_rad + lon1 *= deg_to_rad + lon2 *= deg_to_rad + + R = 6371 # km + d = math.acos(math.sin(lat1)*math.sin(lat2) + + math.cos(lat1)*math.cos(lat2) * + math.cos(lon2-lon1)) * R + return d + + +@hook.command(autohelp=False) +def near(inp, nick='', chan='', db=None): + init_db(db) + + try: + loc = db.execute("select lat, lon from location where chan=? and lower(nick)=lower(?)", (chan, nick)).fetchone() + except db.OperationError: + loc = None + + if loc is None: + return 'use .weather first to set your location' + + lat, lon = loc + + db.create_function('distance', 4, distance) + nearby = db.execute("select nick, distance(lat, lon, ?, ?) as dist from location where chan=?" + " limit 20", (lat, lon, chan)).fetchall() + + return nearby + character_replacements = { 'a': 'รค', diff --git a/plugins/weather.py b/plugins/weather.py index 74169dd..cefeda8 100644 --- a/plugins/weather.py +++ b/plugins/weather.py @@ -1,30 +1,43 @@ "weather, thanks to wunderground" +import math + from util import hook, http + @hook.api_key('wunderground') @hook.command(autohelp=False) -def weather(inp, nick='', server='', reply=None, db=None, api_key=None): +def weather(inp, chan='', nick='', reply=None, db=None, api_key=None): ".weather [dontsave] -- gets weather data from Wunderground "\ "http://wunderground.com/weather/api" if not api_key: return None + # this database is used by other plugins interested in user's locations, + # like .near in tag.py + db.execute("create table if not exists location(chan, nick, loc, lat, lon, primary key(chan, lower(nick)))") + loc = inp dontsave = loc.endswith(" dontsave") if dontsave: loc = loc[:-9].strip().lower() - db.execute("create table if not exists weather(nick primary key, loc)") if not loc: # blank line - loc = db.execute("select loc from weather where nick=lower(?)", - (nick,)).fetchone() + loc = db.execute("select loc from location where chan=? and lower(nick)=lower(?)", + (chan, nick)).fetchone() if not loc: - return weather.__doc__ + try: + # grab from old-style weather database + loc = db.execute("select loc from weather where nick=lower(?)", + (nick,)).fetchone() + except db.OperationalError: + pass # no such table + if not loc: + return weather.__doc__ loc = loc[0] loc, _, state = loc.partition(', ') @@ -91,13 +104,18 @@ def weather(inp, nick='', server='', reply=None, db=None, api_key=None): info['l_f'] = sf['low']['fahrenheit'] info['l_c'] = sf['low']['celsius'] info['humid'] = obs['relative_humidity'] - info['wind'] = 'Wind: {mph}mph/{kph}kph'\ + info['wind'] = 'Wind: {mph}mph/{kph}kph' \ .format(mph=obs['wind_mph'], kph=obs['wind_kph']) - reply('{city}: {weather}, {t_f}F/{t_c}C'\ + reply('{city}: {weather}, {t_f}F/{t_c}C' \ '(H:{h_f}F/{h_c}C L:{l_f}F/{l_c}C)' \ ', Humidity: {humid}, {wind}'.format(**info)) + lat = float(obs['display_location']['latitude']) + lon = float(obs['display_location']['longitude']) + if inp and not dontsave: - db.execute("insert or replace into weather(nick, loc) values (?,?)", - (nick.lower(), inp)) + db.execute("insert or replace into location(chan, nick, loc, lat, lon) " + "values (?, ?, ?, ?,?)", (chan, nick, inp, lat, lon)) db.commit() + +