lib/barometer/weather_services/wunderground.rb in barometer-0.5.0 vs lib/barometer/weather_services/wunderground.rb in barometer-0.6.1

- old
+ new

@@ -44,76 +44,67 @@ # = Wunderground terms of use # Unable to locate. # class WeatherService::Wunderground < WeatherService - def self.source_name; :wunderground; end - def self.accepted_formats + ######################################################################### + # PRIVATE + # If class methods could be private, the remaining methods would be. + # + + def self._source_name; :wunderground; end + def self._accepted_formats [:zipcode, :postalcode, :icao, :coordinates, :geocode] end # these are the icon codes that indicate "wet", used by wet? function - def self.wet_icon_codes + def self._wet_icon_codes %w(flurries rain sleet snow tstorms nt_flurries nt_rain nt_sleet nt_snow nt_tstorms chancerain chancetstorms) end # these are the icon codes that indicate "sun", used by sunny? function - def self.sunny_icon_codes + def self._sunny_icon_codes %w(clear mostlysunny partlysunny sunny partlycloudy) end - def self._measure(measurement, query, metric=true) - raise ArgumentError unless measurement.is_a?(Data::Measurement) - raise ArgumentError unless query.is_a?(Barometer::Query) - measurement.source = self.source_name - - begin - current_result = self.get_current(query.q) - measurement.current = self.build_current(current_result, metric) - rescue Timeout::Error => e - return measurement - end - - begin - forecast_result = self.get_forecast(query.q) - measurement.forecast = self.build_forecast(forecast_result, metric) - rescue Timeout::Error => e - return measurement - end - - measurement.location = self.build_location(current_result) - measurement.station = self.build_station(current_result) - measurement.timezone = self.build_timezone(forecast_result) - - if current_result["credit"] && current_result["credit_URL"] - measurement.links[current_result["credit"]] = current_result["credit_URL"] - end - - sun = nil - if measurement.current - sun = self.build_sun(forecast_result, measurement.timezone) - measurement.current.sun = sun - 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 && sun + if measurement.forecast && measurement.current.sun measurement.forecast.each do |forecast| - forecast.sun = sun + forecast.sun = measurement.current.sun end end - local_time = measurement.timezone ? Data::LocalTime.parse( - measurement.timezone.utc_to_local(Time.now.utc) - ) : nil - measurement.measured_at = local_time - measurement.current.current_at = local_time - measurement end + + def self._parse_full_timezone(data) + raise ArgumentError unless data.is_a?(Hash) + if data && data['simpleforecast'] && + data['simpleforecast']['forecastday'] && + data['simpleforecast']['forecastday'].first && + data['simpleforecast']['forecastday'].first['date'] + Data::Zone.new( + data['simpleforecast']['forecastday'].first['date']['tz_long'] + ) + end + end - def self.build_current(data, metric=true) + def self._build_links(data) + links = {} + if data["credit"] && data["credit_URL"] + links[data["credit"]] = data["credit_URL"] + end + links + end + + def self._build_current(data, metric=true) raise ArgumentError unless data.is_a?(Hash) - current = Data::CurrentMeasurement.new + current = Measurement::Current.new current.updated_at = Data::LocalDateTime.parse(data['observation_time']) if data['observation_time'] current.humidity = data['relative_humidity'].to_i current.icon = data['icon'] if data['icon'] current.temperature = Data::Temperature.new(metric) @@ -140,19 +131,19 @@ current.visibility << [data['visibility_km'], data['visibility_mi']] current end - def self.build_forecast(data, metric=true) + def self._build_forecast(data, metric=true) raise ArgumentError unless data.is_a?(Hash) - forecasts = [] + forecasts = Measurement::ForecastArray.new # go through each forecast and create an instance if data && data['simpleforecast'] && data['simpleforecast']['forecastday'] data['simpleforecast']['forecastday'].each do |forecast| - forecast_measurement = Data::ForecastMeasurement.new + forecast_measurement = Measurement::Forecast.new forecast_measurement.icon = forecast['icon'] forecast_measurement.date = Date.parse(forecast['date']['pretty']) forecast_measurement.pop = forecast['pop'].to_i forecast_measurement.high = Data::Temperature.new(metric) @@ -164,12 +155,12 @@ forecasts << forecast_measurement end end forecasts end - - def self.build_location(data) + + def self._build_location(data, geo=nil) raise ArgumentError unless data.is_a?(Hash) location = Data::Location.new if data['display_location'] location.name = data['display_location']['full'] location.city = data['display_location']['city'] @@ -181,11 +172,11 @@ location.longitude = data['display_location']['longitude'] end location end - def self.build_station(data) + def self._build_station(data) raise ArgumentError unless data.is_a?(Hash) station = Data::Location.new station.id = data['station_id'] if data['observation_location'] station.name = data['observation_location']['full'] @@ -198,71 +189,74 @@ station.longitude = data['observation_location']['longitude'] end station end - def self.build_timezone(data) + def self._build_sun(data) raise ArgumentError unless data.is_a?(Hash) - timezone = nil - if data && data['simpleforecast'] && - data['simpleforecast']['forecastday'] && - data['simpleforecast']['forecastday'].first && - data['simpleforecast']['forecastday'].first['date'] - timezone = Data::Zone.new( - data['simpleforecast']['forecastday'].first['date']['tz_long'] - ) - end - timezone || Data::Zone.new(nil) - end - - def self.build_sun(data, timezone) - raise ArgumentError unless data.is_a?(Hash) - raise ArgumentError unless timezone.is_a?(Data::Zone) sun = nil if data if data['moon_phase'] - if data['moon_phase']['sunrise'] - rise = Data::LocalTime.new( - data['moon_phase']['sunrise']['hour'].to_i, - data['moon_phase']['sunrise']['minute'].to_i - ) - end - if data['moon_phase']['sunset'] - set = Data::LocalTime.new( - data['moon_phase']['sunset']['hour'].to_i, - data['moon_phase']['sunset']['minute'].to_i - ) - end - - sun = Data::Sun.new( - rise, - set - ) + rise = Data::LocalTime.new( + data['moon_phase']['sunrise']['hour'].to_i, + data['moon_phase']['sunrise']['minute'].to_i + ) if data['moon_phase']['sunrise'] + set = Data::LocalTime.new( + data['moon_phase']['sunset']['hour'].to_i, + data['moon_phase']['sunset']['minute'].to_i + ) if data['moon_phase']['sunset'] + sun = Data::Sun.new(rise,set) end end sun || Data::Sun.new end + # override default _fetch behavior + # this service requires TWO seperate http requests (one for current + # and one for forecasted weather) ... combine the results + # + def self._fetch(query, metric=true) + result = [] + result << _fetch_current(query) + result << _fetch_forecast(query) + result + end + # use HTTParty to get the current weather - def self.get_current(query) + # + def self._fetch_current(query) return unless query + puts "fetch wunderground current: #{query.q}" if Barometer::debug? self.get( "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml", - :query => {:query => query}, + :query => {:query => query.q}, :format => :xml, :timeout => Barometer.timeout )['current_observation'] end # use HTTParty to get the forecasted weather - def self.get_forecast(query) + # + def self._fetch_forecast(query) return unless query + puts "fetch wunderground forecast: #{query.q}" if Barometer::debug? self.get( "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml", - :query => {:query => query}, + :query => {:query => query.q}, :format => :xml, :timeout => Barometer.timeout )['forecast'] 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 + def self._location_result(data=nil); data[0]; end + def self._station_result(data=nil); data[0]; end + def self._links_result(data=nil); data[0]; end + def self._sun_result(data=nil); data[1]; end + def self._timezone_result(data=nil); data[1]; end end end \ No newline at end of file