2012-10-13 03:02:22 +02:00
|
|
|
from util import hook, web
|
2012-09-10 12:55:34 +02:00
|
|
|
|
|
|
|
|
2012-09-11 14:16:06 +02:00
|
|
|
def get_weather(location):
|
2012-09-10 12:55:34 +02:00
|
|
|
"""uses the yahoo weather API to get weather information for a location"""
|
|
|
|
|
2012-09-11 14:27:26 +02:00
|
|
|
query = "SELECT * FROM weather.bylocation WHERE location=@location LIMIT 1"
|
2012-10-13 03:02:22 +02:00
|
|
|
result = web.query(query, {"location": location})
|
2012-09-11 14:16:06 +02:00
|
|
|
|
2012-10-13 03:02:22 +02:00
|
|
|
data = result.rows[0]["rss"]["channel"]
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 00:17:30 +02:00
|
|
|
# wind conversions
|
|
|
|
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))
|
2012-09-10 12:55:34 +02:00
|
|
|
|
|
|
|
# textual wind direction
|
2012-09-11 00:17:30 +02:00
|
|
|
direction = data['wind']['direction']
|
2012-09-10 12:55:34 +02:00
|
|
|
if direction >= 0 and direction < 45:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'N'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 45 and direction < 90:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'NE'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 90 and direction < 135:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'E'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 135 and direction < 180:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'SE'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 180 and direction < 225:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'S'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 225 and direction < 270:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'SW'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 270 and direction < 315:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'W'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif direction >= 315 and direction < 360:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'NW'
|
2012-09-10 12:55:34 +02:00
|
|
|
else:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['wind']['text'] = 'N'
|
|
|
|
|
|
|
|
# visibility and pressure conversions
|
|
|
|
data['atmosphere']['visibility_km'] = \
|
|
|
|
int(round(float(data['atmosphere']['visibility']) * 1.609344))
|
|
|
|
data['atmosphere']['visibility_km'] = \
|
|
|
|
str(round((float(data['atmosphere']['visibility']) * 33.8637526), 2))
|
2012-09-10 12:55:34 +02:00
|
|
|
|
|
|
|
# textual value for air pressure
|
2012-09-11 00:17:30 +02:00
|
|
|
rising = data['atmosphere']['rising']
|
2012-09-10 12:55:34 +02:00
|
|
|
if rising == 0:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['atmosphere']['tendancy'] = 'steady'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif rising == 1:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['atmosphere']['tendancy'] = 'rising'
|
2012-09-10 12:55:34 +02:00
|
|
|
elif rising == 2:
|
2012-09-11 00:17:30 +02:00
|
|
|
data['atmosphere']['tendancy'] = 'falling'
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 00:17:30 +02:00
|
|
|
# current conditions
|
|
|
|
data['item']['condition']['temp_c'] = \
|
|
|
|
int(round(((float(data['item']['condition']['temp']) - 32) / 9) * 5))
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 00:17:30 +02:00
|
|
|
# forecasts
|
|
|
|
for i in data['item']['forecast']:
|
|
|
|
i['high_c'] = \
|
|
|
|
int(round(((float(i['high']) - 32) / 9) * 5))
|
|
|
|
i['low_c'] = \
|
2012-09-11 21:35:57 +02:00
|
|
|
int(round(((float(i['low']) - 32) / 9) * 5))
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 00:17:30 +02:00
|
|
|
return data
|
2011-11-20 10:23:31 +01:00
|
|
|
|
2012-02-29 07:09:19 +01:00
|
|
|
|
2011-11-20 10:23:31 +01:00
|
|
|
@hook.command(autohelp=False)
|
2012-09-11 14:16:06 +02:00
|
|
|
def weather(inp, nick="", reply=None, db=None, notice=None):
|
2012-05-16 05:07:27 +02:00
|
|
|
"weather <location> [dontsave] -- Gets weather data"\
|
2012-09-11 14:16:06 +02:00
|
|
|
" for <location> from Yahoo."
|
2011-11-20 10:23:31 +01:00
|
|
|
|
2012-09-10 12:55:34 +02:00
|
|
|
# initalise weather DB
|
2012-09-11 14:16:06 +02:00
|
|
|
db.execute("create table if not exists weather(nick primary key, loc)")
|
2011-11-20 10:23:31 +01:00
|
|
|
|
2012-09-10 12:55:34 +02:00
|
|
|
# if there is no input, try getting the users last location from the DB
|
|
|
|
if not inp:
|
2012-09-11 14:16:06 +02:00
|
|
|
location = db.execute("select loc from weather where nick=lower(?)",
|
2012-09-10 12:55:34 +02:00
|
|
|
[nick]).fetchone()
|
2012-09-11 14:16:06 +02:00
|
|
|
if not location:
|
2012-09-10 12:55:34 +02:00
|
|
|
# no location saved in the database, send the user help text
|
2011-11-20 10:23:31 +01:00
|
|
|
notice(weather.__doc__)
|
|
|
|
return
|
2012-09-11 14:16:06 +02:00
|
|
|
location = location[0]
|
2012-09-10 12:55:34 +02:00
|
|
|
|
|
|
|
# no need to save a location, we already have it
|
|
|
|
dontsave = True
|
|
|
|
else:
|
|
|
|
# see if the input ends with "dontsave"
|
|
|
|
dontsave = inp.endswith(" dontsave")
|
|
|
|
|
|
|
|
# remove "dontsave" from the input string after checking for it
|
|
|
|
if dontsave:
|
|
|
|
location = inp[:-9].strip().lower()
|
|
|
|
else:
|
|
|
|
location = inp
|
|
|
|
|
|
|
|
# now, to get the actual weather
|
2012-09-11 14:16:06 +02:00
|
|
|
try:
|
2012-09-11 21:18:06 +02:00
|
|
|
data = get_weather(location)
|
2012-09-11 14:16:06 +02:00
|
|
|
except KeyError:
|
|
|
|
return "Could not get weather for that location."
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 21:18:06 +02:00
|
|
|
# put all the stuff we want to use in a dictionary for easy formatting of the output
|
2012-09-11 21:39:15 +02:00
|
|
|
weather_data = {
|
2012-09-11 21:18:06 +02:00
|
|
|
"place": data['location']['city'],
|
|
|
|
"conditions": data['item']['condition']['text'],
|
|
|
|
"temp_f": data['item']['condition']['temp'],
|
|
|
|
"temp_c": data['item']['condition']['temp_c'],
|
|
|
|
"humidity": data['atmosphere']['humidity'],
|
|
|
|
"wind_kph": data['wind']['speed_kph'],
|
|
|
|
"wind_mph": data['wind']['speed'],
|
|
|
|
"wind_text": data['wind']['text'],
|
|
|
|
"forecast": data['item']['forecast'][0]['text'],
|
|
|
|
"high_f": data['item']['forecast'][0]['high'],
|
|
|
|
"high_c": data['item']['forecast'][0]['high_c'],
|
|
|
|
"low_f": data['item']['forecast'][0]['low'],
|
|
|
|
"low_c": data['item']['forecast'][0]['low_c']
|
|
|
|
}
|
|
|
|
|
|
|
|
reply("\x02{place}\x02 - \x02Current Conditions:\x02 {conditions}, {temp_f}F/{temp_c}C, Humidity: {humidity}%, " \
|
2012-09-11 21:39:15 +02:00
|
|
|
"Wind: {wind_kph}KPH/{wind_mph}MPH {wind_text}, \x02Today's Forecast:\x02 {forecast}, " \
|
|
|
|
"High: {high_f}F/{high_c}C, Low: {low_f}F/{low_c}C.".format(**weather_data))
|
2012-09-10 12:55:34 +02:00
|
|
|
|
2012-09-11 14:16:06 +02:00
|
|
|
if location and not dontsave:
|
|
|
|
db.execute("insert or replace into weather(nick, loc) values (?,?)",
|
|
|
|
(nick.lower(), location))
|
2012-09-11 00:17:30 +02:00
|
|
|
db.commit()
|
2012-09-12 07:04:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
@hook.command(autohelp=False)
|
|
|
|
def forecast(inp, nick="", reply=None, db=None, notice=None):
|
|
|
|
"forecast <location> [dontsave] -- Gets weather data"\
|
|
|
|
" for <location> from Yahoo."
|
|
|
|
|
|
|
|
# initalise weather DB
|
|
|
|
db.execute("create table if not exists weather(nick primary key, loc)")
|
|
|
|
|
|
|
|
# if there is no input, try getting the users last location from the DB
|
|
|
|
if not inp:
|
|
|
|
location = db.execute("select loc from weather where nick=lower(?)",
|
|
|
|
[nick]).fetchone()
|
|
|
|
if not location:
|
|
|
|
# no location saved in the database, send the user help text
|
|
|
|
notice(forecast.__doc__)
|
|
|
|
return
|
|
|
|
location = location[0]
|
|
|
|
|
|
|
|
# no need to save a location, we already have it
|
|
|
|
dontsave = True
|
|
|
|
else:
|
|
|
|
# see if the input ends with "dontsave"
|
|
|
|
dontsave = inp.endswith(" dontsave")
|
|
|
|
|
|
|
|
# remove "dontsave" from the input string after checking for it
|
|
|
|
if dontsave:
|
|
|
|
location = inp[:-9].strip().lower()
|
|
|
|
else:
|
|
|
|
location = inp
|
|
|
|
|
|
|
|
# now, to get the actual weather (forecast)
|
|
|
|
try:
|
|
|
|
data = get_weather(location)
|
|
|
|
except KeyError:
|
|
|
|
return "Could not get weather for that location."
|
|
|
|
|
|
|
|
# put all the stuff we want to use in a dictionary for easy formatting of the output
|
|
|
|
weather_data = {
|
|
|
|
"place": data['location']['city'],
|
|
|
|
"forecast": data['item']['forecast'][0]['text'],
|
|
|
|
"high_f": data['item']['forecast'][0]['high'],
|
|
|
|
"high_c": data['item']['forecast'][0]['high_c'],
|
|
|
|
"low_f": data['item']['forecast'][0]['low'],
|
|
|
|
"low_c": data['item']['forecast'][0]['low_c'],
|
|
|
|
"_forecast": data['item']['forecast'][1]['text'],
|
|
|
|
"_high_f": data['item']['forecast'][1]['high'],
|
|
|
|
"_high_c": data['item']['forecast'][1]['high_c'],
|
|
|
|
"_low_f": data['item']['forecast'][1]['low'],
|
|
|
|
"_low_c": data['item']['forecast'][1]['low_c']
|
|
|
|
}
|
|
|
|
|
|
|
|
reply("\x02{place}\x02 - \x02Today's Forecast:\x02 {forecast}, " \
|
|
|
|
"High: {high_f}F/{high_c}C, Low: {low_f}F/{low_c}C, "
|
|
|
|
"\x02Tomorrow's Forecast:\x02 {_forecast}, High: {_high_f}F" \
|
|
|
|
"/{_high_c}C, Low: {_low_f}F/{_low_c}C.".format(**weather_data))
|
|
|
|
|
|
|
|
if location and not dontsave:
|
|
|
|
db.execute("insert or replace into weather(nick, loc) values (?,?)",
|
|
|
|
(nick.lower(), location))
|
|
|
|
db.commit()
|