barometer 0.7.3 → 0.8.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/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/LICENSE +1 -1
- data/{README.rdoc → README.md} +124 -110
- data/Rakefile +1 -21
- data/TODO +8 -9
- data/barometer.gemspec +20 -19
- data/bin/barometer +36 -83
- data/lib/barometer.rb +13 -11
- data/lib/barometer/base.rb +10 -10
- data/lib/barometer/data.rb +1 -1
- data/lib/barometer/data/distance.rb +25 -25
- data/lib/barometer/data/geo.rb +9 -9
- data/lib/barometer/data/local_datetime.rb +24 -20
- data/lib/barometer/data/local_time.rb +13 -13
- data/lib/barometer/data/location.rb +6 -6
- data/lib/barometer/data/pressure.rb +24 -24
- data/lib/barometer/data/speed.rb +28 -28
- data/lib/barometer/data/sun.rb +7 -7
- data/lib/barometer/data/temperature.rb +29 -29
- data/lib/barometer/data/units.rb +9 -9
- data/lib/barometer/data/zone.rb +19 -19
- data/lib/barometer/formats.rb +1 -1
- data/lib/barometer/formats/coordinates.rb +7 -7
- data/lib/barometer/formats/format.rb +6 -6
- data/lib/barometer/formats/geocode.rb +5 -5
- data/lib/barometer/formats/icao.rb +6 -6
- data/lib/barometer/formats/postalcode.rb +3 -3
- data/lib/barometer/formats/short_zipcode.rb +2 -2
- data/lib/barometer/formats/weather_id.rb +10 -10
- data/lib/barometer/formats/woe_id.rb +20 -20
- data/lib/barometer/formats/zipcode.rb +3 -3
- data/lib/barometer/key_file_parser.rb +20 -0
- data/lib/barometer/measurements/measurement.rb +32 -32
- data/lib/barometer/measurements/result.rb +39 -39
- data/lib/barometer/measurements/result_array.rb +12 -12
- data/lib/barometer/query.rb +15 -15
- data/lib/barometer/services.rb +3 -3
- data/lib/barometer/translations/icao_country_codes.yml +20 -20
- data/lib/barometer/translations/weather_country_codes.yml +1 -1
- data/lib/barometer/translations/zone_codes.yml +2 -2
- data/lib/barometer/version.rb +3 -0
- data/lib/barometer/weather.rb +27 -27
- data/lib/barometer/weather_services/noaa.rb +314 -3
- data/lib/barometer/weather_services/service.rb +32 -30
- data/lib/barometer/weather_services/weather_bug.rb +35 -33
- data/lib/barometer/weather_services/wunderground.rb +31 -29
- data/lib/barometer/weather_services/yahoo.rb +36 -35
- data/lib/barometer/web_services/geocode.rb +5 -7
- data/lib/barometer/web_services/noaa_station_id.rb +53 -0
- data/lib/barometer/web_services/placemaker.rb +11 -13
- data/lib/barometer/web_services/timezone.rb +5 -7
- data/lib/barometer/web_services/weather_id.rb +4 -6
- data/lib/barometer/web_services/web_service.rb +4 -4
- data/spec/barometer_spec.rb +25 -27
- data/spec/cassettes/Barometer.json +1 -0
- data/spec/cassettes/Query.json +1 -0
- data/spec/cassettes/Query_Format_Coordinates.json +1 -0
- data/spec/cassettes/Query_Format_Geocode.json +1 -0
- data/spec/cassettes/Query_Format_WeatherID.json +1 -0
- data/spec/cassettes/Query_Format_WoeID.json +1 -0
- data/spec/cassettes/WeatherService.json +1 -0
- data/spec/cassettes/WeatherService_Noaa.json +1 -0
- data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
- data/spec/cassettes/WeatherService_Wunderground.json +1 -0
- data/spec/cassettes/WeatherService_Yahoo.json +1 -0
- data/spec/cassettes/WebService_Geocode.json +1 -0
- data/spec/cassettes/WebService_NoaaStation.json +1 -0
- data/spec/data/distance_spec.rb +60 -60
- data/spec/data/geo_spec.rb +23 -23
- data/spec/data/local_datetime_spec.rb +44 -44
- data/spec/data/local_time_spec.rb +47 -47
- data/spec/data/location_spec.rb +16 -16
- data/spec/data/pressure_spec.rb +61 -61
- data/spec/data/speed_spec.rb +69 -69
- data/spec/data/sun_spec.rb +25 -25
- data/spec/data/temperature_spec.rb +68 -68
- data/spec/data/units_spec.rb +21 -21
- data/spec/data/zone_spec.rb +35 -35
- data/spec/formats/coordinates_spec.rb +27 -27
- data/spec/formats/format_spec.rb +17 -25
- data/spec/formats/geocode_spec.rb +23 -31
- data/spec/formats/icao_spec.rb +26 -32
- data/spec/formats/postalcode_spec.rb +22 -28
- data/spec/formats/short_zipcode_spec.rb +20 -26
- data/spec/formats/weather_id_spec.rb +57 -67
- data/spec/formats/woe_id_spec.rb +59 -59
- data/spec/formats/zipcode_spec.rb +39 -47
- data/spec/key_file_parser_spec.rb +28 -0
- data/spec/measurements/measurement_spec.rb +79 -133
- data/spec/measurements/result_array_spec.rb +23 -38
- data/spec/measurements/result_spec.rb +100 -128
- data/spec/query_spec.rb +83 -100
- data/spec/spec_helper.rb +24 -6
- data/spec/weather_services/noaa_spec.rb +179 -0
- data/spec/weather_services/services_spec.rb +28 -36
- data/spec/weather_services/weather_bug_spec.rb +57 -77
- data/spec/weather_services/wunderground_spec.rb +36 -65
- data/spec/weather_services/yahoo_spec.rb +38 -60
- data/spec/weather_spec.rb +79 -79
- data/spec/web_services/geocode_spec.rb +7 -11
- data/spec/web_services/noaa_station_id_spec.rb +33 -0
- data/spec/web_services/placemaker_spec.rb +7 -12
- data/spec/web_services/web_services_spec.rb +3 -9
- metadata +214 -163
- data/VERSION.yml +0 -5
- data/lib/barometer/weather_services/google.rb +0 -142
- data/lib/barometer/weather_services/weather_dot_com.rb +0 -279
- data/spec/fakeweb_helper.rb +0 -179
- data/spec/fixtures/formats/weather_id/90210.xml +0 -7
- data/spec/fixtures/formats/weather_id/from_USGA0028.xml +0 -3
- data/spec/fixtures/formats/weather_id/ksfo.xml +0 -1
- data/spec/fixtures/formats/weather_id/manhattan.xml +0 -7
- data/spec/fixtures/formats/weather_id/new_york.xml +0 -1
- data/spec/fixtures/formats/weather_id/the_hills.xml +0 -1
- data/spec/fixtures/geocode/40_73_v3.json +0 -497
- data/spec/fixtures/geocode/90210_v3.json +0 -63
- data/spec/fixtures/geocode/T5B4M9_v3.json +0 -68
- data/spec/fixtures/geocode/atlanta_v3.json +0 -58
- data/spec/fixtures/geocode/calgary_ab_v3.json +0 -58
- data/spec/fixtures/geocode/ksfo_v3.json +0 -73
- data/spec/fixtures/geocode/newyork_ny_v3.json +0 -58
- data/spec/fixtures/services/google/calgary_ab.xml +0 -1
- data/spec/fixtures/services/placemaker/T5B4M9.xml +0 -65
- data/spec/fixtures/services/placemaker/atlanta.xml +0 -65
- data/spec/fixtures/services/placemaker/coords.xml +0 -65
- data/spec/fixtures/services/placemaker/ksfo.xml +0 -65
- data/spec/fixtures/services/placemaker/new_york.xml +0 -65
- data/spec/fixtures/services/placemaker/the_hills.xml +0 -65
- data/spec/fixtures/services/placemaker/w615702.xml +0 -47
- data/spec/fixtures/services/weather_bug/90210_current.xml +0 -93
- data/spec/fixtures/services/weather_bug/90210_forecast.xml +0 -76
- data/spec/fixtures/services/weather_dot_com/90210.xml +0 -1
- data/spec/fixtures/services/wunderground/current_calgary_ab.xml +0 -9
- data/spec/fixtures/services/wunderground/forecast_calgary_ab.xml +0 -13
- data/spec/fixtures/services/yahoo/90210.xml +0 -3
- data/spec/weather_services/google_spec.rb +0 -181
- data/spec/weather_services/weather_dot_com_spec.rb +0 -224
@@ -16,46 +16,46 @@ module Barometer
|
|
16
16
|
# :woe_id and how to convert to a :woe_id.
|
17
17
|
#
|
18
18
|
class Query::Format::WoeID < Query::Format
|
19
|
-
|
19
|
+
|
20
20
|
def self.format; :woe_id; end
|
21
21
|
def self.regex; /(^[0-9]{4}$)|(^[0-9]{6,7}$)|(^w[0-9]{4,7}$)/; end
|
22
22
|
def self.convertable_formats
|
23
23
|
[:short_zipcode, :zipcode, :weather_id, :coordinates, :icao, :geocode, :postalcode]
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
# remove the 'w' from applicable queries (only needed for detection)
|
27
27
|
#
|
28
28
|
def self.convert_query(text)
|
29
29
|
return nil unless text
|
30
30
|
text.delete('w')
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# convert to this format, X -> :woeid
|
34
34
|
#
|
35
35
|
def self.to(original_query)
|
36
36
|
raise ArgumentError unless is_a_query?(original_query)
|
37
37
|
return nil unless converts?(original_query)
|
38
|
-
|
38
|
+
|
39
39
|
# pre-convert (:weather_id -> :geocode)
|
40
40
|
#
|
41
41
|
pre_query = nil
|
42
42
|
if original_query.format == :weather_id
|
43
|
-
pre_query = Query::Format::WeatherID.reverse(original_query)
|
43
|
+
pre_query = Barometer::Query::Format::WeatherID.reverse(original_query)
|
44
44
|
end
|
45
45
|
|
46
46
|
# pre-convert ([:short_zipcode, :zipcode, :postalcode, :icao] -> :geocode)
|
47
47
|
#
|
48
48
|
unless pre_query
|
49
49
|
if [:short_zipcode, :zipcode, :icao].include?(original_query.format)
|
50
|
-
unless pre_query = original_query.get_conversion(Query::Format::Geocode.format)
|
51
|
-
pre_query = Query::Format::Geocode.to(original_query)
|
50
|
+
unless pre_query = original_query.get_conversion(Barometer::Query::Format::Geocode.format)
|
51
|
+
pre_query = Barometer::Query::Format::Geocode.to(original_query)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
converted_query = Barometer::Query.new
|
57
57
|
converted_query.country_code = original_query.country_code if original_query
|
58
|
-
|
58
|
+
|
59
59
|
# TODO
|
60
60
|
# use Geomojo.com (when no Yahoo! appid)
|
61
61
|
#
|
@@ -72,12 +72,12 @@ module Barometer
|
|
72
72
|
converted_query.q = _query_placemaker(pre_query || original_query)
|
73
73
|
converted_query.format = format
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
converted_query.geo = pre_query.geo if pre_query
|
77
77
|
converted_query.country_code = pre_query.country_code if pre_query
|
78
78
|
converted_query
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
# reverse lookup, :woe_id -> (:geocode || :coordinates)
|
82
82
|
#
|
83
83
|
def self.reverse(original_query)
|
@@ -88,19 +88,19 @@ module Barometer
|
|
88
88
|
converted_query.format = Barometer::Query::Format::Geocode.format
|
89
89
|
converted_query
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
private
|
93
|
-
|
93
|
+
|
94
94
|
# Yahoo! Placemaker
|
95
95
|
# [:geocode,:coordinates] -> :woe_id
|
96
96
|
#
|
97
97
|
def self._query_placemaker(query=nil)
|
98
98
|
return nil unless query
|
99
99
|
raise ArgumentError unless is_a_query?(query)
|
100
|
-
doc = WebService::Placemaker.fetch(query)
|
100
|
+
doc = Barometer::WebService::Placemaker.fetch(query)
|
101
101
|
_parse_woe_from_placemaker(doc)
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
# Geomojo.com
|
105
105
|
# [:coordinates] -> :woe_id
|
106
106
|
#
|
@@ -110,14 +110,14 @@ module Barometer
|
|
110
110
|
# doc = WebService::Geomojo.fetch(query)
|
111
111
|
# _parse_woe_from_geomojo(doc)
|
112
112
|
# end
|
113
|
-
|
113
|
+
|
114
114
|
# :woe_id -> :geocode
|
115
115
|
# query yahoo with :woe_id and parse geo_data
|
116
116
|
#
|
117
117
|
def self._reverse(query=nil)
|
118
118
|
return nil unless query
|
119
119
|
raise ArgumentError unless is_a_query?(query)
|
120
|
-
response = WebService::Placemaker.reverse(query)
|
120
|
+
response = Barometer::WebService::Placemaker.reverse(query)
|
121
121
|
_parse_geocode(response)
|
122
122
|
end
|
123
123
|
|
@@ -126,9 +126,9 @@ module Barometer
|
|
126
126
|
#
|
127
127
|
def self._parse_woe_from_placemaker(doc)
|
128
128
|
return nil unless doc
|
129
|
-
WebService::Placemaker.parse_woe_id(doc)
|
129
|
+
Barometer::WebService::Placemaker.parse_woe_id(doc)
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
# match the first :woe_id (from search results)
|
133
133
|
# expects a Nokogiri doc
|
134
134
|
#
|
@@ -145,6 +145,6 @@ module Barometer
|
|
145
145
|
output.delete("")
|
146
146
|
output.compact.join(', ')
|
147
147
|
end
|
148
|
-
|
148
|
+
|
149
149
|
end
|
150
|
-
end
|
150
|
+
end
|
@@ -9,7 +9,7 @@ module Barometer
|
|
9
9
|
# and what the country_code is.
|
10
10
|
#
|
11
11
|
class Query::Format::Zipcode < Query::Format
|
12
|
-
|
12
|
+
|
13
13
|
def self.format; :zipcode; end
|
14
14
|
def self.country_code(query=nil); "US"; end
|
15
15
|
def self.regex; /(^[0-9]{5}$)|(^[0-9]{5}-[0-9]{4}$)/; end
|
@@ -26,6 +26,6 @@ module Barometer
|
|
26
26
|
converted_query.country_code = country_code(converted_query.q)
|
27
27
|
converted_query
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Barometer
|
2
|
+
KEY_FILE = File.expand_path(File.join('~', '.barometer'))
|
3
|
+
|
4
|
+
class KeyFileParser
|
5
|
+
def self.find(*paths)
|
6
|
+
if File.exists?(KEY_FILE)
|
7
|
+
keys = YAML.load_file(KEY_FILE)
|
8
|
+
|
9
|
+
paths.each do |path|
|
10
|
+
if keys && keys.has_key?(path.to_s)
|
11
|
+
keys = keys.fetch(path.to_s)
|
12
|
+
else
|
13
|
+
keys = nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
keys
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -13,7 +13,7 @@ module Barometer
|
|
13
13
|
# - weather station information (for the station that gave collected the data)
|
14
14
|
#
|
15
15
|
class Measurement
|
16
|
-
|
16
|
+
|
17
17
|
attr_reader :source, :weight
|
18
18
|
attr_reader :measured_at, :utc_time_stamp
|
19
19
|
attr_reader :current, :forecast
|
@@ -21,7 +21,7 @@ module Barometer
|
|
21
21
|
attr_reader :success
|
22
22
|
attr_accessor :metric, :query, :format
|
23
23
|
attr_accessor :start_at, :end_at
|
24
|
-
|
24
|
+
|
25
25
|
def initialize(source=nil, metric=true)
|
26
26
|
@source = source
|
27
27
|
@metric = metric
|
@@ -29,19 +29,19 @@ module Barometer
|
|
29
29
|
@weight = 1
|
30
30
|
@links = {}
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def success!
|
34
34
|
current && current.temperature &&
|
35
35
|
!current.temperature.c.nil? && @success = true
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def stamp!; @utc_time_stamp = Time.now.utc; end
|
39
39
|
def success?; @success; end
|
40
40
|
def metric?; @metric; end
|
41
41
|
def metric!; @metric=true; end
|
42
42
|
def imperial!; @metric=false; end
|
43
43
|
def now; timezone ? timezone.now : nil; end
|
44
|
-
|
44
|
+
|
45
45
|
#
|
46
46
|
# this will tell us if the measurement is still current ... if it is still
|
47
47
|
# current this means that the CurrentMeasurement can still used as now
|
@@ -58,16 +58,16 @@ module Barometer
|
|
58
58
|
def current?(local_time=nil)
|
59
59
|
current_at = ((self.current && self.current.current_at) ?
|
60
60
|
self.current.current_at : self.measured_at)
|
61
|
-
|
61
|
+
|
62
62
|
local_time = (local_time.nil? ? current_at : Data::LocalTime.parse(local_time))
|
63
63
|
return true unless local_time
|
64
64
|
raise ArgumentError unless local_time.is_a?(Data::LocalTime)
|
65
|
-
|
65
|
+
|
66
66
|
hours_still_current = 4
|
67
67
|
difference = (local_time.diff(current_at)).to_i.abs
|
68
68
|
difference <= (60*60*hours_still_current).to_i
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
#
|
72
72
|
# Returns a forecast for a day given by a Date, DateTime,
|
73
73
|
# Time, or a string that can be parsed to a date
|
@@ -76,75 +76,75 @@ module Barometer
|
|
76
76
|
date = @timezone.today unless date || !@timezone
|
77
77
|
date ||= Date.today
|
78
78
|
return nil unless (@forecast && @forecast.size > 0)
|
79
|
-
|
79
|
+
|
80
80
|
@forecast.for(date)
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
#
|
84
84
|
# accesors (with input checking)
|
85
85
|
#
|
86
|
-
|
86
|
+
|
87
87
|
def source=(source)
|
88
88
|
raise ArgumentError unless source.is_a?(Symbol)
|
89
89
|
@source = source
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
def utc_time_stamp=(time=Time.now.utc)
|
93
93
|
raise ArgumentError unless time.is_a?(Time)
|
94
94
|
@utc_time_stamp = time
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def current=(current)
|
98
98
|
raise ArgumentError unless current.is_a?(Measurement::Result)
|
99
99
|
@current = current
|
100
100
|
self.stamp!
|
101
101
|
self.success!
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
def forecast=(forecast)
|
105
105
|
raise ArgumentError unless forecast.is_a?(Measurement::ResultArray)
|
106
106
|
@forecast = forecast
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def timezone=(timezone)
|
110
110
|
return unless timezone
|
111
111
|
raise ArgumentError unless timezone.is_a?(Data::Zone)
|
112
112
|
@timezone = timezone
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
def station=(station)
|
116
116
|
raise ArgumentError unless station.is_a?(Data::Location)
|
117
117
|
@station = station
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
def location=(location)
|
121
121
|
raise ArgumentError unless location.is_a?(Data::Location)
|
122
122
|
@location = location
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
def weight=(weight)
|
126
126
|
raise ArgumentError unless weight.is_a?(Fixnum)
|
127
127
|
@weight = weight
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
def links=(links)
|
131
131
|
raise ArgumentError unless links.is_a?(Hash)
|
132
132
|
@links = links
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
def measured_at=(measured_at)
|
136
136
|
raise ArgumentError unless measured_at.is_a?(Data::LocalTime)
|
137
137
|
@measured_at = measured_at
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
#
|
141
141
|
# simple questions
|
142
142
|
#
|
143
|
-
|
143
|
+
|
144
144
|
def windy?(time_string=nil, threshold=10)
|
145
145
|
time_string ||= (measured_at || now)
|
146
146
|
local_time = Data::LocalTime.parse(time_string)
|
147
|
-
|
147
|
+
|
148
148
|
if current?(local_time)
|
149
149
|
return nil unless current
|
150
150
|
current.windy?(threshold)
|
@@ -153,11 +153,11 @@ module Barometer
|
|
153
153
|
future.windy?(threshold)
|
154
154
|
end
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
def day?(time_string=nil)
|
158
158
|
time_string ||= (measured_at || now)
|
159
159
|
local_time = Data::LocalTime.parse(time_string)
|
160
|
-
|
160
|
+
|
161
161
|
if current?(local_time)
|
162
162
|
return nil unless current
|
163
163
|
current.day?(local_time)
|
@@ -166,15 +166,15 @@ module Barometer
|
|
166
166
|
future.day?(local_time)
|
167
167
|
end
|
168
168
|
end
|
169
|
-
|
169
|
+
|
170
170
|
def sunny?(time_string=nil)
|
171
171
|
time_string ||= (measured_at || now)
|
172
172
|
local_time = Data::LocalTime.parse(time_string)
|
173
173
|
sunny_icons = Barometer::WeatherService.source(@source)._sunny_icon_codes
|
174
|
-
|
174
|
+
|
175
175
|
is_day = day?(local_time)
|
176
176
|
return is_day unless is_day
|
177
|
-
|
177
|
+
|
178
178
|
if current?(local_time)
|
179
179
|
return nil unless current
|
180
180
|
current.sunny?(local_time, sunny_icons)
|
@@ -183,12 +183,12 @@ module Barometer
|
|
183
183
|
future.sunny?(local_time, sunny_icons)
|
184
184
|
end
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
def wet?(time_string=nil, pop_threshold=50, humidity_threshold=99)
|
188
188
|
time_string ||= (measured_at || now)
|
189
189
|
local_time = Data::LocalTime.parse(time_string)
|
190
190
|
wet_icons = Barometer::WeatherService.source(@source)._wet_icon_codes
|
191
|
-
|
191
|
+
|
192
192
|
if current?(local_time)
|
193
193
|
return nil unless current
|
194
194
|
current.wet?(wet_icons, humidity_threshold)
|
@@ -197,6 +197,6 @@ module Barometer
|
|
197
197
|
future.wet?(wet_icons, pop_threshold, humidity_threshold)
|
198
198
|
end
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
end
|
202
|
-
end
|
202
|
+
end
|
@@ -7,7 +7,7 @@ module Barometer
|
|
7
7
|
# conditions.
|
8
8
|
#
|
9
9
|
class Measurement::Result
|
10
|
-
|
10
|
+
|
11
11
|
attr_reader :current_at, :updated_at
|
12
12
|
attr_reader :valid_start_date, :valid_end_date, :date
|
13
13
|
attr_reader :humidity, :icon, :condition
|
@@ -15,131 +15,131 @@ module Barometer
|
|
15
15
|
attr_reader :low, :high, :pop
|
16
16
|
attr_reader :wind, :sun, :pressure, :visibility
|
17
17
|
attr_accessor :metric, :description
|
18
|
-
|
18
|
+
|
19
19
|
def initialize(metric=true); @metric = metric; end
|
20
|
-
|
20
|
+
|
21
21
|
# accessors (with input checking)
|
22
22
|
#
|
23
23
|
def temperature=(temperature)
|
24
24
|
raise ArgumentError unless temperature.is_a?(Data::Temperature)
|
25
25
|
@temperature = temperature
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def dew_point=(dew_point)
|
29
29
|
raise ArgumentError unless dew_point.is_a?(Data::Temperature)
|
30
30
|
@dew_point = dew_point
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def heat_index=(heat_index)
|
34
34
|
raise ArgumentError unless heat_index.is_a?(Data::Temperature)
|
35
35
|
@heat_index = heat_index
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def wind_chill=(wind_chill)
|
39
39
|
raise ArgumentError unless wind_chill.is_a?(Data::Temperature)
|
40
40
|
@wind_chill = wind_chill
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def pressure=(pressure)
|
44
44
|
raise ArgumentError unless pressure.is_a?(Data::Pressure)
|
45
45
|
@pressure = pressure
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def visibility=(visibility)
|
49
49
|
raise ArgumentError unless visibility.is_a?(Data::Distance)
|
50
50
|
@visibility = visibility
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def current_at=(current_at)
|
54
54
|
raise ArgumentError unless (current_at.is_a?(Data::LocalTime) || current_at.is_a?(Data::LocalDateTime))
|
55
55
|
@current_at = current_at
|
56
|
-
end
|
57
|
-
|
56
|
+
end
|
57
|
+
|
58
58
|
def updated_at=(updated_at)
|
59
59
|
raise ArgumentError unless (updated_at.is_a?(Data::LocalTime) || updated_at.is_a?(Data::LocalDateTime))
|
60
60
|
@updated_at = updated_at
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def date=(date)
|
64
64
|
raise ArgumentError unless date.is_a?(Date)
|
65
65
|
@date = date
|
66
66
|
@valid_start_date = Data::LocalDateTime.new(date.year,date.month,date.day,0,0,0)
|
67
67
|
@valid_end_date = Data::LocalDateTime.new(date.year,date.month,date.day,23,59,59)
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def valid_start_date=(date)
|
71
71
|
raise ArgumentError unless date.is_a?(Data::LocalDateTime)
|
72
72
|
@valid_start_date = date
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
def valid_end_date=(date)
|
76
76
|
raise ArgumentError unless date.is_a?(Data::LocalDateTime)
|
77
77
|
@valid_end_date = date
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
def high=(high)
|
81
81
|
raise ArgumentError unless high.is_a?(Data::Temperature)
|
82
82
|
@high = high
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
def low=(low)
|
86
86
|
raise ArgumentError unless low.is_a?(Data::Temperature)
|
87
87
|
@low = low
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
def pop=(pop)
|
91
91
|
raise ArgumentError unless pop.is_a?(Fixnum)
|
92
92
|
@pop = pop
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def humidity=(humidity)
|
96
96
|
raise ArgumentError unless
|
97
97
|
(humidity.is_a?(Fixnum) || humidity.is_a?(Float))
|
98
98
|
@humidity = humidity
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
def icon=(icon)
|
102
102
|
raise ArgumentError unless icon.is_a?(String)
|
103
103
|
@icon = icon
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
def condition=(condition)
|
107
107
|
raise ArgumentError unless condition.is_a?(String)
|
108
108
|
@condition = condition
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
def wind=(wind)
|
112
112
|
raise ArgumentError unless wind.is_a?(Data::Speed)
|
113
113
|
@wind = wind
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def sun=(sun)
|
117
117
|
raise ArgumentError unless (sun.is_a?(Data::Sun) || sun.nil?)
|
118
118
|
@sun = sun
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
#
|
122
122
|
# answer simple questions
|
123
123
|
#
|
124
|
-
|
124
|
+
|
125
125
|
def windy?(threshold=10)
|
126
126
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
127
127
|
return nil unless wind?
|
128
128
|
wind.to_f(metric?) >= threshold.to_f
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
def day?(time)
|
132
132
|
return nil unless time && sun?
|
133
133
|
sun.after_rise?(time) && sun.before_set?(time)
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
def sunny?(time, sunny_icons=nil)
|
137
137
|
return nil unless time
|
138
138
|
is_day = day?(time)
|
139
139
|
return nil if is_day.nil?
|
140
140
|
is_day && _sunny_by_icon?(sunny_icons)
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
def wet?(wet_icons=nil, pop_threshold=50, humidity_threshold=99)
|
144
144
|
result = nil
|
145
145
|
result ||= _wet_by_pop?(pop_threshold) if pop?
|
@@ -148,18 +148,18 @@ module Barometer
|
|
148
148
|
result ||= _wet_by_dewpoint? if (dew_point? && temperature?)
|
149
149
|
result
|
150
150
|
end
|
151
|
-
|
151
|
+
|
152
152
|
#
|
153
153
|
# helpers
|
154
154
|
#
|
155
|
-
|
155
|
+
|
156
156
|
def metric?; metric; end
|
157
|
-
|
157
|
+
|
158
158
|
def for_datetime?(datetime)
|
159
159
|
raise ArgumentError unless datetime.is_a?(Data::LocalDateTime)
|
160
160
|
datetime >= @valid_start_date && datetime <= @valid_end_date
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
# creates "?" helpers for all attributes (which maps to nil?)
|
164
164
|
#
|
165
165
|
def method_missing(method,*args)
|
@@ -171,37 +171,37 @@ module Barometer
|
|
171
171
|
super(method,*args)
|
172
172
|
end
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
private
|
176
|
-
|
176
|
+
|
177
177
|
def _wet_by_dewpoint?
|
178
178
|
return nil unless dew_point? && temperature?
|
179
179
|
temperature.to_f(metric?) <= dew_point.to_f(metric?)
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
def _wet_by_pop?(threshold=50)
|
183
183
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
184
184
|
return nil unless pop?
|
185
185
|
pop.to_f >= threshold.to_f
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
188
|
def _wet_by_humidity?(threshold=99)
|
189
189
|
raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
|
190
190
|
return nil unless humidity?
|
191
191
|
humidity.to_f >= threshold.to_f
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
def _wet_by_icon?(wet_icons=nil)
|
195
195
|
raise ArgumentError unless (wet_icons.nil? || wet_icons.is_a?(Array))
|
196
196
|
return nil unless (icon? && wet_icons)
|
197
197
|
wet_icons.include?(icon.to_s.downcase)
|
198
198
|
end
|
199
|
-
|
199
|
+
|
200
200
|
def _sunny_by_icon?(sunny_icons=nil)
|
201
201
|
raise ArgumentError unless (sunny_icons.nil? || sunny_icons.is_a?(Array))
|
202
202
|
return nil unless (icon? && sunny_icons)
|
203
203
|
sunny_icons.include?(icon.to_s.downcase)
|
204
204
|
end
|
205
|
-
|
205
|
+
|
206
206
|
end
|
207
|
-
end
|
207
|
+
end
|