Source code for modules.weather

# -*- coding: utf-8 -*-

import json
import sys
import requests
from event import Event

if sys.version_info > (3, 0, 0):
    try:
        from .basemodule import BaseModule
    except (ImportError, SystemError):
        from modules.basemodule import BaseModule
else:
    try:
        from basemodule import BaseModule
    except (ImportError, SystemError):
        from modules.basemodule import BaseModule


[docs]class Weather(BaseModule):
[docs] def post_init(self): weather2 = Event('__.weather2__') weather2.define( msg_definition=r'^\.weather |^\.w ', case_insensitive=True) weather2.subscribe(self) self.bot.register_event(weather2, self) # two apis because we get the lat/long from bing's actually really good location search self.bing_api_url = "http://dev.virtualearth.net/REST/v1/Locations?query=" self.bing_api_key_string = "&key=AuEaLSdFYvXwY4u1FnyP-f9l5u5Ul9AUA_U1F-eJ-8O_Fo9Cngl95z6UL0Lr5Nmx" self.api_key = "6dc001f4e77cc0985c5013283368be51" self.api_url = "https://api.openweathermap.org/data/2.5/weather" self.headers = { 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36', }
[docs] def get_lat_long_from_bing(self, location): """ go grab the latitude/longitude from bing's really excellent location API. Returns: tuple of x,y coordinates - (0,0) on error """ u = self.bing_api_url + location + self.bing_api_key_string j = json.loads(requests.get(u, self.headers).text) try: x = j['resourceSets'][0]['resources'][0]['geocodePoints'][0]['coordinates'][0] y = j['resourceSets'][0]['resources'][0]['geocodePoints'][0]['coordinates'][1] except IndexError: return (0, 0) return (x, y)
[docs] def get_api_request(self, x, y): """ Simple form the query string and return it. """ return self.api_url + "?lat=" + \ str(x) + "&lon=" + str(y) + \ "&units=imperial" + "&appid=" + self.api_key
[docs] def get_conditions(self, query, channel): """given a fully formed query to the OpenWeatherMap API, format an output string""" r = requests.get(query) try: r.raise_for_status() except requests.exceptions.HTTPError: self.say( channel, "Encountered an error contacting the OpenWeatherMap API") return weather = r.json() #print(weather) try: # grab the relevant data we want for formatting location = weather['name'] conditions = weather['weather'][0]['main'] temp_f = round(weather['main']['temp'], 1) temp_c = round((temp_f - 32) * (5.0 / 9.0), 1) #sky = weather['weather'][0]['main'] #print(sky) except KeyError: self.say( channel, "Unable to get weather data from results. Sorry.") return # return the formatted string of weather data return location + ': ' + conditions + ', ' + \ str(temp_f) + '°F (' + str(temp_c) + '°C)'
[docs] def handle(self, event): # split the line beginning with .weather into 2 parts, the command and # the search string weather_line = event.msg.split(None, 1) if len(weather_line) > 1: # if we're sure there's actually a search string, then continue x, y = self.get_lat_long_from_bing(weather_line[1]) weather = self.get_conditions( self.get_api_request( x, y), event.channel) if not weather: return self.say(event.channel, weather) else: # chastise the user for being silly and not actually searching for # a location self.say( event.channel, "It would help if you supplied an actual location to search for.")