Rewrote weather.py to use YQL

This commit is contained in:
Luke Rogers 2012-09-11 10:17:30 +12:00
parent 48aeb9426f
commit 16d26a0a01

View file

@ -1,94 +1,66 @@
from util import hook, http from util import hook
import yql
api_url = "http://weather.yahooapis.com/forecastrss"
def get_weather(location_id): def get_weather(location_id):
"""uses the yahoo weather API to get weather information for a location""" """uses the yahoo weather API to get weather information for a location"""
xml = http.get_xml(api_url, p=location_id) y = yql.Public()
data = xml.xpath('//y:location', \ query = 'select * from weather.forecast where woeid = "{}"'.format(location_id)
namespaces={'y': 'http://xml.weather.yahoo.com/ns/rss/1.0'})[0] data = y.execute(query).one()
# create a dictionary for weather data # wind conversions
weather = {} data['wind']['chill_c'] = int(round((int(data['wind']['chill']) - 32) / 1.8, 0))
data['wind']['speed_kph'] = int(round(float(data['wind']['speed']) * 1.609344))
weather['city'] = data.get('city')
weather['region'] = data.get('region')
weather['country'] = data.get('country')
# get wind information
wind = xml.xpath('//y:wind', \
namespaces={'y': 'http://xml.weather.yahoo.com/ns/rss/1.0'})[0]
# wind chill
weather['chill_f'] = wind.get('chill')
weather['chill_c'] = int(round((int(wind.get('chill')) - 32) / 1.8, 0))
# wind speed
weather['wind_speed_kph'] = int(round(float(wind.get('speed')) * 1.609344))
weather['wind_speed_mph'] = wind.get('speed')
# wind_direction
weather['wind_direction'] = wind.get('direction')
# textual wind direction # textual wind direction
direction = weather['wind_direction'] direction = data['wind']['direction']
if direction >= 0 and direction < 45: if direction >= 0 and direction < 45:
weather['wind_direction_text'] = 'N' data['wind']['text'] = 'N'
elif direction >= 45 and direction < 90: elif direction >= 45 and direction < 90:
weather['wind_direction_text'] = 'NE' data['wind']['text'] = 'NE'
elif direction >= 90 and direction < 135: elif direction >= 90 and direction < 135:
weather['wind_direction_text'] = 'E' data['wind']['text'] = 'E'
elif direction >= 135 and direction < 180: elif direction >= 135 and direction < 180:
weather['wind_direction_text'] = 'SE' data['wind']['text'] = 'SE'
elif direction >= 180 and direction < 225: elif direction >= 180 and direction < 225:
weather['wind_direction_text'] = 'S' data['wind']['text'] = 'S'
elif direction >= 225 and direction < 270: elif direction >= 225 and direction < 270:
weather['wind_direction_text'] = 'SW' data['wind']['text'] = 'SW'
elif direction >= 270 and direction < 315: elif direction >= 270 and direction < 315:
weather['wind_direction_text'] = 'W' data['wind']['text'] = 'W'
elif direction >= 315 and direction < 360: elif direction >= 315 and direction < 360:
weather['wind_direction_text'] = 'NW' data['wind']['text'] = 'NW'
else: else:
weather['wind_direction_text'] = 'N' data['wind']['text'] = 'N'
# humidity, visibility and pressure # visibility and pressure conversions
atmosphere = xml.xpath('//y:atmosphere', \ data['atmosphere']['visibility_km'] = \
namespaces={'y': 'http://xml.weather.yahoo.com/ns/rss/1.0'})[0] int(round(float(data['atmosphere']['visibility']) * 1.609344))
weather['humidity'] = atmosphere.get('humidity') + "%" data['atmosphere']['visibility_km'] = \
weather['visibility_mi'] = atmosphere.get('visibility') str(round((float(data['atmosphere']['visibility']) * 33.8637526), 2))
weather['visibility_km'] = \
int(round(float(atmosphere.get('visibility')) * 1.609344))
weather['pressure_in'] = atmosphere.get('pressure')
weather['pressure_mb'] = \
str(round((float(atmosphere.get('pressure')) * 33.8637526), 2))
# textual value for air pressure # textual value for air pressure
rising = int(atmosphere.get('rising')) rising = data['atmosphere']['rising']
if rising == 0: if rising == 0:
weather['pressure_tendancy'] = 'steady' data['atmosphere']['tendancy'] = 'steady'
elif rising == 1: elif rising == 1:
weather['pressure_tendancy'] = 'rising' data['atmosphere']['tendancy'] = 'rising'
elif rising == 2: elif rising == 2:
weather['pressure_tendancy'] = 'falling' data['atmosphere']['tendancy'] = 'falling'
# weather condition code, temperature, summary text # current conditions
condition = xml.xpath('//y:condition', \ data['item']['condition']['temp_c'] = \
namespaces={'y': 'http://xml.weather.yahoo.com/ns/rss/1.0'})[0] int(round(((float(data['item']['condition']['temp']) - 32) / 9) * 5))
weather['code'] = condition.get('code')
weather['temp_f'] = condition.get('temp')
weather['temp_c'] = \
int(round(((float(condition.get('temp')) - 32) / 9) * 5))
weather['conditions'] = condition.get('text')
# sunset and sunrise # forecasts
sun = xml.xpath('//y:astronomy', \ for i in data['item']['forecast']:
namespaces={'y': 'http://xml.weather.yahoo.com/ns/rss/1.0'})[0] i['high_c'] = \
weather['sunrise'] = sun.get('sunrise') int(round(((float(i['high']) - 32) / 9) * 5))
weather['sunset'] = sun.get('sunset') i['low_c'] = \
int(round(((float(i['high']) - 32) / 9) * 5))
return weather return data
@hook.command(autohelp=False) @hook.command(autohelp=False)
@ -97,11 +69,11 @@ def weather(inp, nick='', server='', reply=None, db=None, notice=None):
" for <location> from Google." " for <location> from Google."
# initalise weather DB # initalise weather DB
db.execute("create table if not exists yahoo_weather(nick primary key, location_id)") db.execute("create table if not exists y_weather(nick primary key, location_id)")
# if there is no input, try getting the users last location from the DB # if there is no input, try getting the users last location from the DB
if not inp: if not inp:
location_id = db.execute("select location_id from yahoo_weather where nick=lower(?)", location_id = db.execute("select location_id from y_weather where nick=lower(?)",
[nick]).fetchone() [nick]).fetchone()
if not location_id: if not location_id:
# no location saved in the database, send the user help text # no location saved in the database, send the user help text
@ -122,20 +94,22 @@ def weather(inp, nick='', server='', reply=None, db=None, notice=None):
location = inp location = inp
# get the weather.com location id from the location # get the weather.com location id from the location
w = http.get_xml('http://xoap.weather.com/search/search', where=location) query = 'select * from geo.places where text = "{}" limit 1'.format(location)
try: y = yql.Public()
location_id = w.find('loc').get('id') results = y.execute(query).one()
except AttributeError: location_id = results.get("woeid")
return "Unknown location."
# now, to get the actual weather # now, to get the actual weather
data = get_weather(location_id) d = get_weather(location_id)
reply('Current Conditions for \x02%(city)s\x02 - %(conditions)s, %(temp_f)sF/%(temp_c)sC, %(humidity)s, ' \ reply("Current Conditions for \x02{}\x02 - {}, {}F/{}C, {}%, " \
'Wind: %(wind_speed_kph)sKPH/%(wind_speed_mph)sMPH %(wind_direction_text)s.' % data) "Wind: {}KPH/{}MPH {}.".format(d['location']['city'], \
d['item']['condition']['text'], d['item']['condition']['temp'], \
d['item']['condition']['temp_c'], d['atmosphere']['humidity'], \
d['wind']['speed_kph'], d['wind']['speed'], d['wind']['text']))
if location_id and not dontsave: if location_id and not dontsave:
db.execute("insert or replace into yahoo_weather(nick, location_id) values (?,?)", db.execute("insert or replace into y_weather(nick, location_id) values (?,?)",
(nick.lower(), location_id)) (nick.lower(), location_id))
db.commit() db.commit()