forecast.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from event import Event
  2. import json
  3. import requests
  4. class Forecast:
  5. def __init__(self, events=None, printer_handle=None, bot=None, say=None):
  6. self.events = events
  7. self.printer = printer_handle
  8. self.interests = ['__.forecast__']
  9. self.bot = bot
  10. forecast = Event("__.forecast__")
  11. forecast.define(msg_definition="^\.forecast")
  12. forecast.subscribe(self)
  13. self.bot.register_event(forecast, self)
  14. self.help = ".forecast <location>"
  15. def get_location(self, location_search):
  16. """Returns a list of 3 strings. A formatted location, its latitude, and its longitude"""
  17. if location_search == '':
  18. return None
  19. address = location_search.replace(' ', '+')
  20. key = 'AIzaSyBr4KECytQxPN8PDZhWczIvyK7voqjdN3c'
  21. #key = "AIzaSyA95TSuDZMUySAeijsNuIiqX7cJFbXKUSw"
  22. parameters = {'address': address, 'sensor': 'false', 'key': key}
  23. try:
  24. raw = requests.get('https://maps.googleapis.com/maps/api/geocode/json', params=parameters)
  25. raw.raise_for_status()
  26. geocode = raw.json()
  27. except ValueError:
  28. return ['Error: Cannot form json object']
  29. except requests.exceptions.HTTPError:
  30. return ['Trouble retrieving data from Google API']
  31. try:
  32. latitude = geocode['results'][0]['geometry']['location']['lat']
  33. longitude = geocode['results'][0]['geometry']['location']['lng']
  34. location_name = geocode['results'][0]['formatted_address']
  35. except (IndexError, KeyError), e:
  36. return ['Location not found']
  37. return [location_name, str(latitude), str(longitude)]
  38. def get_forecast(self, latitude="", longitude=""):
  39. """Returns a JSON formatted object with all weather data on the requested
  40. latitude and longitude. latitude and longitude are strings
  41. """
  42. key = "5a9290d413a126311a547f2de4f510c6"
  43. try:
  44. return requests.get('https://api.forecast.io/forecast/'+key+'/'+latitude+','+longitude).json()
  45. except ValueError:
  46. return {}
  47. def current(self, current_data={}):
  48. """Takes a JSON formatted object of data on current weather conditions from forecast.io
  49. Formats into a summarized string for IRC bot use
  50. """
  51. #if no data provided, return a string saying so
  52. conditions = ''
  53. if current_data == {}:
  54. return "No data on current weather conditions."
  55. #Add the data on current temperature. We round the data, cast as int, add into the string
  56. conditions += str(int(round(current_data['temperature']))) + u'\u00B0.'
  57. #Add data on cloud cover. Should alway be available. Descriptions taken from forecast.io api docs
  58. if current_data['cloudCover'] >= 0 and current_data['cloudCover'] < 0.4:
  59. conditions += " Clear skies."
  60. elif current_data['cloudCover'] >= 0.4 and current_data['cloudCover'] < 0.75:
  61. conditions += " Partly cloudy."
  62. elif current_data['cloudCover'] >= 0.75 and current_data['cloudCover'] < 1:
  63. conditions += " Mostly cloudy."
  64. else:
  65. conditions += " Overcast."
  66. #If there is any precipitation data, get the intensity and type of precipitation added into the description
  67. try:
  68. if current_data['precipIntensity'] > 0:
  69. if current_data['precipIntensity'] > 0 and current_data['precipIntensity'] <= 0.017:
  70. conditions += " Very light "
  71. elif current_data['precipIntensity'] > 0.017 and current_data['precipIntensity'] <= 0.1:
  72. conditions += " Light "
  73. elif current_data['precipIntensity'] >= 0.1 and current_data['precipIntensity'] < 0.4:
  74. conditions += " Moderate "
  75. elif current_data['precipIntensity'] >= 0.4:
  76. conditions += " Heavy "
  77. conditions += current_data['precipType'] + '.'
  78. except KeyError:
  79. pass
  80. return conditions
  81. def handle(self, event):
  82. _z = str.split(event.msg, None, 1)
  83. #print "Debugging: Reached stage 1 of handle()"
  84. if _z[1] != '':
  85. cur = ''
  86. loc = self.get_location(_z[1])
  87. if len(loc) == 3: #if there are 3 items, valid data retrieved. if not, it didn't work
  88. cur = ': ' + self.current(self.get_forecast(loc[1], loc[2])['currently'])
  89. try:
  90. self.printer("PRIVMSG " + event.channel + ' :' + loc[0] + cur + '\n')
  91. except TypeError:
  92. print "DEBUG: TypeError: ",
  93. print event.channel,
  94. print event.user