barometer 0.3.2 → 0.5.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/README.rdoc +78 -70
- data/VERSION.yml +2 -2
- data/bin/barometer +100 -37
- data/lib/barometer.rb +12 -8
- data/lib/barometer/base.rb +48 -20
- data/lib/barometer/data.rb +5 -1
- data/lib/barometer/data/current.rb +23 -15
- data/lib/barometer/data/distance.rb +15 -5
- data/lib/barometer/data/forecast.rb +23 -5
- data/lib/barometer/data/geo.rb +16 -54
- data/lib/barometer/data/local_datetime.rb +137 -0
- data/lib/barometer/data/local_time.rb +134 -0
- data/lib/barometer/data/location.rb +6 -1
- data/lib/barometer/data/measurement.rb +71 -42
- data/lib/barometer/data/night.rb +69 -0
- data/lib/barometer/data/pressure.rb +15 -5
- data/lib/barometer/data/speed.rb +16 -5
- data/lib/barometer/data/sun.rb +8 -20
- data/lib/barometer/data/temperature.rb +22 -9
- data/lib/barometer/data/units.rb +10 -19
- data/lib/barometer/data/zone.rb +135 -9
- data/lib/barometer/formats.rb +12 -0
- data/lib/barometer/formats/coordinates.rb +42 -0
- data/lib/barometer/formats/format.rb +46 -0
- data/lib/barometer/formats/geocode.rb +51 -0
- data/lib/barometer/formats/icao.rb +37 -0
- data/lib/barometer/formats/postalcode.rb +22 -0
- data/lib/barometer/formats/short_zipcode.rb +17 -0
- data/lib/barometer/formats/weather_id.rb +107 -0
- data/lib/barometer/formats/zipcode.rb +31 -0
- data/lib/barometer/query.rb +61 -232
- data/lib/barometer/services.rb +14 -4
- data/lib/barometer/translations/icao_country_codes.yml +9 -0
- data/lib/barometer/translations/weather_country_codes.yml +17 -0
- data/lib/barometer/weather.rb +51 -30
- data/lib/barometer/{services → weather_services}/google.rb +23 -26
- data/lib/barometer/weather_services/noaa.rb +6 -0
- data/lib/barometer/{services → weather_services}/service.rb +101 -92
- data/lib/barometer/weather_services/weather_bug.rb +6 -0
- data/lib/barometer/weather_services/weather_dot_com.rb +261 -0
- data/lib/barometer/{services → weather_services}/wunderground.rb +58 -76
- data/lib/barometer/{services → weather_services}/yahoo.rb +91 -121
- data/lib/barometer/web_services/geocode.rb +33 -0
- data/lib/barometer/web_services/weather_id.rb +37 -0
- data/lib/barometer/web_services/web_service.rb +32 -0
- data/lib/demometer/demometer.rb +31 -4
- data/lib/demometer/views/forecast.erb +20 -0
- data/lib/demometer/views/index.erb +10 -3
- data/lib/demometer/views/measurement.erb +8 -3
- data/lib/demometer/views/readme.erb +63 -24
- data/spec/barometer_spec.rb +18 -36
- data/spec/{data_current_spec.rb → data/current_spec.rb} +73 -49
- data/spec/{data_distance_spec.rb → data/distance_spec.rb} +30 -30
- data/spec/{data_forecast_spec.rb → data/forecast_spec.rb} +57 -15
- data/spec/data/geo_spec.rb +91 -0
- data/spec/data/local_datetime_spec.rb +269 -0
- data/spec/data/local_time_spec.rb +239 -0
- data/spec/{data_location_spec.rb → data/location_spec.rb} +12 -1
- data/spec/{data_measurement_spec.rb → data/measurement_spec.rb} +135 -66
- data/spec/data/night_measurement_spec.rb +136 -0
- data/spec/{data_pressure_spec.rb → data/pressure_spec.rb} +29 -29
- data/spec/{data_speed_spec.rb → data/speed_spec.rb} +30 -30
- data/spec/data/sun_spec.rb +49 -0
- data/spec/{data_temperature_spec.rb → data/temperature_spec.rb} +44 -44
- data/spec/{units_spec.rb → data/units_spec.rb} +6 -6
- data/spec/{data_zone_spec.rb → data/zone_spec.rb} +15 -15
- data/spec/fixtures/formats/weather_id/90210.xml +1 -0
- data/spec/fixtures/formats/weather_id/atlanta.xml +1 -0
- data/spec/fixtures/formats/weather_id/from_USGA0028.xml +1 -0
- data/spec/fixtures/formats/weather_id/new_york.xml +1 -0
- data/spec/fixtures/{geocode_40_73.xml → geocode/40_73.xml} +0 -0
- data/spec/fixtures/{geocode_90210.xml → geocode/90210.xml} +0 -0
- data/spec/fixtures/{geocode_T5B4M9.xml → geocode/T5B4M9.xml} +0 -0
- data/spec/fixtures/geocode/atlanta.xml +1 -0
- data/spec/fixtures/{geocode_calgary_ab.xml → geocode/calgary_ab.xml} +0 -0
- data/spec/fixtures/{geocode_ksfo.xml → geocode/ksfo.xml} +0 -0
- data/spec/fixtures/{geocode_newyork_ny.xml → geocode/newyork_ny.xml} +0 -0
- data/spec/fixtures/{google_calgary_ab.xml → services/google/calgary_ab.xml} +0 -0
- data/spec/fixtures/services/weather_dot_com/90210.xml +1 -0
- data/spec/fixtures/{current_calgary_ab.xml → services/wunderground/current_calgary_ab.xml} +0 -0
- data/spec/fixtures/{forecast_calgary_ab.xml → services/wunderground/forecast_calgary_ab.xml} +0 -0
- data/spec/fixtures/{yahoo_90210.xml → services/yahoo/90210.xml} +0 -0
- data/spec/formats/coordinates_spec.rb +158 -0
- data/spec/formats/format_spec.rb +73 -0
- data/spec/formats/geocode_spec.rb +179 -0
- data/spec/formats/icao_spec.rb +61 -0
- data/spec/formats/postalcode_spec.rb +59 -0
- data/spec/formats/short_zipcode_spec.rb +53 -0
- data/spec/formats/weather_id_spec.rb +191 -0
- data/spec/formats/zipcode_spec.rb +111 -0
- data/spec/query_spec.rb +261 -288
- data/spec/spec_helper.rb +128 -4
- data/spec/{service_google_spec.rb → weather_services/google_spec.rb} +46 -46
- data/spec/weather_services/services_spec.rb +1118 -0
- data/spec/weather_services/weather_dot_com_spec.rb +327 -0
- data/spec/weather_services/wunderground_spec.rb +332 -0
- data/spec/{service_yahoo_spec.rb → weather_services/yahoo_spec.rb} +65 -81
- data/spec/weather_spec.rb +73 -61
- data/spec/web_services/geocode_spec.rb +45 -0
- data/spec/web_services/web_services_spec.rb +26 -0
- metadata +88 -36
- data/lib/barometer/services/noaa.rb +0 -6
- data/lib/barometer/services/weather_bug.rb +0 -6
- data/lib/barometer/services/weather_dot_com.rb +0 -6
- data/spec/data_geo_spec.rb +0 -94
- data/spec/data_sun_spec.rb +0 -76
- data/spec/service_wunderground_spec.rb +0 -330
- data/spec/services_spec.rb +0 -1106
@@ -21,7 +21,7 @@ module Barometer
|
|
21
21
|
# - API: http://unknown
|
22
22
|
#
|
23
23
|
# === Possible queries:
|
24
|
-
# -
|
24
|
+
# - http://google.com/ig/api?weather=perth
|
25
25
|
#
|
26
26
|
# where query can be:
|
27
27
|
# - zipcode (US or Canadian)
|
@@ -30,32 +30,28 @@ module Barometer
|
|
30
30
|
# - state
|
31
31
|
# - country
|
32
32
|
#
|
33
|
-
|
33
|
+
# = Google terms of use
|
34
|
+
# This is an unoffical API. There are no terms of use.
|
35
|
+
#
|
36
|
+
class WeatherService::Google < WeatherService
|
34
37
|
|
35
|
-
def self.
|
36
|
-
|
37
|
-
end
|
38
|
+
def self.source_name; :google; end
|
39
|
+
def self.accepted_formats; [:zipcode, :postalcode, :geocode]; end
|
38
40
|
|
39
|
-
def self.source_name
|
40
|
-
:google
|
41
|
-
end
|
42
|
-
|
43
|
-
# these are the icon codes that indicate "wet", used by wet? function
|
44
41
|
def self.wet_icon_codes
|
45
42
|
%w(rain chance_of_rain chance_of_storm thunderstorm mist)
|
46
43
|
end
|
47
|
-
# these are the icon codes that indicate "sun", used by sunny? function
|
48
44
|
def self.sunny_icon_codes
|
49
45
|
%w(sunny mostly_sunny partly_cloudy)
|
50
46
|
end
|
51
47
|
|
52
48
|
def self._measure(measurement, query, metric=true)
|
53
|
-
raise ArgumentError unless measurement.is_a?(
|
49
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
54
50
|
raise ArgumentError unless query.is_a?(Barometer::Query)
|
55
51
|
measurement.source = self.source_name
|
56
52
|
|
57
53
|
begin
|
58
|
-
result = self.get_all(query.
|
54
|
+
result = self.get_all(query.q, metric)
|
59
55
|
rescue Timeout::Error => e
|
60
56
|
return measurement
|
61
57
|
end
|
@@ -68,12 +64,13 @@ module Barometer
|
|
68
64
|
|
69
65
|
def self.build_current(data, metric=true)
|
70
66
|
raise ArgumentError unless data.is_a?(Hash)
|
71
|
-
current = CurrentMeasurement.new
|
67
|
+
current = Data::CurrentMeasurement.new
|
72
68
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
# google gives utc time, no way to convert to local
|
70
|
+
#if data && data['forecast_information'] &&
|
71
|
+
# data['forecast_information']['current_date_time']
|
72
|
+
# current.updated_at = Data::LocalDateTime.parse(data['forecast_information']['current_date_time']['data'])
|
73
|
+
#end
|
77
74
|
|
78
75
|
if data['current_conditions']
|
79
76
|
data = data['current_conditions']
|
@@ -86,10 +83,10 @@ module Barometer
|
|
86
83
|
humidity_match = data['humidity']['data'].match(/[\d]+/)
|
87
84
|
current.humidity = humidity_match[0].to_i if humidity_match
|
88
85
|
|
89
|
-
current.temperature = Temperature.new(metric)
|
86
|
+
current.temperature = Data::Temperature.new(metric)
|
90
87
|
current.temperature << [data['temp_c']['data'], data['temp_f']['data']]
|
91
88
|
|
92
|
-
current.wind = Speed.new(metric)
|
89
|
+
current.wind = Data::Speed.new(metric)
|
93
90
|
begin
|
94
91
|
current.wind << data['wind_condition']['data'].match(/[\d]+/)[0]
|
95
92
|
current.wind.direction = data['wind_condition']['data'].match(/Wind:.*?([\w]+).*?at/)[1]
|
@@ -111,7 +108,7 @@ module Barometer
|
|
111
108
|
# go through each forecast and create an instance
|
112
109
|
d = 0
|
113
110
|
data.each do |forecast|
|
114
|
-
forecast_measurement = ForecastMeasurement.new
|
111
|
+
forecast_measurement = Data::ForecastMeasurement.new
|
115
112
|
if forecast['icon']
|
116
113
|
icon_match = forecast['icon']['data'].match(/.*\/([A-Za-z_]*)\.png/)
|
117
114
|
forecast_measurement.icon = icon_match[1] if icon_match
|
@@ -122,9 +119,9 @@ module Barometer
|
|
122
119
|
forecast_measurement.date = start_date + d
|
123
120
|
end
|
124
121
|
|
125
|
-
forecast_measurement.high = Temperature.new(metric)
|
122
|
+
forecast_measurement.high = Data::Temperature.new(metric)
|
126
123
|
forecast_measurement.high << forecast['high']['data']
|
127
|
-
forecast_measurement.low = Temperature.new(metric)
|
124
|
+
forecast_measurement.low = Data::Temperature.new(metric)
|
128
125
|
forecast_measurement.low << forecast['low']['data']
|
129
126
|
|
130
127
|
forecasts << forecast_measurement
|
@@ -134,8 +131,8 @@ module Barometer
|
|
134
131
|
end
|
135
132
|
|
136
133
|
def self.build_location(geo=nil)
|
137
|
-
raise ArgumentError unless (geo.nil? || geo.is_a?(
|
138
|
-
location = Location.new
|
134
|
+
raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
|
135
|
+
location = Data::Location.new
|
139
136
|
if geo
|
140
137
|
location.city = geo.locality
|
141
138
|
location.state_code = geo.region
|
@@ -149,7 +146,7 @@ module Barometer
|
|
149
146
|
|
150
147
|
# use HTTParty to get the current weather
|
151
148
|
def self.get_all(query, metric=true)
|
152
|
-
|
149
|
+
self.get(
|
153
150
|
"http://google.com/ig/api",
|
154
151
|
:query => {:weather => query, :hl => (metric ? "en-GB" : "en-US")},
|
155
152
|
:format => :xml,
|
@@ -13,20 +13,19 @@ module Barometer
|
|
13
13
|
# drivers. Each driver inherits from this class.
|
14
14
|
#
|
15
15
|
# Basically, all a service is required to do is take a query
|
16
|
-
# (ie "Paris") and return a complete
|
16
|
+
# (ie "Paris") and return a complete Data::Measurement instance.
|
17
17
|
#
|
18
|
-
class
|
19
|
-
|
18
|
+
class WeatherService
|
20
19
|
# all service drivers will use the HTTParty gem
|
21
20
|
include HTTParty
|
22
21
|
|
23
|
-
#
|
22
|
+
# retrieves the weather source Service object
|
24
23
|
def self.source(source_name)
|
25
24
|
raise ArgumentError unless (source_name.is_a?(String) || source_name.is_a?(Symbol))
|
26
25
|
source_name = source_name.to_s.split("_").collect{ |s| s.capitalize }.join('')
|
27
|
-
raise ArgumentError unless Barometer.const_defined?(source_name)
|
28
|
-
raise ArgumentError unless Barometer.const_get(source_name).superclass == Barometer::
|
29
|
-
Barometer.const_get(source_name)
|
26
|
+
raise ArgumentError unless Barometer::WeatherService.const_defined?(source_name)
|
27
|
+
raise ArgumentError unless Barometer::WeatherService.const_get(source_name).superclass == Barometer::WeatherService
|
28
|
+
Barometer::WeatherService.const_get(source_name)
|
30
29
|
end
|
31
30
|
|
32
31
|
#
|
@@ -35,10 +34,14 @@ module Barometer
|
|
35
34
|
def self.measure(query, metric=true)
|
36
35
|
raise ArgumentError unless query.is_a?(Barometer::Query)
|
37
36
|
|
38
|
-
measurement =
|
37
|
+
measurement = Data::Measurement.new(self.source_name, metric)
|
39
38
|
if self.meets_requirements?(query)
|
40
|
-
query.convert!(self.accepted_formats)
|
41
|
-
|
39
|
+
converted_query = query.convert!(self.accepted_formats)
|
40
|
+
if converted_query
|
41
|
+
measurement.query = converted_query.q
|
42
|
+
measurement.format = converted_query.format
|
43
|
+
measurement = self._measure(measurement, converted_query, metric)
|
44
|
+
end
|
42
45
|
end
|
43
46
|
measurement
|
44
47
|
end
|
@@ -51,40 +54,34 @@ module Barometer
|
|
51
54
|
# NOTE: The following methods MUST be re-defined by each driver.
|
52
55
|
#
|
53
56
|
|
57
|
+
# STUB: define this method to actually retireve the source_name
|
58
|
+
def self.source_name; raise NotImplementedError; end
|
59
|
+
|
54
60
|
# STUB: define this method to indicate what query formats are accepted
|
55
|
-
def self.accepted_formats
|
56
|
-
raise NotImplementedError
|
57
|
-
end
|
61
|
+
def self.accepted_formats; raise NotImplementedError; end
|
58
62
|
|
59
63
|
# STUB: define this method to measure the current & future weather
|
60
64
|
def self._measure(measurement=nil, query=nil, metric=true)
|
61
65
|
raise NotImplementedError
|
62
66
|
end
|
63
67
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
+
#
|
69
|
+
# NOTE: The following methods can be re-defined by each driver. [OPTIONAL]
|
70
|
+
#
|
68
71
|
|
69
72
|
# STUB: define this method to check for the existance of API keys,
|
70
73
|
# this method is NOT needed if requires_keys? returns false
|
71
|
-
def self.has_keys
|
72
|
-
raise NotImplementedError
|
73
|
-
end
|
74
|
+
def self.has_keys?; raise NotImplementedError; end
|
74
75
|
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
76
|
+
# STUB: define this method to check for the existance of API keys,
|
77
|
+
# this method is NOT needed if requires_keys? returns false
|
78
|
+
def self.keys=(keys=nil); nil; end
|
78
79
|
|
79
80
|
# DEFAULT: override this if you need to determine if the country is specified
|
80
|
-
def self.supports_country?(query=nil)
|
81
|
-
true
|
82
|
-
end
|
81
|
+
def self.supports_country?(query=nil); true; end
|
83
82
|
|
84
83
|
# DEFAULT: override this if you need to determine if API keys are required
|
85
|
-
def self.requires_keys
|
86
|
-
false
|
87
|
-
end
|
84
|
+
def self.requires_keys?; false; end
|
88
85
|
|
89
86
|
#
|
90
87
|
# answer simple questions
|
@@ -93,20 +90,21 @@ module Barometer
|
|
93
90
|
#
|
94
91
|
# WINDY?
|
95
92
|
#
|
96
|
-
def self.windy?(measurement, threshold=10,
|
97
|
-
|
93
|
+
def self.windy?(measurement, threshold=10, time_string=nil)
|
94
|
+
local_time = Data::LocalDateTime.parse(time_string) if time_string
|
95
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
98
96
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
99
|
-
raise ArgumentError unless (
|
97
|
+
raise ArgumentError unless (local_time.is_a?(Data::LocalDateTime) || local_time.nil?)
|
100
98
|
|
101
|
-
measurement.current?(
|
99
|
+
measurement.current?(local_time) ?
|
102
100
|
self.currently_windy?(measurement, threshold) :
|
103
|
-
self.forecasted_windy?(measurement, threshold,
|
101
|
+
self.forecasted_windy?(measurement, threshold, local_time)
|
104
102
|
end
|
105
103
|
|
106
104
|
# cookie cutter answer, a driver can override this if they answer it differently
|
107
105
|
# if a service doesn't support obtaining the wind value, it will be ignored
|
108
106
|
def self.currently_windy?(measurement, threshold=10)
|
109
|
-
raise ArgumentError unless measurement.is_a?(
|
107
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
110
108
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
111
109
|
return nil if (!measurement.current || !measurement.current.wind?)
|
112
110
|
measurement.metric? ?
|
@@ -115,23 +113,24 @@ module Barometer
|
|
115
113
|
end
|
116
114
|
|
117
115
|
# no driver can currently answer this question, so it doesn't have any code
|
118
|
-
def self.forecasted_windy?(measurement, threshold,
|
116
|
+
def self.forecasted_windy?(measurement, threshold, time_string); nil; end
|
119
117
|
|
120
118
|
#
|
121
119
|
# WET?
|
122
120
|
#
|
123
|
-
def self.wet?(measurement, threshold=50,
|
124
|
-
|
121
|
+
def self.wet?(measurement, threshold=50, time_string=nil)
|
122
|
+
local_time = Data::LocalDateTime.parse(time_string) if time_string
|
123
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
125
124
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
126
|
-
raise ArgumentError unless (
|
127
|
-
measurement.current?(
|
125
|
+
raise ArgumentError unless (local_time.is_a?(Data::LocalDateTime) || local_time.nil?)
|
126
|
+
measurement.current?(local_time) ?
|
128
127
|
self.currently_wet?(measurement, threshold) :
|
129
|
-
self.forecasted_wet?(measurement, threshold,
|
128
|
+
self.forecasted_wet?(measurement, threshold, local_time)
|
130
129
|
end
|
131
130
|
|
132
131
|
# cookie cutter answer
|
133
132
|
def self.currently_wet?(measurement, threshold=50)
|
134
|
-
raise ArgumentError unless measurement.is_a?(
|
133
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
135
134
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
136
135
|
return nil unless measurement.current
|
137
136
|
self.currently_wet_by_icon?(measurement.current) ||
|
@@ -142,7 +141,7 @@ module Barometer
|
|
142
141
|
|
143
142
|
# cookie cutter answer
|
144
143
|
def self.currently_wet_by_dewpoint?(measurement)
|
145
|
-
raise ArgumentError unless measurement.is_a?(
|
144
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
146
145
|
return nil if (!measurement.current || !measurement.current.temperature? ||
|
147
146
|
!measurement.current.dew_point?)
|
148
147
|
measurement.metric? ?
|
@@ -152,14 +151,14 @@ module Barometer
|
|
152
151
|
|
153
152
|
# cookie cutter answer
|
154
153
|
def self.currently_wet_by_humidity?(current_measurement)
|
155
|
-
raise ArgumentError unless current_measurement.is_a?(
|
154
|
+
raise ArgumentError unless current_measurement.is_a?(Data::CurrentMeasurement)
|
156
155
|
return nil unless current_measurement.humidity?
|
157
156
|
current_measurement.humidity.to_i >= 99
|
158
157
|
end
|
159
158
|
|
160
159
|
# cookie cutter answer
|
161
160
|
def self.currently_wet_by_pop?(measurement, threshold=50)
|
162
|
-
raise ArgumentError unless measurement.is_a?(
|
161
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
163
162
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
164
163
|
return nil unless measurement.forecast
|
165
164
|
# get todays forecast
|
@@ -169,12 +168,13 @@ module Barometer
|
|
169
168
|
end
|
170
169
|
|
171
170
|
# cookie cutter answer
|
172
|
-
def self.forecasted_wet?(measurement, threshold=50,
|
173
|
-
|
171
|
+
def self.forecasted_wet?(measurement, threshold=50, time_string=nil)
|
172
|
+
local_time = Data::LocalDateTime.parse(time_string) if time_string
|
173
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
174
174
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
175
|
-
raise ArgumentError unless (
|
175
|
+
raise ArgumentError unless (local_time.is_a?(Data::LocalDateTime) || local_time.nil?)
|
176
176
|
return nil unless measurement.forecast
|
177
|
-
forecast_measurement = measurement.for(
|
177
|
+
forecast_measurement = measurement.for(local_time)
|
178
178
|
return nil unless forecast_measurement
|
179
179
|
self.forecasted_wet_by_icon?(forecast_measurement) ||
|
180
180
|
self.forecasted_wet_by_pop?(forecast_measurement, threshold)
|
@@ -182,14 +182,14 @@ module Barometer
|
|
182
182
|
|
183
183
|
# cookie cutter answer
|
184
184
|
def self.forecasted_wet_by_pop?(forecast_measurement, threshold=50)
|
185
|
-
raise ArgumentError unless forecast_measurement.is_a?(
|
185
|
+
raise ArgumentError unless forecast_measurement.is_a?(Data::ForecastMeasurement)
|
186
186
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
187
187
|
return nil unless forecast_measurement.pop?
|
188
188
|
forecast_measurement.pop.to_f >= threshold.to_f
|
189
189
|
end
|
190
190
|
|
191
191
|
def self.currently_wet_by_icon?(current_measurement)
|
192
|
-
raise ArgumentError unless current_measurement.is_a?(
|
192
|
+
raise ArgumentError unless current_measurement.is_a?(Data::CurrentMeasurement)
|
193
193
|
return nil unless self.wet_icon_codes
|
194
194
|
return nil unless current_measurement.icon?
|
195
195
|
current_measurement.icon.is_a?(String) ?
|
@@ -198,7 +198,7 @@ module Barometer
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def self.forecasted_wet_by_icon?(forecast_measurement)
|
201
|
-
raise ArgumentError unless forecast_measurement.is_a?(
|
201
|
+
raise ArgumentError unless forecast_measurement.is_a?(Data::ForecastMeasurement)
|
202
202
|
return nil unless self.wet_icon_codes
|
203
203
|
return nil unless forecast_measurement.icon?
|
204
204
|
forecast_measurement.icon.is_a?(String) ?
|
@@ -212,90 +212,100 @@ module Barometer
|
|
212
212
|
#
|
213
213
|
# DAY?
|
214
214
|
#
|
215
|
-
def self.day?(measurement,
|
216
|
-
|
217
|
-
raise ArgumentError unless
|
215
|
+
def self.day?(measurement, time_string=nil)
|
216
|
+
local_datetime = Data::LocalDateTime.parse(time_string) if time_string
|
217
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
218
|
+
raise ArgumentError unless (local_datetime.is_a?(Data::LocalDateTime) || local_datetime.nil?)
|
218
219
|
|
219
|
-
measurement.current?(
|
220
|
+
measurement.current?(local_datetime) ?
|
220
221
|
self.currently_day?(measurement) :
|
221
|
-
self.forecasted_day?(measurement,
|
222
|
+
self.forecasted_day?(measurement, local_datetime)
|
222
223
|
end
|
223
224
|
|
224
225
|
def self.currently_day?(measurement)
|
225
|
-
raise ArgumentError unless measurement.is_a?(
|
226
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
226
227
|
return nil unless measurement.current && measurement.current.sun
|
227
228
|
self.currently_after_sunrise?(measurement.current) &&
|
228
229
|
self.currently_before_sunset?(measurement.current)
|
229
230
|
end
|
230
231
|
|
231
232
|
def self.currently_after_sunrise?(current_measurement)
|
232
|
-
raise ArgumentError unless current_measurement.is_a?(
|
233
|
-
return nil unless current_measurement.
|
234
|
-
|
233
|
+
raise ArgumentError unless current_measurement.is_a?(Data::CurrentMeasurement)
|
234
|
+
return nil unless current_measurement.current_at &&
|
235
|
+
current_measurement.sun && current_measurement.sun.rise
|
236
|
+
#Time.now.utc >= current_measurement.sun.rise
|
237
|
+
current_measurement.current_at >= current_measurement.sun.rise
|
235
238
|
end
|
236
239
|
|
237
240
|
def self.currently_before_sunset?(current_measurement)
|
238
|
-
raise ArgumentError unless current_measurement.is_a?(
|
239
|
-
return nil unless current_measurement.
|
240
|
-
|
241
|
+
raise ArgumentError unless current_measurement.is_a?(Data::CurrentMeasurement)
|
242
|
+
return nil unless current_measurement.current_at &&
|
243
|
+
current_measurement.sun && current_measurement.sun.set
|
244
|
+
#Time.now.utc <= current_measurement.sun.set
|
245
|
+
current_measurement.current_at <= current_measurement.sun.set
|
241
246
|
end
|
242
247
|
|
243
|
-
def self.forecasted_day?(measurement,
|
244
|
-
|
245
|
-
raise ArgumentError unless
|
248
|
+
def self.forecasted_day?(measurement, time_string=nil)
|
249
|
+
local_datetime = Data::LocalDateTime.parse(time_string) if time_string
|
250
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
251
|
+
raise ArgumentError unless (local_datetime.is_a?(Data::LocalDateTime) || local_datetime.nil?)
|
246
252
|
return nil unless measurement.forecast
|
247
|
-
forecast_measurement = measurement.for(
|
253
|
+
forecast_measurement = measurement.for(local_datetime)
|
248
254
|
return nil unless forecast_measurement
|
249
|
-
self.forecasted_after_sunrise?(forecast_measurement,
|
250
|
-
self.forecasted_before_sunset?(forecast_measurement,
|
255
|
+
self.forecasted_after_sunrise?(forecast_measurement, local_datetime) &&
|
256
|
+
self.forecasted_before_sunset?(forecast_measurement, local_datetime)
|
251
257
|
end
|
252
258
|
|
253
|
-
def self.forecasted_after_sunrise?(forecast_measurement,
|
254
|
-
|
255
|
-
raise ArgumentError unless
|
259
|
+
def self.forecasted_after_sunrise?(forecast_measurement, time_string)
|
260
|
+
local_datetime = Data::LocalDateTime.parse(time_string) if time_string
|
261
|
+
raise ArgumentError unless forecast_measurement.is_a?(Data::ForecastMeasurement)
|
262
|
+
raise ArgumentError unless (local_datetime.is_a?(Data::LocalDateTime) || local_datetime.nil?)
|
256
263
|
return nil unless forecast_measurement.sun && forecast_measurement.sun.rise
|
257
|
-
|
264
|
+
local_datetime >= forecast_measurement.sun.rise
|
258
265
|
end
|
259
266
|
|
260
|
-
def self.forecasted_before_sunset?(forecast_measurement,
|
261
|
-
|
262
|
-
raise ArgumentError unless
|
267
|
+
def self.forecasted_before_sunset?(forecast_measurement, time_string)
|
268
|
+
local_datetime = Data::LocalDateTime.parse(time_string) if time_string
|
269
|
+
raise ArgumentError unless forecast_measurement.is_a?(Data::ForecastMeasurement)
|
270
|
+
raise ArgumentError unless (local_datetime.is_a?(Data::LocalDateTime) || local_datetime.nil?)
|
263
271
|
return nil unless forecast_measurement.sun && forecast_measurement.sun.set
|
264
|
-
|
272
|
+
local_datetime <= forecast_measurement.sun.set
|
265
273
|
end
|
266
274
|
|
267
275
|
#
|
268
276
|
# SUNNY?
|
269
277
|
#
|
270
|
-
def self.sunny?(measurement,
|
271
|
-
|
272
|
-
raise ArgumentError unless
|
273
|
-
|
278
|
+
def self.sunny?(measurement, time_string=nil)
|
279
|
+
local_time = Data::LocalDateTime.parse(time_string) if time_string
|
280
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
281
|
+
raise ArgumentError unless (local_time.is_a?(Data::LocalDateTime) || local_time.nil?)
|
282
|
+
measurement.current?(local_time) ?
|
274
283
|
self.currently_sunny?(measurement) :
|
275
|
-
self.forecasted_sunny?(measurement,
|
284
|
+
self.forecasted_sunny?(measurement, local_time)
|
276
285
|
end
|
277
286
|
|
278
287
|
# cookie cutter answer
|
279
288
|
def self.currently_sunny?(measurement)
|
280
|
-
raise ArgumentError unless measurement.is_a?(
|
289
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
281
290
|
return nil unless measurement.current
|
282
291
|
return false if self.currently_day?(measurement) == false
|
283
292
|
self.currently_sunny_by_icon?(measurement.current)
|
284
293
|
end
|
285
294
|
|
286
295
|
# cookie cutter answer
|
287
|
-
def self.forecasted_sunny?(measurement,
|
288
|
-
|
289
|
-
raise ArgumentError unless
|
296
|
+
def self.forecasted_sunny?(measurement, time_string=nil)
|
297
|
+
local_time = Data::LocalDateTime.parse(time_string) if time_string
|
298
|
+
raise ArgumentError unless measurement.is_a?(Data::Measurement)
|
299
|
+
raise ArgumentError unless (local_time.is_a?(Data::LocalDateTime) || local_time.nil?)
|
290
300
|
return nil unless measurement.forecast
|
291
|
-
return false if self.forecasted_day?(measurement,
|
292
|
-
forecast_measurement = measurement.for(
|
301
|
+
return false if self.forecasted_day?(measurement, local_time) == false
|
302
|
+
forecast_measurement = measurement.for(local_time)
|
293
303
|
return nil unless forecast_measurement
|
294
304
|
self.forecasted_sunny_by_icon?(forecast_measurement)
|
295
305
|
end
|
296
306
|
|
297
307
|
def self.currently_sunny_by_icon?(current_measurement)
|
298
|
-
raise ArgumentError unless current_measurement.is_a?(
|
308
|
+
raise ArgumentError unless current_measurement.is_a?(Data::CurrentMeasurement)
|
299
309
|
return nil unless self.sunny_icon_codes
|
300
310
|
return nil unless current_measurement.icon?
|
301
311
|
current_measurement.icon.is_a?(String) ?
|
@@ -304,7 +314,7 @@ module Barometer
|
|
304
314
|
end
|
305
315
|
|
306
316
|
def self.forecasted_sunny_by_icon?(forecast_measurement)
|
307
|
-
raise ArgumentError unless forecast_measurement.is_a?(
|
317
|
+
raise ArgumentError unless forecast_measurement.is_a?(Data::ForecastMeasurement)
|
308
318
|
return nil unless self.sunny_icon_codes
|
309
319
|
return nil unless forecast_measurement.icon?
|
310
320
|
forecast_measurement.icon.is_a?(String) ?
|
@@ -316,7 +326,6 @@ module Barometer
|
|
316
326
|
def self.sunny_icon_codes; nil; end
|
317
327
|
|
318
328
|
end
|
319
|
-
|
320
329
|
end
|
321
330
|
|
322
331
|
# def key_name
|