SHOW:
|
|
- or go back to the newest paste.
1 | ||
2 | ||
3 | require 'cinch' | |
4 | require 'ostruct' | |
5 | require 'open-uri' | |
6 | require 'json' | |
7 | require 'cinch/toolbox' | |
8 | ||
9 | module Cinch | |
10 | module Plugins | |
11 | class Weather | |
12 | include Cinch::Plugin | |
13 | ||
14 | set :prefix, /^~/ | |
15 | set :help, <<-USAGE.gsub(/^ {6}/, '') | |
16 | Check the weather right from the IRC channel! | |
17 | Usage: | |
18 | * ~weather <location>: The bot will check the weather for the location you provide! | |
19 | USAGE | |
20 | ||
21 | match /weather (.+)/i, method: :current | |
22 | match /f (.+) (.+)/i, method: :hourly | |
23 | ||
24 | def current(m, query) | |
25 | query.gsub! /\s/, '+' | |
26 | geometry = geolookup(query) | |
27 | return m.reply "No results found for #{query}." if geometry.nil? | |
28 | ||
29 | data = get_current(geometry) | |
30 | return m.reply 'Uh oh, there was a problem getting the specified weather data. Try again later.' if data.nil? | |
31 | ||
32 | locale = location_r(query) | |
33 | ||
34 | m.reply(current_summary(data, locale)) | |
35 | end | |
36 | ||
37 | # Now we introduce a method to get the hourly up to 24hrs. | |
38 | ||
39 | def hourly(m, hour, query) | |
40 | query.gsub! /\s/, '+' | |
41 | geometry = geolookup(query) | |
42 | return m.reply "No results found for #{query}." if geometry.nil? | |
43 | ||
44 | data = get_hourly(hour, geometry) | |
45 | return m.reply 'Oh no! There was a problem fetching the specified weather data. Please try again later.' if data.empty? | |
46 | ||
47 | - | m.reply(hourly_summary(hour)) |
47 | + | m.reply(hourly_summary(data,hour)) |
48 | end | |
49 | ||
50 | # Fetch the location from Google Maps for the area the user is looking for to be passed into get_current. | |
51 | ||
52 | def geolookup(zipcode) | |
53 | raw_location = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{zipcode}&sensor=true").read) | |
54 | location = raw_location['results'][0]['geometry']['location'] | |
55 | lat = location['lat'] | |
56 | lng = location['lng'] | |
57 | ||
58 | geometry = "#{lat},#{lng}" | |
59 | return geometry | |
60 | rescue | |
61 | nil | |
62 | end | |
63 | ||
64 | # Fetch the current weather data for the location found in geolookup. | |
65 | ||
66 | def get_current(geometry) | |
67 | data = JSON.parse(open("https://api.forecast.io/forecast/9cf5d8e80388a30e7e37b14e43b9707a/#{geometry}").read) | |
68 | current = data['currently'] | |
69 | ||
70 | OpenStruct.new( | |
71 | conditions: current['summary'], | |
72 | temp: current['temperature'], | |
73 | feels_like: current['apparentTemperature'], | |
74 | wind_speed: current['windSpeed'], | |
75 | wind_bearing: current['windBearing'] | |
76 | ) | |
77 | rescue | |
78 | nil | |
79 | end | |
80 | ||
81 | # Now we are going to fetch the hourly data. | |
82 | ||
83 | def get_hourly(hour, geometry) | |
84 | logo = "10Hourly Fore4cast:" | |
85 | data = JSON.parse(open("https://api.forecast.io/forecast/9cf5d8e80388a30e7e37b14e43b9707a/#{geometry}").read) | |
86 | raw_hourly = data['hourly']['data'] | |
87 | hourly = [] | |
88 | ||
89 | raw_hourly.each{|i| hourly.push("%s Forecast Predicted in #{hour}(s): %s | Temp: %s - Will Feel Like: %s | Wind: %s - Bearing: %s" % [logo, i['summary'], i['temperature'], i['apparentTemperature'], i['windSpeed'], i['windBearing']])} | |
90 | ||
91 | return hourly | |
92 | end | |
93 | ||
94 | - | def hourly_summary(hour) |
94 | + | def hourly_summary(data, hour) |
95 | - | return get_hourly[hour.to_i - 1] |
95 | + | return data[hour.to_i - 1] |
96 | end | |
97 | ||
98 | # We're gonna fetch the location data again so we can pass it into the results. Primitive, but it works. | |
99 | ||
100 | def location_r(location) | |
101 | raw_locale = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}&sensor=true").read) | |
102 | locale_data = raw_locale['results'][0]['formatted_address'] | |
103 | ||
104 | locale = "#{locale_data}" | |
105 | end | |
106 | ||
107 | def current_summary(data, locale) | |
108 | # Converting Imperial for Metric, because it's sane when using a protocol like IRC to deliver this info | |
109 | ||
110 | temp_c = (data.temp - 32) * 5 / 9 | |
111 | feels_temp_c = (data.feels_like - 32) * 5 / 9 | |
112 | wind_speed_kph = data.wind_speed * 1.6 | |
113 | temp_c = (temp_c*10).ceil/10.0 | |
114 | feels_temp_c = (feels_temp_c*10).ceil/10.0 | |
115 | wind_speed_kph = (wind_speed_kph*10).ceil/10.0 | |
116 | ||
117 | # Now, deliver the info to IRC | |
118 | ||
119 | %Q{10Weather: #{locale} | Current Weather: #{data.conditions} | Temp: #{data.temp} F (#{temp_c} C) - Feels like: #{data.feels_like} F (#{feels_temp_c} C) | Wind: #{data.wind_speed} MPH (#{wind_speed_kph} KPH) - Bearing: #{data.wind_bearing}} | |
120 | end | |
121 | end | |
122 | end | |
123 | end |