weather.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # -*- coding: utf-8 -*-
  2. import requests
  3. import re
  4. import json
  5. import sys
  6. from event import Event
  7. if sys.version_info > (3, 0, 0):
  8. try:
  9. from .basemodule import BaseModule
  10. except (ImportError, SystemError):
  11. from modules.basemodule import BaseModule
  12. else:
  13. try:
  14. from basemodule import BaseModule
  15. except (ImportError, SystemError):
  16. from modules.basemodule import BaseModule
  17. class Weather2(BaseModule):
  18. def post_init(self):
  19. weather2 = Event('__.weather2__')
  20. weather2.define(msg_definition='^\.[Ww]eather')
  21. weather2.subscribe(self)
  22. self.bot.register_event(weather2, self)
  23. # now using openweathermap as wunderground ended theirs :(
  24. self.api_key = "6dc001f4e77cc0985c5013283368be51"
  25. self.api_url = "https://api.openweathermap.org/data/2.5/weather"
  26. def api_request(self, location, channel, command="conditions"):
  27. """location is a search string after the .weather command. This function
  28. will determine whether it is a zip code or a named location and return an
  29. appropriate API call"""
  30. query = None
  31. try:
  32. # test if is a zipcode or a single city name
  33. a = float(location.split()[0])
  34. if a and len(location.split()[0]) < 5:
  35. self.say(channel,"valid zipcode required, numbnuts")
  36. return None
  37. zipcode = re.match('[0-9]{5}', location)
  38. query = '?zip='+zipcode.string
  39. except ValueError: # broken encoding on numbers or something or they tried a city name
  40. self.say(channel, "city name no longer supported due to wunderground API shutdown :(")
  41. if query:
  42. return self.api_url+query+"&appid="+self.api_key+"&units=imperial"
  43. return None
  44. def get_conditions(self, query, channel):
  45. """given a fully formed query to the OpenWeatherMap API, format an output string"""
  46. r = requests.get(query)
  47. try:
  48. r.raise_for_status()
  49. except requests.exceptions.HTTPError:
  50. self.say(channel, "Encountered an error contacting the OpenWeatherMap API")
  51. return
  52. weather = r.json()
  53. try:
  54. #grab the relevant data we want for formatting
  55. location = weather['name']
  56. conditions = weather['weather'][0]['main']
  57. temp_f = str(round(weather['main']['temp'], 1))
  58. except KeyError:
  59. self.say(channel, "Unable to get weather data from results. Sorry.")
  60. return
  61. #return the formatted string of weather data
  62. return location + ': ' + conditions + ', ' + temp_f + '° F'
  63. def handle(self, event):
  64. #split the line beginning with .weather into 2 parts, the command and the search string
  65. weather_line = event.msg.split(None, 1)
  66. if len(weather_line) > 1:
  67. #if we're sure there's actually a search string, then continue
  68. query = self.api_request(weather_line[1], event.channel)
  69. if not query:
  70. return
  71. weather = self.get_conditions(query, event.channel)
  72. if not weather:
  73. return
  74. self.say(event.channel, weather)
  75. else:
  76. #chastise the user for being silly and not actually searching for a location
  77. self.say(event.channel, "It would help if you supplied an actual location to search for.")