Class: Barometer::WeatherService

Inherits:
Object
  • Object
show all
Includes:
HTTParty
Defined in:
lib/barometer/weather_services/service.rb

Overview

Service Class

This is a base class for creating alternate weather api-consuming drivers. Each driver inherits from this class. This class creates some default behaviours, but they can easily be over-ridden.

Basically, all a service is required to do is take a query (ie “Paris”) and return a complete Barometer::Measurement instance.

Defined Under Namespace

Classes: Google, Noaa, WeatherBug, WeatherDotCom, Wunderground, Yahoo

Class Method Summary collapse

Class Method Details

._accepted_formatsObject

Raises:

  • (NotImplementedError)


60
# File 'lib/barometer/weather_services/service.rb', line 60

def self._accepted_formats; raise NotImplementedError; end

._build_current(result = nil, metric = true) ⇒ Object



62
# File 'lib/barometer/weather_services/service.rb', line 62

def self._build_current(result=nil, metric=true); nil; end

._build_extra(measurement = nil, result = nil, metric = true) ⇒ Object



77
# File 'lib/barometer/weather_services/service.rb', line 77

def self._build_extra(measurement=nil, result=nil, metric=true); measurement; end

._build_forecast(result = nil, metric = true) ⇒ Object



63
# File 'lib/barometer/weather_services/service.rb', line 63

def self._build_forecast(result=nil, metric=true); nil; end


74
# File 'lib/barometer/weather_services/service.rb', line 74

def self._build_links(result=nil); {}; end

._build_local_time(measurement) ⇒ Object



78
79
80
# File 'lib/barometer/weather_services/service.rb', line 78

def self._build_local_time(measurement)
  (measurement && measurement.timezone) ? Data::LocalTime.parse(measurement.timezone.now) : nil
end

._build_location(result = nil, geo = nil) ⇒ Object

data processing stubs



72
# File 'lib/barometer/weather_services/service.rb', line 72

def self._build_location(result=nil, geo=nil); nil; end

._build_station(result = nil) ⇒ Object



73
# File 'lib/barometer/weather_services/service.rb', line 73

def self._build_station(result=nil); Data::Location.new; end

._build_sun(result = nil) ⇒ Object



75
# File 'lib/barometer/weather_services/service.rb', line 75

def self._build_sun(result=nil); Data::Sun.new; end

._build_timezone(result = nil) ⇒ Object



76
# File 'lib/barometer/weather_services/service.rb', line 76

def self._build_timezone(result=nil); nil; end

._current_result(data = nil) ⇒ Object

data accessors (see the wunderground driver for an example of overriding these)



114
# File 'lib/barometer/weather_services/service.rb', line 114

def self._current_result(data=nil); data; end

._fetch(query = nil, metric = true) ⇒ Object



61
# File 'lib/barometer/weather_services/service.rb', line 61

def self._fetch(query=nil, metric=true); nil; end

._forecast_result(data = nil) ⇒ Object



115
# File 'lib/barometer/weather_services/service.rb', line 115

def self._forecast_result(data=nil); data; end

._has_keys?Boolean

STUB: define this method to check for the existance of API keys,

this method is NOT needed if requires_keys? returns false

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


99
# File 'lib/barometer/weather_services/service.rb', line 99

def self._has_keys?; raise NotImplementedError; end

._keys=(keys = nil) ⇒ Object

STUB: define this method to check for the existance of API keys,

this method is NOT needed if requires_keys? returns false


103
# File 'lib/barometer/weather_services/service.rb', line 103

def self._keys=(keys=nil); nil; end


118
# File 'lib/barometer/weather_services/service.rb', line 118

def self._links_result(data=nil); data; end

._local_time(result, measurement = nil) ⇒ Object

return the current local time (as Data::LocalTime)



178
179
180
# File 'lib/barometer/weather_services/service.rb', line 178

def self._local_time(result, measurement=nil)
  _parse_local_time(result) || _build_local_time(measurement)
end

._location_result(data = nil) ⇒ Object



116
# File 'lib/barometer/weather_services/service.rb', line 116

def self._location_result(data=nil); data; end

._measure(measurement, query, metric = true) ⇒ Object

this is the generic measuring and data processing for each weather service driver. this method should be re-defined if the driver in question doesn’t fit into “generic” (ie wunderground)

Raises:

  • (ArgumentError)


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/barometer/weather_services/service.rb', line 133

def self._measure(measurement, query, metric=true)
  raise ArgumentError unless measurement.is_a?(Barometer::Measurement)
  raise ArgumentError unless query.is_a?(Barometer::Query)
  
  begin
    result = _fetch(query, metric)
  rescue Timeout::Error => e
    return measurement
  end
  
  if result
    measurement.current = _build_current(_current_result(result), metric)
    measurement.forecast = _build_forecast(_forecast_result(result), metric)
    measurement.location = _build_location(_location_result(result), query.geo)
    measurement.station = _build_station(_station_result(result))
    measurement.links = _build_links(_links_result(result))
    measurement.current.sun = _build_sun(_sun_result(result)) if measurement.current
    measurement.timezone = _timezone(_timezone_result(result), query, measurement.location)
    if local_time = _local_time(_time_result(result), measurement)
       measurement.measured_at = local_time
       measurement.current.current_at = local_time
    end
    measurement = _build_extra(measurement, result, metric)
  end
  
  measurement
end

._meets_requirements?(query = nil) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/barometer/weather_services/service.rb', line 182

def self._meets_requirements?(query=nil)
  self._supports_country?(query) && (!self._requires_keys? || self._has_keys?)
end

._parse_full_timezone(result = nil) ⇒ Object

given the result set, return the full_timezone or local time … if not available return nil



84
# File 'lib/barometer/weather_services/service.rb', line 84

def self._parse_full_timezone(result=nil); nil; end

._parse_local_time(result = nil) ⇒ Object



85
# File 'lib/barometer/weather_services/service.rb', line 85

def self._parse_local_time(result=nil); nil; end

._requires_keys?Boolean

DEFAULT: override this if you need to determine if API keys are required

Returns:

  • (Boolean)


109
# File 'lib/barometer/weather_services/service.rb', line 109

def self._requires_keys?; false; end

._source_nameObject

REQUIRED re-defining these methods will be required

Raises:

  • (NotImplementedError)


59
# File 'lib/barometer/weather_services/service.rb', line 59

def self._source_name; raise NotImplementedError; end

._station_result(data = nil) ⇒ Object



117
# File 'lib/barometer/weather_services/service.rb', line 117

def self._station_result(data=nil); data; end

._sun_result(data = nil) ⇒ Object



119
# File 'lib/barometer/weather_services/service.rb', line 119

def self._sun_result(data=nil); data; end

._sunny_icon_codesObject

this returns an array of codes that indicate “sunny”



90
# File 'lib/barometer/weather_services/service.rb', line 90

def self._sunny_icon_codes; nil; end

._supports_country?(query = nil) ⇒ Boolean

DEFAULT: override this if you need to determine if the country is specified

Returns:

  • (Boolean)


106
# File 'lib/barometer/weather_services/service.rb', line 106

def self._supports_country?(query=nil); true; end

._time_result(data = nil) ⇒ Object



121
# File 'lib/barometer/weather_services/service.rb', line 121

def self._time_result(data=nil); data; end

._timezone(result = nil, query = nil, location = nil) ⇒ Object

either get the timezone based on coords, or build it from the data



163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/barometer/weather_services/service.rb', line 163

def self._timezone(result=nil, query=nil, location=nil)
  if full_timezone = _parse_full_timezone(result)
    full_timezone
  elsif query && query.timezone
    query.timezone
  elsif Barometer.enhance_timezone && location &&
        location.latitude && location.longitude
    WebService::Timezone.fetch(location.latitude, location.longitude)
  else
    _build_timezone(result)
  end
end

._timezone_result(data = nil) ⇒ Object



120
# File 'lib/barometer/weather_services/service.rb', line 120

def self._timezone_result(data=nil); data; end

._wet_icon_codesObject

this returns an array of codes that indicate “wet”



88
# File 'lib/barometer/weather_services/service.rb', line 88

def self._wet_icon_codes; nil; end

.measure(query, metric = true) ⇒ Object

get current weather and future (forecasted) weather

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/barometer/weather_services/service.rb', line 31

def self.measure(query, metric=true)
  raise ArgumentError unless query.is_a?(Barometer::Query)
  
  measurement = Barometer::Measurement.new(self._source_name, metric)
  measurement.start_at = Time.now.utc
  if self._meets_requirements?(query)
    converted_query = query.convert!(self._accepted_formats)
    if converted_query
      measurement.source = self._source_name
      measurement.query = converted_query.q
      measurement.format = converted_query.format
      measurement = self._measure(measurement, converted_query, metric)
    end
  end
  measurement.end_at = Time.now.utc
  measurement
end

.source(source_name) ⇒ Object

retrieves the weather source Service object

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
# File 'lib/barometer/weather_services/service.rb', line 20

def self.source(source_name)
  raise ArgumentError unless (source_name.is_a?(String) || source_name.is_a?(Symbol))
  source_name = source_name.to_s.split("_").collect{ |s| s.capitalize }.join('')
  raise ArgumentError unless Barometer::WeatherService.const_defined?(source_name)
  raise ArgumentError unless Barometer::WeatherService.const_get(source_name).superclass == Barometer::WeatherService
  Barometer::WeatherService.const_get(source_name)
end