lib/barometer/weather_services/weather_bug.rb in barometer-0.7.3 vs lib/barometer/weather_services/weather_bug.rb in barometer-0.8.0
- old
+ new
@@ -1,5 +1,7 @@
+require 'crack'
+
module Barometer
#
# = WeatherBug
# www.weatherbug.com
#
@@ -32,11 +34,11 @@
# == notes
# - WeatherBug also supports queries using "citycode" and "stationID", but these
# are specific to WeatherBug and un-supported by Barometer
#
class WeatherService::WeatherBug < WeatherService
-
+
@@api_code = nil
def self.keys=(keys)
raise ArgumentError unless keys.is_a?(Hash)
keys.each do |key, value|
@@ -63,22 +65,22 @@
end
def self._sunny_icon_codes
codes = [0,2,3,4,7,26,31,64,65,75]
codes.collect {|c| c.to_s}
end
-
+
def self._build_extra(measurement, result, metric=true)
#raise ArgumentError unless measurement.is_a?(Data::Measurement)
#raise ArgumentError unless query.is_a?(Barometer::Query)
# use todays sun data for all future days
if measurement.forecast && measurement.current.sun
measurement.forecast.each do |forecast|
forecast.sun = measurement.current.sun
end
end
-
+
measurement
end
def self._parse_local_time(data)
Data::LocalTime.new(
@@ -119,38 +121,38 @@
current.wind_chill = Data::Temperature.new(metric)
current.wind_chill << data['aws:feels_like']
current
end
-
+
def self._build_forecast(data, metric=true)
raise ArgumentError unless data.is_a?(Hash)
forecasts = Measurement::ResultArray.new
# go through each forecast and create an instance
- if data && data["aws:forecast"]
+ if data && data["forecast"]
start_date = Date.strptime(data['date'], "%m/%d/%Y %H:%M:%S %p")
i = 0
- data["aws:forecast"].each do |forecast|
+ data["forecast"].each do |forecast|
forecast_measurement = Measurement::Result.new
- icon_match = forecast['aws:image'].match(/cond(\d*)\.gif$/)
+ icon_match = forecast['image']['icon'].match(/cond(\d*)\.gif$/)
forecast_measurement.icon = icon_match[1].to_i.to_s if icon_match
forecast_measurement.date = start_date + i
- forecast_measurement.condition = forecast['aws:short_prediction']
+ forecast_measurement.condition = forecast['short_prediction']
forecast_measurement.high = Data::Temperature.new(metric)
- forecast_measurement.high << forecast['aws:high']
+ forecast_measurement.high << forecast['high']['__content__']
forecast_measurement.low = Data::Temperature.new(metric)
- forecast_measurement.low << forecast['aws:low']
+ forecast_measurement.low << forecast['low']['__content__']
forecasts << forecast_measurement
i += 1
end
end
forecasts
end
-
+
def self._build_location(data, geo=nil)
raise ArgumentError unless data.is_a?(Hash)
raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
location = Data::Location.new
# use the geocoded data if available, otherwise get data from result
@@ -160,19 +162,19 @@
location.country = geo.country
location.country_code = geo.country_code
location.latitude = geo.latitude
location.longitude = geo.longitude
else
- if data && data['aws:location']
- location.city = data['aws:location']['aws:city']
- location.state_code = data['aws:location']['aws:state']
- location.zip_code = data['aws:location']['aws:zip']
+ if data && data['location']
+ location.city = data['location']['city']
+ location.state_code = data['location']['state']
+ location.zip_code = data['location']['zip']
end
end
location
end
-
+
def self._build_station(data)
raise ArgumentError unless data.is_a?(Hash)
station = Data::Location.new
station.id = data['aws:station_id']
station.name = data['aws:station']
@@ -182,11 +184,11 @@
station.zip_code = data['aws:station_zipcode']
station.latitude = data['aws:latitude']
station.longitude = data['aws:longitude']
station
end
-
+
def self._build_sun(data)
raise ArgumentError unless data.is_a?(Hash)
sun = nil
if data
if data['aws:sunrise']
@@ -216,20 +218,20 @@
result = []
result << _fetch_current(query,metric)
result << _fetch_forecast(query,metric)
result
end
-
+
# use HTTParty to get the current weather
#
def self._fetch_current(query, metric=true)
puts "fetch weatherbug current: #{query.q}" if Barometer::debug?
-
+
q = ( query.format.to_sym == :short_zipcode ?
{ :zipCode => query.q } :
{ :lat => query.q.split(',')[0], :long => query.q.split(',')[1] })
-
+
# httparty and the xml builder it uses miss some information
# 1st - get the raw response
# 2nd - manually get the missing information
# 3rd - let httparty build xml as normal
#
@@ -238,50 +240,50 @@
:query => { :ACode => @@api_code,
:OutputType => "1", :UnitType => (metric ? '1' : '0')
}.merge(q),
:format => :plain,
:timeout => Barometer.timeout
- )
-
+ )
+
# get icon
icon_match = response.match(/cond(\d*)\.gif/)
icon = icon_match[1] if icon_match
-
+
# get station zipcode
zip_match = response.match(/zipcode=\"(\d*)\"/)
zipcode = zip_match[1] if zip_match
-
+
# build xml
- output = Crack::XML.parse(response)
+ output = ::Crack::XML.parse(response)
output = output["aws:weather"]["aws:ob"]
-
+
# add missing data
output["aws:icon"] = icon
output["aws:station_zipcode"] = zipcode
-
+
output
end
-
+
# use HTTParty to get the current weather
#
def self._fetch_forecast(query, metric=true)
puts "fetch weatherbug forecast: #{query.q}" if Barometer::debug?
-
+
q = ( query.format.to_sym == :short_zipcode ?
{ :zipCode => query.q } :
{ :lat => query.q.split(',')[0], :long => query.q.split(',')[1] })
-
+
self.get(
"http://#{@@api_code}.api.wxbug.net/getForecastRSS.aspx",
:query => { :ACode => @@api_code,
:OutputType => "1", :UnitType => (metric ? '1' : '0')
}.merge(q),
:format => :xml,
:timeout => Barometer.timeout
- )["aws:weather"]["aws:forecasts"]
+ )["weather"]["forecasts"]
end
-
+
# since we have two sets of data, override these calls to choose the
# right set of data
#
def self._current_result(data); data[0]; end
def self._forecast_result(data=nil); data[1]; end
@@ -290,6 +292,6 @@
def self._sun_result(data=nil); data[0]; end
def self._timezone_result(data=nil); data[0]; end
def self._time_result(data=nil); data[0]; end
end
-end
\ No newline at end of file
+end