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.
Files changed (138) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +7 -0
  3. data/LICENSE +1 -1
  4. data/{README.rdoc → README.md} +124 -110
  5. data/Rakefile +1 -21
  6. data/TODO +8 -9
  7. data/barometer.gemspec +20 -19
  8. data/bin/barometer +36 -83
  9. data/lib/barometer.rb +13 -11
  10. data/lib/barometer/base.rb +10 -10
  11. data/lib/barometer/data.rb +1 -1
  12. data/lib/barometer/data/distance.rb +25 -25
  13. data/lib/barometer/data/geo.rb +9 -9
  14. data/lib/barometer/data/local_datetime.rb +24 -20
  15. data/lib/barometer/data/local_time.rb +13 -13
  16. data/lib/barometer/data/location.rb +6 -6
  17. data/lib/barometer/data/pressure.rb +24 -24
  18. data/lib/barometer/data/speed.rb +28 -28
  19. data/lib/barometer/data/sun.rb +7 -7
  20. data/lib/barometer/data/temperature.rb +29 -29
  21. data/lib/barometer/data/units.rb +9 -9
  22. data/lib/barometer/data/zone.rb +19 -19
  23. data/lib/barometer/formats.rb +1 -1
  24. data/lib/barometer/formats/coordinates.rb +7 -7
  25. data/lib/barometer/formats/format.rb +6 -6
  26. data/lib/barometer/formats/geocode.rb +5 -5
  27. data/lib/barometer/formats/icao.rb +6 -6
  28. data/lib/barometer/formats/postalcode.rb +3 -3
  29. data/lib/barometer/formats/short_zipcode.rb +2 -2
  30. data/lib/barometer/formats/weather_id.rb +10 -10
  31. data/lib/barometer/formats/woe_id.rb +20 -20
  32. data/lib/barometer/formats/zipcode.rb +3 -3
  33. data/lib/barometer/key_file_parser.rb +20 -0
  34. data/lib/barometer/measurements/measurement.rb +32 -32
  35. data/lib/barometer/measurements/result.rb +39 -39
  36. data/lib/barometer/measurements/result_array.rb +12 -12
  37. data/lib/barometer/query.rb +15 -15
  38. data/lib/barometer/services.rb +3 -3
  39. data/lib/barometer/translations/icao_country_codes.yml +20 -20
  40. data/lib/barometer/translations/weather_country_codes.yml +1 -1
  41. data/lib/barometer/translations/zone_codes.yml +2 -2
  42. data/lib/barometer/version.rb +3 -0
  43. data/lib/barometer/weather.rb +27 -27
  44. data/lib/barometer/weather_services/noaa.rb +314 -3
  45. data/lib/barometer/weather_services/service.rb +32 -30
  46. data/lib/barometer/weather_services/weather_bug.rb +35 -33
  47. data/lib/barometer/weather_services/wunderground.rb +31 -29
  48. data/lib/barometer/weather_services/yahoo.rb +36 -35
  49. data/lib/barometer/web_services/geocode.rb +5 -7
  50. data/lib/barometer/web_services/noaa_station_id.rb +53 -0
  51. data/lib/barometer/web_services/placemaker.rb +11 -13
  52. data/lib/barometer/web_services/timezone.rb +5 -7
  53. data/lib/barometer/web_services/weather_id.rb +4 -6
  54. data/lib/barometer/web_services/web_service.rb +4 -4
  55. data/spec/barometer_spec.rb +25 -27
  56. data/spec/cassettes/Barometer.json +1 -0
  57. data/spec/cassettes/Query.json +1 -0
  58. data/spec/cassettes/Query_Format_Coordinates.json +1 -0
  59. data/spec/cassettes/Query_Format_Geocode.json +1 -0
  60. data/spec/cassettes/Query_Format_WeatherID.json +1 -0
  61. data/spec/cassettes/Query_Format_WoeID.json +1 -0
  62. data/spec/cassettes/WeatherService.json +1 -0
  63. data/spec/cassettes/WeatherService_Noaa.json +1 -0
  64. data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
  65. data/spec/cassettes/WeatherService_Wunderground.json +1 -0
  66. data/spec/cassettes/WeatherService_Yahoo.json +1 -0
  67. data/spec/cassettes/WebService_Geocode.json +1 -0
  68. data/spec/cassettes/WebService_NoaaStation.json +1 -0
  69. data/spec/data/distance_spec.rb +60 -60
  70. data/spec/data/geo_spec.rb +23 -23
  71. data/spec/data/local_datetime_spec.rb +44 -44
  72. data/spec/data/local_time_spec.rb +47 -47
  73. data/spec/data/location_spec.rb +16 -16
  74. data/spec/data/pressure_spec.rb +61 -61
  75. data/spec/data/speed_spec.rb +69 -69
  76. data/spec/data/sun_spec.rb +25 -25
  77. data/spec/data/temperature_spec.rb +68 -68
  78. data/spec/data/units_spec.rb +21 -21
  79. data/spec/data/zone_spec.rb +35 -35
  80. data/spec/formats/coordinates_spec.rb +27 -27
  81. data/spec/formats/format_spec.rb +17 -25
  82. data/spec/formats/geocode_spec.rb +23 -31
  83. data/spec/formats/icao_spec.rb +26 -32
  84. data/spec/formats/postalcode_spec.rb +22 -28
  85. data/spec/formats/short_zipcode_spec.rb +20 -26
  86. data/spec/formats/weather_id_spec.rb +57 -67
  87. data/spec/formats/woe_id_spec.rb +59 -59
  88. data/spec/formats/zipcode_spec.rb +39 -47
  89. data/spec/key_file_parser_spec.rb +28 -0
  90. data/spec/measurements/measurement_spec.rb +79 -133
  91. data/spec/measurements/result_array_spec.rb +23 -38
  92. data/spec/measurements/result_spec.rb +100 -128
  93. data/spec/query_spec.rb +83 -100
  94. data/spec/spec_helper.rb +24 -6
  95. data/spec/weather_services/noaa_spec.rb +179 -0
  96. data/spec/weather_services/services_spec.rb +28 -36
  97. data/spec/weather_services/weather_bug_spec.rb +57 -77
  98. data/spec/weather_services/wunderground_spec.rb +36 -65
  99. data/spec/weather_services/yahoo_spec.rb +38 -60
  100. data/spec/weather_spec.rb +79 -79
  101. data/spec/web_services/geocode_spec.rb +7 -11
  102. data/spec/web_services/noaa_station_id_spec.rb +33 -0
  103. data/spec/web_services/placemaker_spec.rb +7 -12
  104. data/spec/web_services/web_services_spec.rb +3 -9
  105. metadata +214 -163
  106. data/VERSION.yml +0 -5
  107. data/lib/barometer/weather_services/google.rb +0 -142
  108. data/lib/barometer/weather_services/weather_dot_com.rb +0 -279
  109. data/spec/fakeweb_helper.rb +0 -179
  110. data/spec/fixtures/formats/weather_id/90210.xml +0 -7
  111. data/spec/fixtures/formats/weather_id/from_USGA0028.xml +0 -3
  112. data/spec/fixtures/formats/weather_id/ksfo.xml +0 -1
  113. data/spec/fixtures/formats/weather_id/manhattan.xml +0 -7
  114. data/spec/fixtures/formats/weather_id/new_york.xml +0 -1
  115. data/spec/fixtures/formats/weather_id/the_hills.xml +0 -1
  116. data/spec/fixtures/geocode/40_73_v3.json +0 -497
  117. data/spec/fixtures/geocode/90210_v3.json +0 -63
  118. data/spec/fixtures/geocode/T5B4M9_v3.json +0 -68
  119. data/spec/fixtures/geocode/atlanta_v3.json +0 -58
  120. data/spec/fixtures/geocode/calgary_ab_v3.json +0 -58
  121. data/spec/fixtures/geocode/ksfo_v3.json +0 -73
  122. data/spec/fixtures/geocode/newyork_ny_v3.json +0 -58
  123. data/spec/fixtures/services/google/calgary_ab.xml +0 -1
  124. data/spec/fixtures/services/placemaker/T5B4M9.xml +0 -65
  125. data/spec/fixtures/services/placemaker/atlanta.xml +0 -65
  126. data/spec/fixtures/services/placemaker/coords.xml +0 -65
  127. data/spec/fixtures/services/placemaker/ksfo.xml +0 -65
  128. data/spec/fixtures/services/placemaker/new_york.xml +0 -65
  129. data/spec/fixtures/services/placemaker/the_hills.xml +0 -65
  130. data/spec/fixtures/services/placemaker/w615702.xml +0 -47
  131. data/spec/fixtures/services/weather_bug/90210_current.xml +0 -93
  132. data/spec/fixtures/services/weather_bug/90210_forecast.xml +0 -76
  133. data/spec/fixtures/services/weather_dot_com/90210.xml +0 -1
  134. data/spec/fixtures/services/wunderground/current_calgary_ab.xml +0 -9
  135. data/spec/fixtures/services/wunderground/forecast_calgary_ab.xml +0 -13
  136. data/spec/fixtures/services/yahoo/90210.xml +0 -3
  137. data/spec/weather_services/google_spec.rb +0 -181
  138. 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