barometer 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/LICENSE +1 -1
- data/{README.rdoc → README.md} +124 -110
- data/Rakefile +1 -21
- data/TODO +8 -9
- data/barometer.gemspec +20 -19
- data/bin/barometer +36 -83
- data/lib/barometer.rb +13 -11
- data/lib/barometer/base.rb +10 -10
- data/lib/barometer/data.rb +1 -1
- data/lib/barometer/data/distance.rb +25 -25
- data/lib/barometer/data/geo.rb +9 -9
- data/lib/barometer/data/local_datetime.rb +24 -20
- data/lib/barometer/data/local_time.rb +13 -13
- data/lib/barometer/data/location.rb +6 -6
- data/lib/barometer/data/pressure.rb +24 -24
- data/lib/barometer/data/speed.rb +28 -28
- data/lib/barometer/data/sun.rb +7 -7
- data/lib/barometer/data/temperature.rb +29 -29
- data/lib/barometer/data/units.rb +9 -9
- data/lib/barometer/data/zone.rb +19 -19
- data/lib/barometer/formats.rb +1 -1
- data/lib/barometer/formats/coordinates.rb +7 -7
- data/lib/barometer/formats/format.rb +6 -6
- data/lib/barometer/formats/geocode.rb +5 -5
- data/lib/barometer/formats/icao.rb +6 -6
- data/lib/barometer/formats/postalcode.rb +3 -3
- data/lib/barometer/formats/short_zipcode.rb +2 -2
- data/lib/barometer/formats/weather_id.rb +10 -10
- data/lib/barometer/formats/woe_id.rb +20 -20
- data/lib/barometer/formats/zipcode.rb +3 -3
- data/lib/barometer/key_file_parser.rb +20 -0
- data/lib/barometer/measurements/measurement.rb +32 -32
- data/lib/barometer/measurements/result.rb +39 -39
- data/lib/barometer/measurements/result_array.rb +12 -12
- data/lib/barometer/query.rb +15 -15
- data/lib/barometer/services.rb +3 -3
- data/lib/barometer/translations/icao_country_codes.yml +20 -20
- data/lib/barometer/translations/weather_country_codes.yml +1 -1
- data/lib/barometer/translations/zone_codes.yml +2 -2
- data/lib/barometer/version.rb +3 -0
- data/lib/barometer/weather.rb +27 -27
- data/lib/barometer/weather_services/noaa.rb +314 -3
- data/lib/barometer/weather_services/service.rb +32 -30
- data/lib/barometer/weather_services/weather_bug.rb +35 -33
- data/lib/barometer/weather_services/wunderground.rb +31 -29
- data/lib/barometer/weather_services/yahoo.rb +36 -35
- data/lib/barometer/web_services/geocode.rb +5 -7
- data/lib/barometer/web_services/noaa_station_id.rb +53 -0
- data/lib/barometer/web_services/placemaker.rb +11 -13
- data/lib/barometer/web_services/timezone.rb +5 -7
- data/lib/barometer/web_services/weather_id.rb +4 -6
- data/lib/barometer/web_services/web_service.rb +4 -4
- data/spec/barometer_spec.rb +25 -27
- data/spec/cassettes/Barometer.json +1 -0
- data/spec/cassettes/Query.json +1 -0
- data/spec/cassettes/Query_Format_Coordinates.json +1 -0
- data/spec/cassettes/Query_Format_Geocode.json +1 -0
- data/spec/cassettes/Query_Format_WeatherID.json +1 -0
- data/spec/cassettes/Query_Format_WoeID.json +1 -0
- data/spec/cassettes/WeatherService.json +1 -0
- data/spec/cassettes/WeatherService_Noaa.json +1 -0
- data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
- data/spec/cassettes/WeatherService_Wunderground.json +1 -0
- data/spec/cassettes/WeatherService_Yahoo.json +1 -0
- data/spec/cassettes/WebService_Geocode.json +1 -0
- data/spec/cassettes/WebService_NoaaStation.json +1 -0
- data/spec/data/distance_spec.rb +60 -60
- data/spec/data/geo_spec.rb +23 -23
- data/spec/data/local_datetime_spec.rb +44 -44
- data/spec/data/local_time_spec.rb +47 -47
- data/spec/data/location_spec.rb +16 -16
- data/spec/data/pressure_spec.rb +61 -61
- data/spec/data/speed_spec.rb +69 -69
- data/spec/data/sun_spec.rb +25 -25
- data/spec/data/temperature_spec.rb +68 -68
- data/spec/data/units_spec.rb +21 -21
- data/spec/data/zone_spec.rb +35 -35
- data/spec/formats/coordinates_spec.rb +27 -27
- data/spec/formats/format_spec.rb +17 -25
- data/spec/formats/geocode_spec.rb +23 -31
- data/spec/formats/icao_spec.rb +26 -32
- data/spec/formats/postalcode_spec.rb +22 -28
- data/spec/formats/short_zipcode_spec.rb +20 -26
- data/spec/formats/weather_id_spec.rb +57 -67
- data/spec/formats/woe_id_spec.rb +59 -59
- data/spec/formats/zipcode_spec.rb +39 -47
- data/spec/key_file_parser_spec.rb +28 -0
- data/spec/measurements/measurement_spec.rb +79 -133
- data/spec/measurements/result_array_spec.rb +23 -38
- data/spec/measurements/result_spec.rb +100 -128
- data/spec/query_spec.rb +83 -100
- data/spec/spec_helper.rb +24 -6
- data/spec/weather_services/noaa_spec.rb +179 -0
- data/spec/weather_services/services_spec.rb +28 -36
- data/spec/weather_services/weather_bug_spec.rb +57 -77
- data/spec/weather_services/wunderground_spec.rb +36 -65
- data/spec/weather_services/yahoo_spec.rb +38 -60
- data/spec/weather_spec.rb +79 -79
- data/spec/web_services/geocode_spec.rb +7 -11
- data/spec/web_services/noaa_station_id_spec.rb +33 -0
- data/spec/web_services/placemaker_spec.rb +7 -12
- data/spec/web_services/web_services_spec.rb +3 -9
- metadata +214 -163
- data/VERSION.yml +0 -5
- data/lib/barometer/weather_services/google.rb +0 -142
- data/lib/barometer/weather_services/weather_dot_com.rb +0 -279
- data/spec/fakeweb_helper.rb +0 -179
- data/spec/fixtures/formats/weather_id/90210.xml +0 -7
- data/spec/fixtures/formats/weather_id/from_USGA0028.xml +0 -3
- data/spec/fixtures/formats/weather_id/ksfo.xml +0 -1
- data/spec/fixtures/formats/weather_id/manhattan.xml +0 -7
- data/spec/fixtures/formats/weather_id/new_york.xml +0 -1
- data/spec/fixtures/formats/weather_id/the_hills.xml +0 -1
- data/spec/fixtures/geocode/40_73_v3.json +0 -497
- data/spec/fixtures/geocode/90210_v3.json +0 -63
- data/spec/fixtures/geocode/T5B4M9_v3.json +0 -68
- data/spec/fixtures/geocode/atlanta_v3.json +0 -58
- data/spec/fixtures/geocode/calgary_ab_v3.json +0 -58
- data/spec/fixtures/geocode/ksfo_v3.json +0 -73
- data/spec/fixtures/geocode/newyork_ny_v3.json +0 -58
- data/spec/fixtures/services/google/calgary_ab.xml +0 -1
- data/spec/fixtures/services/placemaker/T5B4M9.xml +0 -65
- data/spec/fixtures/services/placemaker/atlanta.xml +0 -65
- data/spec/fixtures/services/placemaker/coords.xml +0 -65
- data/spec/fixtures/services/placemaker/ksfo.xml +0 -65
- data/spec/fixtures/services/placemaker/new_york.xml +0 -65
- data/spec/fixtures/services/placemaker/the_hills.xml +0 -65
- data/spec/fixtures/services/placemaker/w615702.xml +0 -47
- data/spec/fixtures/services/weather_bug/90210_current.xml +0 -93
- data/spec/fixtures/services/weather_bug/90210_forecast.xml +0 -76
- data/spec/fixtures/services/weather_dot_com/90210.xml +0 -1
- data/spec/fixtures/services/wunderground/current_calgary_ab.xml +0 -9
- data/spec/fixtures/services/wunderground/forecast_calgary_ab.xml +0 -13
- data/spec/fixtures/services/yahoo/90210.xml +0 -3
- data/spec/weather_services/google_spec.rb +0 -181
- data/spec/weather_services/weather_dot_com_spec.rb +0 -224
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'crack'
|
2
|
+
|
1
3
|
module Barometer
|
2
4
|
#
|
3
5
|
# = WeatherBug
|
@@ -34,7 +36,7 @@ module Barometer
|
|
34
36
|
# are specific to WeatherBug and un-supported by Barometer
|
35
37
|
#
|
36
38
|
class WeatherService::WeatherBug < WeatherService
|
37
|
-
|
39
|
+
|
38
40
|
@@api_code = nil
|
39
41
|
|
40
42
|
def self.keys=(keys)
|
@@ -65,7 +67,7 @@ module Barometer
|
|
65
67
|
codes = [0,2,3,4,7,26,31,64,65,75]
|
66
68
|
codes.collect {|c| c.to_s}
|
67
69
|
end
|
68
|
-
|
70
|
+
|
69
71
|
def self._build_extra(measurement, result, metric=true)
|
70
72
|
#raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
71
73
|
#raise ArgumentError unless query.is_a?(Barometer::Query)
|
@@ -76,7 +78,7 @@ module Barometer
|
|
76
78
|
forecast.sun = measurement.current.sun
|
77
79
|
end
|
78
80
|
end
|
79
|
-
|
81
|
+
|
80
82
|
measurement
|
81
83
|
end
|
82
84
|
|
@@ -121,26 +123,26 @@ module Barometer
|
|
121
123
|
|
122
124
|
current
|
123
125
|
end
|
124
|
-
|
126
|
+
|
125
127
|
def self._build_forecast(data, metric=true)
|
126
128
|
raise ArgumentError unless data.is_a?(Hash)
|
127
129
|
forecasts = Measurement::ResultArray.new
|
128
130
|
# go through each forecast and create an instance
|
129
|
-
if data && data["
|
131
|
+
if data && data["forecast"]
|
130
132
|
start_date = Date.strptime(data['date'], "%m/%d/%Y %H:%M:%S %p")
|
131
133
|
i = 0
|
132
|
-
data["
|
134
|
+
data["forecast"].each do |forecast|
|
133
135
|
forecast_measurement = Measurement::Result.new
|
134
|
-
icon_match = forecast['
|
136
|
+
icon_match = forecast['image']['icon'].match(/cond(\d*)\.gif$/)
|
135
137
|
forecast_measurement.icon = icon_match[1].to_i.to_s if icon_match
|
136
138
|
forecast_measurement.date = start_date + i
|
137
|
-
forecast_measurement.condition = forecast['
|
139
|
+
forecast_measurement.condition = forecast['short_prediction']
|
138
140
|
|
139
141
|
forecast_measurement.high = Data::Temperature.new(metric)
|
140
|
-
forecast_measurement.high << forecast['
|
142
|
+
forecast_measurement.high << forecast['high']['__content__']
|
141
143
|
|
142
144
|
forecast_measurement.low = Data::Temperature.new(metric)
|
143
|
-
forecast_measurement.low << forecast['
|
145
|
+
forecast_measurement.low << forecast['low']['__content__']
|
144
146
|
|
145
147
|
forecasts << forecast_measurement
|
146
148
|
i += 1
|
@@ -148,7 +150,7 @@ module Barometer
|
|
148
150
|
end
|
149
151
|
forecasts
|
150
152
|
end
|
151
|
-
|
153
|
+
|
152
154
|
def self._build_location(data, geo=nil)
|
153
155
|
raise ArgumentError unless data.is_a?(Hash)
|
154
156
|
raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
|
@@ -162,15 +164,15 @@ module Barometer
|
|
162
164
|
location.latitude = geo.latitude
|
163
165
|
location.longitude = geo.longitude
|
164
166
|
else
|
165
|
-
if data && data['
|
166
|
-
location.city = data['
|
167
|
-
location.state_code = data['
|
168
|
-
location.zip_code = data['
|
167
|
+
if data && data['location']
|
168
|
+
location.city = data['location']['city']
|
169
|
+
location.state_code = data['location']['state']
|
170
|
+
location.zip_code = data['location']['zip']
|
169
171
|
end
|
170
172
|
end
|
171
173
|
location
|
172
174
|
end
|
173
|
-
|
175
|
+
|
174
176
|
def self._build_station(data)
|
175
177
|
raise ArgumentError unless data.is_a?(Hash)
|
176
178
|
station = Data::Location.new
|
@@ -184,7 +186,7 @@ module Barometer
|
|
184
186
|
station.longitude = data['aws:longitude']
|
185
187
|
station
|
186
188
|
end
|
187
|
-
|
189
|
+
|
188
190
|
def self._build_sun(data)
|
189
191
|
raise ArgumentError unless data.is_a?(Hash)
|
190
192
|
sun = nil
|
@@ -218,16 +220,16 @@ module Barometer
|
|
218
220
|
result << _fetch_forecast(query,metric)
|
219
221
|
result
|
220
222
|
end
|
221
|
-
|
223
|
+
|
222
224
|
# use HTTParty to get the current weather
|
223
225
|
#
|
224
226
|
def self._fetch_current(query, metric=true)
|
225
227
|
puts "fetch weatherbug current: #{query.q}" if Barometer::debug?
|
226
|
-
|
228
|
+
|
227
229
|
q = ( query.format.to_sym == :short_zipcode ?
|
228
230
|
{ :zipCode => query.q } :
|
229
231
|
{ :lat => query.q.split(',')[0], :long => query.q.split(',')[1] })
|
230
|
-
|
232
|
+
|
231
233
|
# httparty and the xml builder it uses miss some information
|
232
234
|
# 1st - get the raw response
|
233
235
|
# 2nd - manually get the missing information
|
@@ -240,36 +242,36 @@ module Barometer
|
|
240
242
|
}.merge(q),
|
241
243
|
:format => :plain,
|
242
244
|
:timeout => Barometer.timeout
|
243
|
-
)
|
244
|
-
|
245
|
+
)
|
246
|
+
|
245
247
|
# get icon
|
246
248
|
icon_match = response.match(/cond(\d*)\.gif/)
|
247
249
|
icon = icon_match[1] if icon_match
|
248
|
-
|
250
|
+
|
249
251
|
# get station zipcode
|
250
252
|
zip_match = response.match(/zipcode=\"(\d*)\"/)
|
251
253
|
zipcode = zip_match[1] if zip_match
|
252
|
-
|
254
|
+
|
253
255
|
# build xml
|
254
|
-
output = Crack::XML.parse(response)
|
256
|
+
output = ::Crack::XML.parse(response)
|
255
257
|
output = output["aws:weather"]["aws:ob"]
|
256
|
-
|
258
|
+
|
257
259
|
# add missing data
|
258
260
|
output["aws:icon"] = icon
|
259
261
|
output["aws:station_zipcode"] = zipcode
|
260
|
-
|
262
|
+
|
261
263
|
output
|
262
264
|
end
|
263
|
-
|
265
|
+
|
264
266
|
# use HTTParty to get the current weather
|
265
267
|
#
|
266
268
|
def self._fetch_forecast(query, metric=true)
|
267
269
|
puts "fetch weatherbug forecast: #{query.q}" if Barometer::debug?
|
268
|
-
|
270
|
+
|
269
271
|
q = ( query.format.to_sym == :short_zipcode ?
|
270
272
|
{ :zipCode => query.q } :
|
271
273
|
{ :lat => query.q.split(',')[0], :long => query.q.split(',')[1] })
|
272
|
-
|
274
|
+
|
273
275
|
self.get(
|
274
276
|
"http://#{@@api_code}.api.wxbug.net/getForecastRSS.aspx",
|
275
277
|
:query => { :ACode => @@api_code,
|
@@ -277,9 +279,9 @@ module Barometer
|
|
277
279
|
}.merge(q),
|
278
280
|
:format => :xml,
|
279
281
|
:timeout => Barometer.timeout
|
280
|
-
)["
|
282
|
+
)["weather"]["forecasts"]
|
281
283
|
end
|
282
|
-
|
284
|
+
|
283
285
|
# since we have two sets of data, override these calls to choose the
|
284
286
|
# right set of data
|
285
287
|
#
|
@@ -292,4 +294,4 @@ module Barometer
|
|
292
294
|
def self._time_result(data=nil); data[0]; end
|
293
295
|
|
294
296
|
end
|
295
|
-
end
|
297
|
+
end
|
@@ -45,17 +45,17 @@ module Barometer
|
|
45
45
|
# Unable to locate.
|
46
46
|
#
|
47
47
|
class WeatherService::Wunderground < WeatherService
|
48
|
-
|
48
|
+
|
49
49
|
#########################################################################
|
50
50
|
# PRIVATE
|
51
51
|
# If class methods could be private, the remaining methods would be.
|
52
52
|
#
|
53
|
-
|
53
|
+
|
54
54
|
def self._source_name; :wunderground; end
|
55
55
|
def self._accepted_formats
|
56
56
|
[:zipcode, :postalcode, :icao, :coordinates, :geocode]
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# these are the icon codes that indicate "wet", used by wet? function
|
60
60
|
def self._wet_icon_codes
|
61
61
|
%w(flurries rain sleet snow tstorms nt_flurries nt_rain nt_sleet nt_snow nt_tstorms chancerain chancetstorms)
|
@@ -75,7 +75,7 @@ module Barometer
|
|
75
75
|
forecast.sun = measurement.current.sun
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
measurement
|
80
80
|
end
|
81
81
|
|
@@ -90,7 +90,7 @@ module Barometer
|
|
90
90
|
)
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
def self._build_links(data)
|
95
95
|
links = {}
|
96
96
|
if data["credit"] && data["credit_URL"]
|
@@ -101,63 +101,65 @@ module Barometer
|
|
101
101
|
|
102
102
|
def self._build_current(data, metric=true)
|
103
103
|
raise ArgumentError unless data.is_a?(Hash)
|
104
|
-
|
104
|
+
|
105
105
|
current = Measurement::Result.new
|
106
|
-
|
106
|
+
if data['observation_time'] && data['observation_time'].match(/\d/)
|
107
|
+
current.updated_at = Data::LocalDateTime.parse(data['observation_time'])
|
108
|
+
end
|
107
109
|
current.humidity = data['relative_humidity'].to_i
|
108
110
|
current.icon = data['icon'] if data['icon']
|
109
|
-
|
111
|
+
|
110
112
|
current.temperature = Data::Temperature.new(metric)
|
111
113
|
current.temperature << [data['temp_c'], data['temp_f']]
|
112
|
-
|
114
|
+
|
113
115
|
current.wind = Data::Speed.new(metric)
|
114
116
|
current.wind.mph = data['wind_mph'].to_f
|
115
117
|
current.wind.degrees = data['wind_degrees'].to_i
|
116
118
|
current.wind.direction = data['wind_dir']
|
117
|
-
|
119
|
+
|
118
120
|
current.pressure = Data::Pressure.new(metric)
|
119
121
|
current.pressure << [data['pressure_mb'], data['pressure_in']]
|
120
|
-
|
122
|
+
|
121
123
|
current.dew_point = Data::Temperature.new(metric)
|
122
124
|
current.dew_point << [data['dewpoint_c'], data['dewpoint_f']]
|
123
|
-
|
125
|
+
|
124
126
|
current.heat_index = Data::Temperature.new(metric)
|
125
127
|
current.heat_index << [data['heat_index_c'], data['heat_index_f']]
|
126
|
-
|
128
|
+
|
127
129
|
current.wind_chill = Data::Temperature.new(metric)
|
128
130
|
current.wind_chill << [data['windchill_c'], data['windchill_f']]
|
129
|
-
|
131
|
+
|
130
132
|
current.visibility = Data::Distance.new(metric)
|
131
133
|
current.visibility << [data['visibility_km'], data['visibility_mi']]
|
132
|
-
|
134
|
+
|
133
135
|
current
|
134
136
|
end
|
135
|
-
|
137
|
+
|
136
138
|
def self._build_forecast(data, metric=true)
|
137
139
|
raise ArgumentError unless data.is_a?(Hash)
|
138
140
|
forecasts = Measurement::ResultArray.new
|
139
141
|
# go through each forecast and create an instance
|
140
142
|
if data && data['simpleforecast'] &&
|
141
143
|
data['simpleforecast']['forecastday']
|
142
|
-
|
144
|
+
|
143
145
|
data['simpleforecast']['forecastday'].each do |forecast|
|
144
146
|
forecast_measurement = Measurement::Result.new
|
145
147
|
forecast_measurement.icon = forecast['icon']
|
146
148
|
forecast_measurement.date = Date.parse(forecast['date']['pretty'])
|
147
149
|
forecast_measurement.pop = forecast['pop'].to_i
|
148
|
-
|
150
|
+
|
149
151
|
forecast_measurement.high = Data::Temperature.new(metric)
|
150
152
|
forecast_measurement.high << [forecast['high']['celsius'],forecast['high']['fahrenheit']]
|
151
|
-
|
153
|
+
|
152
154
|
forecast_measurement.low = Data::Temperature.new(metric)
|
153
155
|
forecast_measurement.low << [forecast['low']['celsius'],forecast['low']['fahrenheit']]
|
154
|
-
|
156
|
+
|
155
157
|
forecasts << forecast_measurement
|
156
158
|
end
|
157
159
|
end
|
158
160
|
forecasts
|
159
161
|
end
|
160
|
-
|
162
|
+
|
161
163
|
def self._build_location(data, geo=nil)
|
162
164
|
raise ArgumentError unless data.is_a?(Hash)
|
163
165
|
location = Data::Location.new
|
@@ -173,7 +175,7 @@ module Barometer
|
|
173
175
|
end
|
174
176
|
location
|
175
177
|
end
|
176
|
-
|
178
|
+
|
177
179
|
def self._build_station(data)
|
178
180
|
raise ArgumentError unless data.is_a?(Hash)
|
179
181
|
station = Data::Location.new
|
@@ -190,7 +192,7 @@ module Barometer
|
|
190
192
|
end
|
191
193
|
station
|
192
194
|
end
|
193
|
-
|
195
|
+
|
194
196
|
def self._build_sun(data)
|
195
197
|
raise ArgumentError unless data.is_a?(Hash)
|
196
198
|
sun = nil
|
@@ -209,7 +211,7 @@ module Barometer
|
|
209
211
|
end
|
210
212
|
sun || Data::Sun.new
|
211
213
|
end
|
212
|
-
|
214
|
+
|
213
215
|
# override default _fetch behavior
|
214
216
|
# this service requires TWO seperate http requests (one for current
|
215
217
|
# and one for forecasted weather) ... combine the results
|
@@ -220,7 +222,7 @@ module Barometer
|
|
220
222
|
result << _fetch_forecast(query)
|
221
223
|
result
|
222
224
|
end
|
223
|
-
|
225
|
+
|
224
226
|
# use HTTParty to get the current weather
|
225
227
|
#
|
226
228
|
def self._fetch_current(query)
|
@@ -233,7 +235,7 @@ module Barometer
|
|
233
235
|
:timeout => Barometer.timeout
|
234
236
|
)['current_observation']
|
235
237
|
end
|
236
|
-
|
238
|
+
|
237
239
|
# use HTTParty to get the forecasted weather
|
238
240
|
#
|
239
241
|
def self._fetch_forecast(query)
|
@@ -246,7 +248,7 @@ module Barometer
|
|
246
248
|
:timeout => Barometer.timeout
|
247
249
|
)['forecast']
|
248
250
|
end
|
249
|
-
|
251
|
+
|
250
252
|
# since we have two sets of data, override these calls to choose the
|
251
253
|
# right set of data
|
252
254
|
#
|
@@ -257,6 +259,6 @@ module Barometer
|
|
257
259
|
def self._links_result(data=nil); data[0]; end
|
258
260
|
def self._sun_result(data=nil); data[1]; end
|
259
261
|
def self._timezone_result(data=nil); data[1]; end
|
260
|
-
|
262
|
+
|
261
263
|
end
|
262
|
-
end
|
264
|
+
end
|
@@ -46,16 +46,16 @@ module Barometer
|
|
46
46
|
# - the Yahoo! WOEID is only used by Yahoo!, and is a 32-bit number. Unfortunately
|
47
47
|
# this number confilcts with US Zipcodes (ie the zipcode=90210 and the
|
48
48
|
# WOEID=90210 cannot be destinguished and do not mean the same thing). To
|
49
|
-
# solve this, any 5 digit number will be dtected as a ZIPCODE. To have a
|
49
|
+
# solve this, any 5 digit number will be dtected as a ZIPCODE. To have a
|
50
50
|
# 5 digit query be detected as a WOEID, prepend it with a 'w' (ie: w90210).
|
51
51
|
#
|
52
52
|
class WeatherService::Yahoo < WeatherService
|
53
|
-
|
53
|
+
|
54
54
|
#########################################################################
|
55
55
|
# PRIVATE
|
56
56
|
# If class methods could be private, the remaining methods would be.
|
57
57
|
#
|
58
|
-
|
58
|
+
|
59
59
|
def self._source_name; :yahoo; end
|
60
60
|
def self._accepted_formats; [:zipcode, :weather_id, :woe_id]; end
|
61
61
|
|
@@ -67,11 +67,11 @@ module Barometer
|
|
67
67
|
codes = (29..34).to_a + [36]
|
68
68
|
codes.collect {|c| c.to_s}
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def self._build_extra(measurement, result, metric=true)
|
72
72
|
#raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
73
73
|
#raise ArgumentError unless query.is_a?(Barometer::Query)
|
74
|
-
|
74
|
+
|
75
75
|
# use todays sun data for all future days
|
76
76
|
if measurement.forecast && measurement.current.sun
|
77
77
|
measurement.forecast.each do |forecast|
|
@@ -80,14 +80,14 @@ module Barometer
|
|
80
80
|
end
|
81
81
|
measurement
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def self._build_timezone(data)
|
85
85
|
if data && data['item'] && data['item']['pubDate']
|
86
86
|
zone_match = data['item']['pubDate'].match(/ ([A-Z]*)$/)
|
87
87
|
Data::Zone.new(zone_match[1]) if zone_match
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def self._build_links(data)
|
92
92
|
links = {}
|
93
93
|
if data["title"] && data["link"]
|
@@ -95,29 +95,29 @@ module Barometer
|
|
95
95
|
end
|
96
96
|
links
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
def self._build_current(data, metric=true)
|
100
100
|
raise ArgumentError unless data.is_a?(Hash)
|
101
101
|
current = Measurement::Result.new(metric)
|
102
102
|
if data
|
103
|
-
if data['item'] && data['item']['
|
104
|
-
condition_result = data['item']['
|
103
|
+
if data['item'] && data['item']['condition']
|
104
|
+
condition_result = data['item']['condition']
|
105
105
|
current.updated_at = Data::LocalDateTime.parse(condition_result['date'])
|
106
106
|
current.icon = condition_result['code']
|
107
107
|
current.condition = condition_result['text']
|
108
108
|
current.temperature = Data::Temperature.new(metric)
|
109
109
|
current.temperature << condition_result['temp']
|
110
110
|
end
|
111
|
-
if data['
|
112
|
-
atmosphere_result = data['
|
111
|
+
if data['atmosphere']
|
112
|
+
atmosphere_result = data['atmosphere']
|
113
113
|
current.humidity = atmosphere_result['humidity'].to_i
|
114
114
|
current.pressure = Data::Pressure.new(metric)
|
115
115
|
current.pressure << atmosphere_result['pressure']
|
116
116
|
current.visibility = Data::Distance.new(metric)
|
117
117
|
current.visibility << atmosphere_result['visibility']
|
118
118
|
end
|
119
|
-
if data['
|
120
|
-
wind_result = data['
|
119
|
+
if data['wind']
|
120
|
+
wind_result = data['wind']
|
121
121
|
current.wind = Data::Speed.new(metric)
|
122
122
|
current.wind << wind_result['speed']
|
123
123
|
current.wind.degrees = wind_result['degrees'].to_f
|
@@ -127,14 +127,14 @@ module Barometer
|
|
127
127
|
end
|
128
128
|
current
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
def self._build_forecast(data, metric=true)
|
132
132
|
raise ArgumentError unless data.is_a?(Hash)
|
133
133
|
forecasts = Measurement::ResultArray.new
|
134
|
-
|
135
|
-
if data && data['item'] && data['item']['
|
136
|
-
forecast_result = data['item']['
|
137
|
-
|
134
|
+
|
135
|
+
if data && data['item'] && data['item']['forecast']
|
136
|
+
forecast_result = data['item']['forecast']
|
137
|
+
|
138
138
|
forecast_result.each do |forecast|
|
139
139
|
forecast_measurement = Measurement::Result.new
|
140
140
|
forecast_measurement.icon = forecast['code']
|
@@ -149,7 +149,7 @@ module Barometer
|
|
149
149
|
end
|
150
150
|
forecasts
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
def self._build_location(data, geo=nil)
|
154
154
|
raise ArgumentError unless data.is_a?(Hash)
|
155
155
|
raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
|
@@ -163,30 +163,30 @@ module Barometer
|
|
163
163
|
location.latitude = geo.latitude
|
164
164
|
location.longitude = geo.longitude
|
165
165
|
else
|
166
|
-
if data && data['
|
167
|
-
location.city = data['
|
168
|
-
location.state_code = data['
|
169
|
-
location.country_code = data['
|
166
|
+
if data && data['location']
|
167
|
+
location.city = data['location']['city']
|
168
|
+
location.state_code = data['location']['region']
|
169
|
+
location.country_code = data['location']['country']
|
170
170
|
if data['item']
|
171
|
-
location.latitude = data['item']['
|
172
|
-
location.longitude = data['item']['
|
171
|
+
location.latitude = data['item']['lat']
|
172
|
+
location.longitude = data['item']['long']
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
176
176
|
location
|
177
177
|
end
|
178
|
-
|
178
|
+
|
179
179
|
def self._build_sun(data)
|
180
180
|
raise ArgumentError unless data.is_a?(Hash)
|
181
181
|
sun = nil
|
182
|
-
if data && data['
|
183
|
-
local_rise = Data::LocalTime.parse(data['
|
184
|
-
local_set = Data::LocalTime.parse(data['
|
182
|
+
if data && data['astronomy'] && data['item']
|
183
|
+
local_rise = Data::LocalTime.parse(data['astronomy']['sunrise'])
|
184
|
+
local_set = Data::LocalTime.parse(data['astronomy']['sunset'])
|
185
185
|
sun = Data::Sun.new(local_rise, local_set)
|
186
186
|
end
|
187
187
|
sun || Data::Sun.new
|
188
188
|
end
|
189
|
-
|
189
|
+
|
190
190
|
# use HTTParty to get the current weather
|
191
191
|
def self._fetch(query, metric=true)
|
192
192
|
return unless query
|
@@ -196,13 +196,14 @@ module Barometer
|
|
196
196
|
:w => query.format == :woe_id ? query.q : nil,
|
197
197
|
:u => (metric ? 'c' : 'f')
|
198
198
|
}.delete_if {|k,v| v.nil? }
|
199
|
-
self.get(
|
199
|
+
r = self.get(
|
200
200
|
"http://weather.yahooapis.com/forecastrss",
|
201
201
|
:query => options,
|
202
202
|
:format => :xml,
|
203
203
|
:timeout => Barometer.timeout
|
204
|
-
)
|
204
|
+
)
|
205
|
+
r['rss']['channel']
|
205
206
|
end
|
206
|
-
|
207
|
+
|
207
208
|
end
|
208
|
-
end
|
209
|
+
end
|