attack-barometer 0.5.0 → 0.6.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 (64) hide show
  1. data/README.rdoc +51 -9
  2. data/VERSION.yml +1 -1
  3. data/bin/barometer +57 -7
  4. data/lib/barometer/base.rb +3 -0
  5. data/lib/barometer/data/sun.rb +10 -0
  6. data/lib/barometer/data/zone.rb +79 -188
  7. data/lib/barometer/data.rb +11 -6
  8. data/lib/barometer/formats/coordinates.rb +4 -1
  9. data/lib/barometer/formats/geocode.rb +9 -7
  10. data/lib/barometer/formats/icao.rb +2 -2
  11. data/lib/barometer/formats/weather_id.rb +2 -2
  12. data/lib/barometer/measurements/common.rb +113 -0
  13. data/lib/barometer/{data → measurements}/current.rb +17 -42
  14. data/lib/barometer/measurements/forecast.rb +62 -0
  15. data/lib/barometer/measurements/forecast_array.rb +72 -0
  16. data/lib/barometer/{data → measurements}/measurement.rb +57 -45
  17. data/lib/barometer/measurements/night.rb +27 -0
  18. data/lib/barometer/query.rb +55 -5
  19. data/lib/barometer/services.rb +3 -1
  20. data/lib/barometer/translations/zone_codes.yml +360 -0
  21. data/lib/barometer/weather.rb +5 -4
  22. data/lib/barometer/weather_services/google.rb +19 -35
  23. data/lib/barometer/weather_services/service.rb +113 -255
  24. data/lib/barometer/weather_services/weather_bug.rb +291 -2
  25. data/lib/barometer/weather_services/weather_dot_com.rb +45 -54
  26. data/lib/barometer/weather_services/wunderground.rb +83 -89
  27. data/lib/barometer/weather_services/yahoo.rb +44 -91
  28. data/lib/barometer/web_services/geocode.rb +1 -0
  29. data/lib/barometer/web_services/timezone.rb +40 -0
  30. data/lib/barometer/web_services/weather_id.rb +17 -2
  31. data/lib/barometer.rb +11 -0
  32. data/lib/demometer/demometer.rb +28 -0
  33. data/lib/demometer/public/css/master.css +259 -1
  34. data/lib/demometer/views/index.erb +2 -0
  35. data/lib/demometer/views/layout.erb +3 -2
  36. data/lib/demometer/views/measurement.erb +4 -1
  37. data/lib/demometer/views/readme.erb +116 -88
  38. data/spec/data/sun_spec.rb +53 -0
  39. data/spec/data/zone_spec.rb +330 -100
  40. data/spec/fixtures/formats/weather_id/ksfo.xml +1 -0
  41. data/spec/fixtures/services/weather_bug/90210_current.xml +1 -0
  42. data/spec/fixtures/services/weather_bug/90210_forecast.xml +1 -0
  43. data/spec/formats/weather_id_spec.rb +10 -5
  44. data/spec/measurements/common_spec.rb +352 -0
  45. data/spec/{data → measurements}/current_spec.rb +40 -103
  46. data/spec/measurements/forecast_array_spec.rb +165 -0
  47. data/spec/measurements/forecast_spec.rb +135 -0
  48. data/spec/{data → measurements}/measurement_spec.rb +86 -107
  49. data/spec/measurements/night_measurement_spec.rb +49 -0
  50. data/spec/query_spec.rb +12 -2
  51. data/spec/spec_helper.rb +28 -1
  52. data/spec/weather_services/google_spec.rb +27 -117
  53. data/spec/weather_services/services_spec.rb +49 -1024
  54. data/spec/weather_services/weather_bug_spec.rb +274 -0
  55. data/spec/weather_services/weather_dot_com_spec.rb +45 -125
  56. data/spec/weather_services/wunderground_spec.rb +42 -136
  57. data/spec/weather_services/yahoo_spec.rb +26 -116
  58. data/spec/weather_spec.rb +45 -45
  59. metadata +23 -11
  60. data/lib/barometer/data/forecast.rb +0 -84
  61. data/lib/barometer/data/night.rb +0 -69
  62. data/lib/barometer/extensions/graticule.rb +0 -51
  63. data/spec/data/forecast_spec.rb +0 -192
  64. data/spec/data/night_measurement_spec.rb +0 -136
@@ -30,12 +30,14 @@ module Barometer
30
30
  :geocode => "Geocode"
31
31
  }
32
32
 
33
- attr_accessor :format, :q, :country_code, :geo
33
+ attr_accessor :format, :q, :country_code
34
+ attr_accessor :geo, :timezone, :conversions
34
35
 
35
36
  def initialize(query=nil)
36
37
  return unless query
37
38
  @q = query
38
39
  self.analyze!
40
+ @conversions = {}
39
41
  end
40
42
 
41
43
  # analyze the saved query to determine the format.
@@ -61,10 +63,16 @@ module Barometer
61
63
  raise ArgumentError unless (preferred_formats && preferred_formats.size > 0)
62
64
 
63
65
  # why convert if we are already there?
66
+ # (except in the case that the serivce excepts coordinates and we have a
67
+ # a geocode ... the google geocode results are superior)
68
+ #
64
69
  skip_conversion = false
65
- if preferred_formats.include?(@format.to_sym)
66
- skip_conversion = true
67
- converted_query = self.dup
70
+ unless (@format.to_sym == Query::Format::Geocode.format) &&
71
+ preferred_formats.include?(Query::Format::Coordinates.format)
72
+ if preferred_formats.include?(@format.to_sym)
73
+ skip_conversion = true
74
+ converted_query = self.dup
75
+ end
68
76
  end
69
77
 
70
78
  unless skip_conversion
@@ -78,11 +86,14 @@ module Barometer
78
86
  converted_query = Barometer::Query.new(@q)
79
87
  end
80
88
  unless converted
81
- converted_query = Query::Format.const_get(klass.to_s).to(self)
89
+ unless converted_query = get_conversion(preferred_format)
90
+ converted_query = Query::Format.const_get(klass.to_s).to(self)
91
+ end
82
92
  converted = true if converted_query
83
93
  end
84
94
  if converted
85
95
  converted_query.country_code ||= Query::Format.const_get(klass.to_s).country_code(converted_query.q)
96
+ post_conversion(converted_query)
86
97
  break
87
98
  end
88
99
  end
@@ -94,13 +105,52 @@ module Barometer
94
105
  if converted_query && converted_query.geo
95
106
  @geo = converted_query.geo
96
107
  else
108
+ puts "enhance geocode: #{converted_query.q}" if Barometer::debug?
97
109
  geo_query = Query::Format::Coordinates.to(converted_query)
98
110
  @geo = geo_query.geo if (geo_query && geo_query.geo)
111
+ converted_query.geo = @geo.dup
112
+ end
113
+ end
114
+
115
+ # enhance timezone?, unless we already did
116
+ #
117
+ if Barometer.enhance_timezone && !@timezone
118
+ if converted_query && converted_query.timezone
119
+ @geo = converted_query.timezone
120
+ elsif @geo && @geo.latitude && @geo.longitude
121
+ puts "enhance timezone: #{@geo.latitude}, #{@geo.longitude}" if Barometer::debug?
122
+ @timezone = WebService::Timezone.fetch(@geo.latitude,@geo.longitude)
123
+ converted_query.timezone = @timezone.dup
99
124
  end
100
125
  end
101
126
 
102
127
  converted_query
103
128
  end
104
129
 
130
+ # save the important parts of the conversion ... by saving conversion we
131
+ # can avoid doing the same conversion multiple times
132
+ #
133
+ def post_conversion(converted_query)
134
+ return unless (converted_query && converted_query.q && converted_query.format)
135
+ @conversions = {} unless @conversions
136
+ return if @conversions.has_key?(converted_query.format.to_sym)
137
+ puts "store: #{self.format} -> #{converted_query.format.to_sym} = #{self.q} -> #{converted_query.q}" if Barometer::debug?
138
+ @conversions[converted_query.format.to_sym] = converted_query.q
139
+ end
140
+
141
+ def get_conversion(format)
142
+ return nil unless format && @conversions
143
+ puts "found: #{self.format} -> #{format.to_sym} = #{self.q} -> #{@conversions[format.to_sym]}" if Barometer::debug? && @conversions.has_key?(format.to_sym)
144
+ # re-constuct converted query
145
+ if q = @conversions[format.to_sym]
146
+ converted_query = self.dup
147
+ converted_query.q = q
148
+ converted_query.format = format
149
+ converted_query
150
+ else
151
+ nil
152
+ end
153
+ end
154
+
105
155
  end
106
156
  end
@@ -7,10 +7,12 @@ require 'weather_services/wunderground'
7
7
  require 'weather_services/google'
8
8
  require 'weather_services/yahoo'
9
9
  require 'weather_services/weather_dot_com'
10
+ require 'weather_services/weather_bug'
10
11
 
11
12
  #
12
13
  # web services (non weather)
13
14
  #
14
15
  require 'web_services/web_service'
15
16
  require 'web_services/geocode'
16
- require 'web_services/weather_id'
17
+ require 'web_services/weather_id'
18
+ require 'web_services/timezone'
@@ -0,0 +1,360 @@
1
+ # first term - time zone short code
2
+ # second term - UTC offset (- or +)
3
+ #
4
+ A : 1
5
+ ACDT : 10.5
6
+ ACST : 9.5
7
+ ADT : -3
8
+ AEDT : 11
9
+
10
+ AEST : 10
11
+ AFT : 4.5
12
+ AHDT : -9
13
+ AHST : -10
14
+ AKDT : -8
15
+ AKST : -9
16
+ AMST : 5
17
+ AMT : 4
18
+ ANAST : 13
19
+ ANAT : 12
20
+ ART : -3
21
+ AST : -4
22
+ AT : -1
23
+ AWDT : 9
24
+ AWST : 8
25
+ AZOST : 0
26
+ AZOT : -1
27
+ AZST : 5
28
+ AZT : 4
29
+
30
+ B : 2
31
+ BADT : 4
32
+ BAT : 6
33
+ BDST : 2
34
+ BDT : 6
35
+ BET : -11
36
+ BNT : 8
37
+ BORT : 8
38
+ BOT : -4
39
+ BRA : -3
40
+ BST : 1
41
+ BT : 6
42
+ BTT : 6
43
+
44
+ C : 3
45
+ CAT : 2
46
+ CCT : 8
47
+ CEST : 2
48
+ CET : 1
49
+ CHADT : 13.75
50
+ CHAST : 12.75
51
+ CHST : 10
52
+ CKT : -10
53
+ CLST : -3
54
+ CLT : -4
55
+ COT : -5
56
+ CUT : 0
57
+ CVT : -1
58
+ CWT : 8.75
59
+ CXT : 7
60
+ CEDT : 2
61
+
62
+ D : 4
63
+ DAVT : 7
64
+ DDUT : 10
65
+ DNT : 1
66
+ DST : 2
67
+
68
+ E : 5
69
+ EASST : -5
70
+ EAST : -6
71
+ EAT : 3
72
+ ECT : -5
73
+ EEST : 3
74
+ EET : 2
75
+ EGST : 0
76
+ EGT : -1
77
+ EMT : 1
78
+ EEDT : 3
79
+
80
+ F : 6
81
+ FDT : -1
82
+ FJST : 13
83
+ FJT : 12
84
+ FKST : -3
85
+ FKT : -4
86
+ FST : 2
87
+ FWT : 1
88
+
89
+ G : 7
90
+ GALT : -6
91
+ GAMT : -9
92
+ GEST : 5
93
+ GET : 4
94
+ GFT : -3
95
+ GILT : 12
96
+ GST : 4
97
+ GT : 0
98
+ GYT : -4
99
+ GZ : 0
100
+
101
+ H : 8
102
+ HAA : -3
103
+ HAC : -5
104
+ HADT : -9
105
+ HAE : -4
106
+ HAP : -7
107
+ HAR : -6
108
+ HAST : -10
109
+ HAT : -2.5
110
+ HAY : -8
111
+ HDT : -9.5
112
+ HFE : 2
113
+ HFH : 1
114
+ HG : 0
115
+ HKT : 8
116
+ HNA : -4
117
+ HNC : -6
118
+ HNE : -5
119
+ HNP : -8
120
+ HNR : -7
121
+ HNT : -3.5
122
+ HNY : -9
123
+ HOE : 1
124
+ HST : -10
125
+
126
+ I : 9
127
+ ICT : 4
128
+ IDLE : 12
129
+ IDLW : -12
130
+ IDT : 1
131
+ IOT : 5
132
+ IRDT : 4.5
133
+ IRKST : 9
134
+ IRKT : 8
135
+ IRST : 3.5
136
+ IRT : 3.5
137
+ IST : 1
138
+ IT : 3.5
139
+ ITA : 1
140
+
141
+ JAVT : 7
142
+ JAYT : 9
143
+ JFDT : -3
144
+ JFST : -4
145
+ JST : 9
146
+ JT : 7
147
+
148
+ K : 10
149
+ KDT : 10
150
+ KGST : 6
151
+ KGT : 5
152
+ KOST : 12
153
+ KOVT : 7
154
+ KOVST : 8
155
+ KRAST : 8
156
+ KRAT : 7
157
+ KST : 9
158
+
159
+ L : 11
160
+ LHDT : 11
161
+ LHST : 10.5
162
+ LIGT : 10
163
+ LINT : 14
164
+ LKT : 6
165
+ LST : 1
166
+
167
+ M : 12
168
+ MAGST : 12
169
+ MAGT : 11
170
+ MAL : 8
171
+ MART : -9.5
172
+ MAT : 3
173
+ MAWT : 6
174
+ MBT : 8
175
+ MED : 2
176
+ MEDST : 2
177
+ MEST : 2
178
+ MESZ : 2
179
+ MET : 1
180
+ MEWT : 1
181
+ MEX : -6
182
+ MEZ : 1
183
+ MHT : 12
184
+ MIT : 9.5
185
+ MMT : 6.5
186
+ MNT : 8
187
+ MNST : 9
188
+ MPT : 10
189
+ MSD : 4
190
+ MSK : 3
191
+ MSKS : 4
192
+ MT : 8.5
193
+ MUT : 4
194
+ MUST : 5
195
+ MVT : 5
196
+ MYT : 8
197
+ MFPT : -10
198
+
199
+ N : -1
200
+ NCT : 11
201
+ NDT : -2.5
202
+ NFT : 11.5
203
+ NOR : 1
204
+ NOVST : 7
205
+ NOVT : 6
206
+ NPT : 5.75
207
+ NRT : 12
208
+ NST : -3.5
209
+ NSUT : 6.5
210
+ NT : -11
211
+ NUT : -11
212
+ NZDT : 13
213
+ NZST : 12
214
+ NZT : 12
215
+
216
+ O : -2
217
+ OESZ : 3
218
+ OEZ : 2
219
+ OMSK : 7
220
+ OMSST : 7
221
+ OMST : 6
222
+
223
+ P : -3
224
+ PET : -5
225
+ PETST : 13
226
+ PETT : 12
227
+ PGT : 10
228
+ PHOT : 13
229
+ PHT : 8
230
+ PIT : 8
231
+ PKT : 5
232
+ PKST : 6
233
+ PMDT : -2
234
+ PMST : -3
235
+ PMT : -3
236
+ PNT : -8.5
237
+ PONT : 11
238
+ PYST : -3
239
+ PYT : -4
240
+ PWT : 9
241
+
242
+ Q : -4
243
+
244
+ R : -5
245
+ R1T : 2
246
+ R2T : 3
247
+ RET : 4
248
+ ROK : 9
249
+ ROTT : -3
250
+
251
+ S : -6
252
+ SADT : 10.5
253
+ SAMST : 5
254
+ SAMT : 4
255
+ SAST : 2
256
+ SBT : 11
257
+ SCT : 4
258
+ SCDT : 13
259
+ SCST : 12
260
+ SET : 1
261
+ SGT : 8
262
+ SIT : 8
263
+ SLT : -4
264
+ SLST : -3
265
+ SRT : -3
266
+ SST : -11
267
+ SYST : 3
268
+ SWT : 1
269
+ SYT : 2
270
+
271
+ T : -7
272
+ TAHT : -10
273
+ TFT : 5
274
+ THA : 7
275
+ THAT : -10
276
+ TJT : 5
277
+ TKT : -10
278
+ TMT : 5
279
+ TOT : 13
280
+ TRUK : 10
281
+ TPT : 9
282
+ TRUT : 10
283
+ TST : 3
284
+ TUC : 0
285
+ TVT : 12
286
+ TWT : 8
287
+
288
+ U : -8
289
+ ULAST : 9
290
+ ULAT : 8
291
+ USZ1 : 2
292
+ USZ1S : 3
293
+ USZ3 : 4
294
+ USZ3S : 5
295
+ USZ4 : 5
296
+ USZ4S : 6
297
+ USZ5 : 6
298
+ USZ5S : 7
299
+ USZ6 : 7
300
+ USZ6S : 8
301
+ USZ7 : 8
302
+ USZ7S : 9
303
+ USZ8 : 9
304
+ USZ8S : 10
305
+ USZ9 : 10
306
+ USZ9S : 11
307
+ UTZ : -3
308
+ UYT : -3
309
+ UYST : -2
310
+ UZ10 : 11
311
+ UZ10S : 12
312
+ UZ11 : 12
313
+ UZ11S : 13
314
+ UZ12 : 12
315
+ UZ12S : 13
316
+ UZT : 5
317
+
318
+ V : -9
319
+ VET : -4.5
320
+ VLAST : 11
321
+ VLAT : 10
322
+ VOST : 6
323
+ VST : -4.5
324
+ VTZ : -2
325
+ VUT : 11
326
+
327
+ W : -10
328
+ WAKT : 12
329
+ WAST : 2
330
+ WAT : 1
331
+ WCT : 8.75
332
+ WEST : 1
333
+ WESZ : 1
334
+ WET : 0
335
+ WEZ : 0
336
+ WFT : 12
337
+ WGST : -2
338
+ WGT : -3
339
+ WIB : 7
340
+ WITA : 8
341
+ WIT : 9
342
+ WST : 8
343
+ WKST : 5
344
+ WTZ : -1
345
+ WUT : 1
346
+ WEDT : 1
347
+ WDT : 9
348
+
349
+ X : -11
350
+
351
+ Y : -12
352
+ YAKST : 10
353
+ YAKT : 9
354
+ YAPT : 10
355
+ YDT : -8
356
+ YEKST : 6
357
+ YEKT : 5
358
+ YST : -9
359
+
360
+ Z : 0
@@ -8,6 +8,7 @@ module Barometer
8
8
  class Weather
9
9
 
10
10
  attr_accessor :measurements
11
+ attr_accessor :start_at, :end_at
11
12
 
12
13
  def initialize; @measurements = []; end
13
14
 
@@ -139,7 +140,7 @@ module Barometer
139
140
  # pass the question on to each successful measurement until we get an answer
140
141
  #
141
142
 
142
- def windy?(threshold=10, time_string=nil)
143
+ def windy?(time_string=nil, threshold=10)
143
144
  local_datetime = Data::LocalDateTime.parse(time_string)
144
145
  raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
145
146
  raise ArgumentError unless (local_datetime.nil? || local_datetime.is_a?(Data::LocalDateTime))
@@ -147,14 +148,14 @@ module Barometer
147
148
  is_windy = nil
148
149
  @measurements.each do |measurement|
149
150
  if measurement.success?
150
- is_windy = measurement.windy?(threshold, local_datetime)
151
+ is_windy = measurement.windy?(local_datetime, threshold)
151
152
  return is_windy if !is_windy.nil?
152
153
  end
153
154
  end
154
155
  is_windy
155
156
  end
156
157
 
157
- def wet?(threshold=50, time_string=nil)
158
+ def wet?(time_string=nil, threshold=50)
158
159
  local_datetime = Data::LocalDateTime.parse(time_string)
159
160
  raise ArgumentError unless (threshold.is_a?(Fixnum) || threshold.is_a?(Float))
160
161
  raise ArgumentError unless (local_datetime.nil? || local_datetime.is_a?(Data::LocalDateTime))
@@ -162,7 +163,7 @@ module Barometer
162
163
  is_wet = nil
163
164
  @measurements.each do |measurement|
164
165
  if measurement.success?
165
- is_wet = measurement.wet?(threshold, local_datetime)
166
+ is_wet = measurement.wet?(local_datetime, threshold)
166
167
  return is_wet if !is_wet.nil?
167
168
  end
168
169
  end
@@ -35,43 +35,25 @@ module Barometer
35
35
  #
36
36
  class WeatherService::Google < WeatherService
37
37
 
38
- def self.source_name; :google; end
39
- def self.accepted_formats; [:zipcode, :postalcode, :geocode]; end
38
+ #########################################################################
39
+ # PRIVATE
40
+ # If class methods could be private, the remaining methods would be.
41
+ #
40
42
 
41
- def self.wet_icon_codes
43
+ def self._source_name; :google; end
44
+ def self._accepted_formats; [:zipcode, :postalcode, :geocode]; end
45
+
46
+ def self._wet_icon_codes
42
47
  %w(rain chance_of_rain chance_of_storm thunderstorm mist)
43
48
  end
44
- def self.sunny_icon_codes
49
+ def self._sunny_icon_codes
45
50
  %w(sunny mostly_sunny partly_cloudy)
46
51
  end
47
-
48
- def self._measure(measurement, query, metric=true)
49
- raise ArgumentError unless measurement.is_a?(Data::Measurement)
50
- raise ArgumentError unless query.is_a?(Barometer::Query)
51
- measurement.source = self.source_name
52
-
53
- begin
54
- result = self.get_all(query.q, metric)
55
- rescue Timeout::Error => e
56
- return measurement
57
- end
58
-
59
- measurement.current = self.build_current(result, metric)
60
- measurement.forecast = self.build_forecast(result, metric)
61
- measurement.location = self.build_location(query.geo)
62
- measurement
63
- end
64
52
 
65
- def self.build_current(data, metric=true)
53
+ def self._build_current(data, metric=true)
66
54
  raise ArgumentError unless data.is_a?(Hash)
67
- current = Data::CurrentMeasurement.new
55
+ current = Measurement::Current.new
68
56
 
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
74
-
75
57
  if data['current_conditions']
76
58
  data = data['current_conditions']
77
59
  if data['icon']
@@ -96,10 +78,10 @@ module Barometer
96
78
  current
97
79
  end
98
80
 
99
- def self.build_forecast(data, metric=true)
81
+ def self._build_forecast(data, metric=true)
100
82
  raise ArgumentError unless data.is_a?(Hash)
101
83
 
102
- forecasts = []
84
+ forecasts = Measurement::ForecastArray.new
103
85
  return forecasts unless data && data['forecast_information'] &&
104
86
  data['forecast_information']['forecast_date']
105
87
  start_date = Date.parse(data['forecast_information']['forecast_date']['data'])
@@ -108,7 +90,7 @@ module Barometer
108
90
  # go through each forecast and create an instance
109
91
  d = 0
110
92
  data.each do |forecast|
111
- forecast_measurement = Data::ForecastMeasurement.new
93
+ forecast_measurement = Measurement::Forecast.new
112
94
  if forecast['icon']
113
95
  icon_match = forecast['icon']['data'].match(/.*\/([A-Za-z_]*)\.png/)
114
96
  forecast_measurement.icon = icon_match[1] if icon_match
@@ -130,7 +112,7 @@ module Barometer
130
112
  forecasts
131
113
  end
132
114
 
133
- def self.build_location(geo=nil)
115
+ def self._build_location(result=nil, geo=nil)
134
116
  raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
135
117
  location = Data::Location.new
136
118
  if geo
@@ -145,10 +127,12 @@ module Barometer
145
127
  end
146
128
 
147
129
  # use HTTParty to get the current weather
148
- def self.get_all(query, metric=true)
130
+ def self._fetch(query, metric=true)
131
+ return unless query
132
+ puts "fetch google: #{query.q}" if Barometer::debug?
149
133
  self.get(
150
134
  "http://google.com/ig/api",
151
- :query => {:weather => query, :hl => (metric ? "en-GB" : "en-US")},
135
+ :query => {:weather => query.q, :hl => (metric ? "en-GB" : "en-US")},
152
136
  :format => :xml,
153
137
  :timeout => Barometer.timeout
154
138
  )['xml_api_reply']['weather']