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