attack-barometer 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -46,72 +46,63 @@ module Barometer
46
46
  #
47
47
  class WeatherService::Wunderground < WeatherService
48
48
 
49
- def self.source_name; :wunderground; end
50
- def self.accepted_formats
49
+ #########################################################################
50
+ # PRIVATE
51
+ # If class methods could be private, the remaining methods would be.
52
+ #
53
+
54
+ def self._source_name; :wunderground; end
55
+ def self._accepted_formats
51
56
  [:zipcode, :postalcode, :icao, :coordinates, :geocode]
52
57
  end
53
58
 
54
59
  # these are the icon codes that indicate "wet", used by wet? function
55
- def self.wet_icon_codes
60
+ def self._wet_icon_codes
56
61
  %w(flurries rain sleet snow tstorms nt_flurries nt_rain nt_sleet nt_snow nt_tstorms chancerain chancetstorms)
57
62
  end
58
63
  # these are the icon codes that indicate "sun", used by sunny? function
59
- def self.sunny_icon_codes
64
+ def self._sunny_icon_codes
60
65
  %w(clear mostlysunny partlysunny sunny partlycloudy)
61
66
  end
62
67
 
63
- def self._measure(measurement, query, metric=true)
64
- raise ArgumentError unless measurement.is_a?(Data::Measurement)
65
- raise ArgumentError unless query.is_a?(Barometer::Query)
66
- measurement.source = self.source_name
67
-
68
- begin
69
- current_result = self.get_current(query.q)
70
- measurement.current = self.build_current(current_result, metric)
71
- rescue Timeout::Error => e
72
- return measurement
73
- end
74
-
75
- begin
76
- forecast_result = self.get_forecast(query.q)
77
- measurement.forecast = self.build_forecast(forecast_result, metric)
78
- rescue Timeout::Error => e
79
- return measurement
80
- end
81
-
82
- measurement.location = self.build_location(current_result)
83
- measurement.station = self.build_station(current_result)
84
- measurement.timezone = self.build_timezone(forecast_result)
85
-
86
- if current_result["credit"] && current_result["credit_URL"]
87
- measurement.links[current_result["credit"]] = current_result["credit_URL"]
88
- end
89
-
90
- sun = nil
91
- if measurement.current
92
- sun = self.build_sun(forecast_result, measurement.timezone)
93
- measurement.current.sun = sun
94
- end
68
+ def self._build_extra(measurement, result, metric=true)
69
+ #raise ArgumentError unless measurement.is_a?(Data::Measurement)
70
+ #raise ArgumentError unless query.is_a?(Barometer::Query)
71
+
95
72
  # use todays sun data for all future days
96
- if measurement.forecast && sun
73
+ if measurement.forecast && measurement.current.sun
97
74
  measurement.forecast.each do |forecast|
98
- forecast.sun = sun
75
+ forecast.sun = measurement.current.sun
99
76
  end
100
77
  end
101
78
 
102
- local_time = measurement.timezone ? Data::LocalTime.parse(
103
- measurement.timezone.utc_to_local(Time.now.utc)
104
- ) : nil
105
- measurement.measured_at = local_time
106
- measurement.current.current_at = local_time
107
-
108
79
  measurement
109
80
  end
81
+
82
+ def self._parse_full_timezone(data)
83
+ raise ArgumentError unless data.is_a?(Hash)
84
+ if data && data['simpleforecast'] &&
85
+ data['simpleforecast']['forecastday'] &&
86
+ data['simpleforecast']['forecastday'].first &&
87
+ data['simpleforecast']['forecastday'].first['date']
88
+ Data::Zone.new(
89
+ data['simpleforecast']['forecastday'].first['date']['tz_long']
90
+ )
91
+ end
92
+ end
110
93
 
111
- def self.build_current(data, metric=true)
94
+ def self._build_links(data)
95
+ links = {}
96
+ if data["credit"] && data["credit_URL"]
97
+ links[data["credit"]] = data["credit_URL"]
98
+ end
99
+ links
100
+ end
101
+
102
+ def self._build_current(data, metric=true)
112
103
  raise ArgumentError unless data.is_a?(Hash)
113
104
 
114
- current = Data::CurrentMeasurement.new
105
+ current = Measurement::Current.new
115
106
  current.updated_at = Data::LocalDateTime.parse(data['observation_time']) if data['observation_time']
116
107
  current.humidity = data['relative_humidity'].to_i
117
108
  current.icon = data['icon'] if data['icon']
@@ -142,15 +133,15 @@ module Barometer
142
133
  current
143
134
  end
144
135
 
145
- def self.build_forecast(data, metric=true)
136
+ def self._build_forecast(data, metric=true)
146
137
  raise ArgumentError unless data.is_a?(Hash)
147
- forecasts = []
138
+ forecasts = Measurement::ForecastArray.new
148
139
  # go through each forecast and create an instance
149
140
  if data && data['simpleforecast'] &&
150
141
  data['simpleforecast']['forecastday']
151
142
 
152
143
  data['simpleforecast']['forecastday'].each do |forecast|
153
- forecast_measurement = Data::ForecastMeasurement.new
144
+ forecast_measurement = Measurement::Forecast.new
154
145
  forecast_measurement.icon = forecast['icon']
155
146
  forecast_measurement.date = Date.parse(forecast['date']['pretty'])
156
147
  forecast_measurement.pop = forecast['pop'].to_i
@@ -166,8 +157,8 @@ module Barometer
166
157
  end
167
158
  forecasts
168
159
  end
169
-
170
- def self.build_location(data)
160
+
161
+ def self._build_location(data, geo=nil)
171
162
  raise ArgumentError unless data.is_a?(Hash)
172
163
  location = Data::Location.new
173
164
  if data['display_location']
@@ -183,7 +174,7 @@ module Barometer
183
174
  location
184
175
  end
185
176
 
186
- def self.build_station(data)
177
+ def self._build_station(data)
187
178
  raise ArgumentError unless data.is_a?(Hash)
188
179
  station = Data::Location.new
189
180
  station.id = data['station_id']
@@ -200,69 +191,72 @@ module Barometer
200
191
  station
201
192
  end
202
193
 
203
- def self.build_timezone(data)
204
- raise ArgumentError unless data.is_a?(Hash)
205
- timezone = nil
206
- if data && data['simpleforecast'] &&
207
- data['simpleforecast']['forecastday'] &&
208
- data['simpleforecast']['forecastday'].first &&
209
- data['simpleforecast']['forecastday'].first['date']
210
- timezone = Data::Zone.new(
211
- data['simpleforecast']['forecastday'].first['date']['tz_long']
212
- )
213
- end
214
- timezone || Data::Zone.new(nil)
215
- end
216
-
217
- def self.build_sun(data, timezone)
194
+ def self._build_sun(data)
218
195
  raise ArgumentError unless data.is_a?(Hash)
219
- raise ArgumentError unless timezone.is_a?(Data::Zone)
220
196
  sun = nil
221
197
  if data
222
198
  if data['moon_phase']
223
- if data['moon_phase']['sunrise']
224
- rise = Data::LocalTime.new(
225
- data['moon_phase']['sunrise']['hour'].to_i,
226
- data['moon_phase']['sunrise']['minute'].to_i
227
- )
228
- end
229
- if data['moon_phase']['sunset']
230
- set = Data::LocalTime.new(
231
- data['moon_phase']['sunset']['hour'].to_i,
232
- data['moon_phase']['sunset']['minute'].to_i
233
- )
234
- end
235
-
236
- sun = Data::Sun.new(
237
- rise,
238
- set
239
- )
199
+ rise = Data::LocalTime.new(
200
+ data['moon_phase']['sunrise']['hour'].to_i,
201
+ data['moon_phase']['sunrise']['minute'].to_i
202
+ ) if data['moon_phase']['sunrise']
203
+ set = Data::LocalTime.new(
204
+ data['moon_phase']['sunset']['hour'].to_i,
205
+ data['moon_phase']['sunset']['minute'].to_i
206
+ ) if data['moon_phase']['sunset']
207
+ sun = Data::Sun.new(rise,set)
240
208
  end
241
209
  end
242
210
  sun || Data::Sun.new
243
211
  end
244
212
 
213
+ # override default _fetch behavior
214
+ # this service requires TWO seperate http requests (one for current
215
+ # and one for forecasted weather) ... combine the results
216
+ #
217
+ def self._fetch(query, metric=true)
218
+ result = []
219
+ result << _fetch_current(query)
220
+ result << _fetch_forecast(query)
221
+ result
222
+ end
223
+
245
224
  # use HTTParty to get the current weather
246
- def self.get_current(query)
225
+ #
226
+ def self._fetch_current(query)
247
227
  return unless query
228
+ puts "fetch wunderground current: #{query.q}" if Barometer::debug?
248
229
  self.get(
249
230
  "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml",
250
- :query => {:query => query},
231
+ :query => {:query => query.q},
251
232
  :format => :xml,
252
233
  :timeout => Barometer.timeout
253
234
  )['current_observation']
254
235
  end
255
236
 
256
237
  # use HTTParty to get the forecasted weather
257
- def self.get_forecast(query)
238
+ #
239
+ def self._fetch_forecast(query)
258
240
  return unless query
241
+ puts "fetch wunderground forecast: #{query.q}" if Barometer::debug?
259
242
  self.get(
260
243
  "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml",
261
- :query => {:query => query},
244
+ :query => {:query => query.q},
262
245
  :format => :xml,
263
246
  :timeout => Barometer.timeout
264
247
  )['forecast']
265
248
  end
266
249
 
250
+ # since we have two sets of data, override these calls to choose the
251
+ # right set of data
252
+ #
253
+ def self._current_result(data); data[0]; end
254
+ def self._forecast_result(data=nil); data[1]; end
255
+ def self._location_result(data=nil); data[0]; end
256
+ def self._station_result(data=nil); data[0]; end
257
+ def self._links_result(data=nil); data[0]; end
258
+ def self._sun_result(data=nil); data[1]; end
259
+ def self._timezone_result(data=nil); data[1]; end
260
+
267
261
  end
268
262
  end
@@ -45,103 +45,54 @@ module Barometer
45
45
  #
46
46
  class WeatherService::Yahoo < WeatherService
47
47
 
48
- def self.source_name; :yahoo; end
49
- def self.accepted_formats; [:zipcode, :weather_id]; end
48
+ #########################################################################
49
+ # PRIVATE
50
+ # If class methods could be private, the remaining methods would be.
51
+ #
50
52
 
51
- # these are the icon codes that indicate "wet", used by wet? function
52
- def self.wet_icon_codes
53
+ def self._source_name; :yahoo; end
54
+ def self._accepted_formats; [:zipcode, :weather_id]; end
55
+
56
+ def self._wet_icon_codes
53
57
  codes = [1] + (3..18).to_a + [35] + (37..43).to_a + (45..47).to_a
54
58
  codes.collect {|c| c.to_s}
55
59
  end
56
- def self.sunny_icon_codes
60
+ def self._sunny_icon_codes
57
61
  codes = (29..34).to_a + [36]
58
62
  codes.collect {|c| c.to_s}
59
63
  end
60
-
61
- def self._measure(measurement, query, metric=true)
62
- raise ArgumentError unless measurement.is_a?(Data::Measurement)
63
- raise ArgumentError unless query.is_a?(Barometer::Query)
64
- measurement.source = self.source_name
65
-
66
- begin
67
- result = self.fetch(query.q, metric)
68
- rescue Timeout::Error => e
69
- return measurement
70
- end
71
-
72
- measurement.current = self.build_current(result, metric)
73
- measurement.forecast = self.build_forecast(result, metric)
74
- measurement.location = self.build_location(result, query.geo)
75
-
76
- if result["title"] && result["link"]
77
- measurement.links[result["title"]] = result["link"]
78
- end
79
-
80
- sun = nil
81
- if measurement.current
82
- sun = self.build_sun(result)
83
- measurement.current.sun = sun
84
- end
85
- # use todays sun data for all future days
86
- if measurement.forecast && sun
87
- measurement.forecast.each do |forecast|
88
- forecast.sun = sun
89
- end
90
- end
91
-
92
- local_time = self.build_local_time(result)
93
- if local_time
94
- measurement.measured_at = local_time
95
- measurement.current.current_at = local_time
64
+
65
+ def self._build_extra(measurement, result, metric=true)
66
+ #raise ArgumentError unless measurement.is_a?(Data::Measurement)
67
+ #raise ArgumentError unless query.is_a?(Barometer::Query)
68
+
69
+ # use todays sun data for all future days
70
+ if measurement.forecast && measurement.current.sun
71
+ measurement.forecast.each do |forecast|
72
+ forecast.sun = measurement.current.sun
73
+ end
74
+ end
75
+ measurement
76
+ end
77
+
78
+ def self._build_timezone(data)
79
+ if data && data['item'] && data['item']['pubDate']
80
+ zone_match = data['item']['pubDate'].match(/ ([A-Z]*)$/)
81
+ Data::Zone.new(zone_match[1]) if zone_match
96
82
  end
97
-
98
- measurement
99
83
  end
100
84
 
101
- def self.build_local_time(data)
102
- if data
103
- if data['item']
104
- # what time is it now?
105
- now_utc = Time.now.utc
106
-
107
- # get published date
108
- pub_date = data['item']['pubDate']
109
-
110
- # get the TIME ZONE CODE
111
- zone_match = pub_date.match(/ ([A-Z]*)$/) if pub_date
112
-
113
- if zone_match
114
- zone = zone_match[1]
115
-
116
- # try converting pub_date to utc
117
- # pub_date_utc = Data::Zone.code_to_utc(Time.parse(pub_date), zone) if zone
118
-
119
- # how far back was this?
120
- # data_age_in_seconds = now_utc - pub_date_utc
121
-
122
- # is this older then 2 hours
123
- # if (data_age_in_seconds < 0) || (data_age_in_seconds > (60 * 60 * 2))
124
- # we may have converted the time wrong.
125
- # if pub_date in the future, then?
126
- # if pub_date too far back, then?
127
-
128
- # for now do nothing ... don't set measured_time
129
- # return nil
130
- # else
131
- # everything seems fine
132
- # convert now to the local time
133
- offset = Data::Zone.zone_to_offset(zone)
134
- return Data::LocalTime.parse(now_utc + offset)
135
- # end
85
+ def self._build_links(data)
86
+ links = {}
87
+ if data["title"] && data["link"]
88
+ links[data["title"]] = data["link"]
136
89
  end
137
- nil
90
+ links
138
91
  end
139
- end
140
- end
141
92
 
142
- def self.build_current(data, metric=true)
93
+ def self._build_current(data, metric=true)
143
94
  raise ArgumentError unless data.is_a?(Hash)
144
- current = Data::CurrentMeasurement.new
95
+ current = Measurement::Current.new(metric)
145
96
  if data
146
97
  if data['item'] && data['item']['yweather:condition']
147
98
  condition_result = data['item']['yweather:condition']
@@ -171,15 +122,15 @@ end
171
122
  current
172
123
  end
173
124
 
174
- def self.build_forecast(data, metric=true)
125
+ def self._build_forecast(data, metric=true)
175
126
  raise ArgumentError unless data.is_a?(Hash)
176
- forecasts = []
127
+ forecasts = Measurement::ForecastArray.new
177
128
 
178
129
  if data && data['item'] && data['item']['yweather:forecast']
179
130
  forecast_result = data['item']['yweather:forecast']
180
131
 
181
132
  forecast_result.each do |forecast|
182
- forecast_measurement = Data::ForecastMeasurement.new
133
+ forecast_measurement = Measurement::Forecast.new
183
134
  forecast_measurement.icon = forecast['code']
184
135
  forecast_measurement.date = Date.parse(forecast['date'])
185
136
  forecast_measurement.condition = forecast['text']
@@ -193,7 +144,7 @@ end
193
144
  forecasts
194
145
  end
195
146
 
196
- def self.build_location(data, geo=nil)
147
+ def self._build_location(data, geo=nil)
197
148
  raise ArgumentError unless data.is_a?(Hash)
198
149
  raise ArgumentError unless (geo.nil? || geo.is_a?(Data::Geo))
199
150
  location = Data::Location.new
@@ -219,7 +170,7 @@ end
219
170
  location
220
171
  end
221
172
 
222
- def self.build_sun(data)
173
+ def self._build_sun(data)
223
174
  raise ArgumentError unless data.is_a?(Hash)
224
175
  sun = nil
225
176
  if data && data['yweather:astronomy'] && data['item']
@@ -229,12 +180,14 @@ end
229
180
  end
230
181
  sun || Data::Sun.new
231
182
  end
232
-
183
+
233
184
  # use HTTParty to get the current weather
234
- def self.fetch(query, metric=true)
185
+ def self._fetch(query, metric=true)
186
+ return unless query
187
+ puts "fetch yahoo: #{query.q}" if Barometer::debug?
235
188
  self.get(
236
189
  "http://weather.yahooapis.com/forecastrss",
237
- :query => {:p => query, :u => (metric ? 'c' : 'f')},
190
+ :query => {:p => query.q, :u => (metric ? 'c' : 'f')},
238
191
  :format => :xml,
239
192
  :timeout => Barometer.timeout
240
193
  )['rss']['channel']
@@ -8,6 +8,7 @@ module Barometer
8
8
 
9
9
  def self.fetch(query)
10
10
  raise ArgumentError unless _is_a_query?(query)
11
+ puts "geocoding: #{query.q}" if Barometer::debug?
11
12
  return nil unless _has_geocode_key?
12
13
  location = self.get(
13
14
  "http://maps.google.com/maps/geo",
@@ -0,0 +1,40 @@
1
+ module Barometer
2
+ #
3
+ # Web Service: Timezone
4
+ #
5
+ # uses geonames.org to obtain the full timezone for given coordinates
6
+ #
7
+ class WebService::Timezone < WebService
8
+
9
+ # get the full timezone for given coordinates
10
+ #
11
+ def self.fetch(latitude, longitude)
12
+ puts "timezone: #{latitude}, #{longitude}"
13
+ return nil unless latitude && longitude
14
+ _fetch_via_wunderground(latitude, longitude)
15
+ end
16
+
17
+ def self._fetch_via_geonames(latitude, longitude)
18
+ response = self.get(
19
+ "http://ws.geonames.org/timezone",
20
+ :query => { :lat => latitude, :lng => longitude },
21
+ :format => :xml,
22
+ :timeout => Barometer.timeout
23
+ )['geonames']['timezone']
24
+ response ? Data::Zone.new(response['timezoneId']) : nil
25
+ end
26
+
27
+ def self._fetch_via_wunderground(latitude, longitude)
28
+ response = self.get(
29
+ "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml",
30
+ :query => {:query => "#{latitude},#{longitude}"},
31
+ :format => :xml,
32
+ :timeout => Barometer.timeout
33
+ )['forecast']['simpleforecast']['forecastday'].first
34
+ response ? Data::Zone.new(response['date']['tz_long']) : nil
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+
@@ -9,11 +9,13 @@ module Barometer
9
9
  # get the weather_id for a given query
10
10
  #
11
11
  def self.fetch(query)
12
+ puts "fetch weather_id: #{query.q}" if Barometer::debug?
12
13
  return nil unless query
13
14
  raise ArgumentError unless _is_a_query?(query)
14
- response = self.get(
15
+
16
+ self.get(
15
17
  "http://xoap.weather.com/search/search",
16
- :query => { :where => query.q }, :format => :plain,
18
+ :query => { :where => _adjust_query(query.q) }, :format => :plain,
17
19
  :timeout => Barometer.timeout
18
20
  )
19
21
  end
@@ -21,6 +23,7 @@ module Barometer
21
23
  # get the location_date (geocode) for a given weather_id
22
24
  #
23
25
  def self.reverse(query)
26
+ puts "reverse weather_id: #{query.q}" if Barometer::debug?
24
27
  return nil unless query
25
28
  raise ArgumentError unless _is_a_query?(query)
26
29
  self.get(
@@ -30,6 +33,18 @@ module Barometer
30
33
  :timeout => Barometer.timeout
31
34
  )['rss']['channel']["yweather:location"]
32
35
  end
36
+
37
+ # filter out words that weather.com has trouble geo-locating
38
+ # mostly these are icao related
39
+ #
40
+ def self._adjust_query(query)
41
+ output = query.dup
42
+ words_to_remove = %w(international airport municipal)
43
+ words_to_remove.each do |word|
44
+ output.gsub!(/#{word}/i, "")
45
+ end
46
+ output
47
+ end
33
48
 
34
49
  end
35
50
  end
data/lib/barometer.rb CHANGED
@@ -9,6 +9,12 @@ require 'barometer/formats'
9
9
 
10
10
  module Barometer
11
11
 
12
+ @@debug_mode = false
13
+ def self.debug; @@debug_mode; end;
14
+ def self.debug=(value); @@debug_mode = value; end;
15
+ def self.debug!; @@debug_mode = true; end;
16
+ def self.debug?; @@debug_mode; end;
17
+
12
18
  @@google_geocode_key = nil
13
19
  def self.google_geocode_key; @@google_geocode_key; end;
14
20
  def self.google_geocode_key=(key); @@google_geocode_key = key; end;
@@ -25,6 +31,11 @@ module Barometer
25
31
  def self.force_geocode=(value); @@force_geocode = value; end;
26
32
  def self.force_geocode!; @@force_geocode = true; end;
27
33
 
34
+ @@enhance_timezone = false
35
+ def self.enhance_timezone; @@enhance_timezone; end;
36
+ def self.enhance_timezone=(value); @@enhance_timezone = value; end;
37
+ def self.enhance_timezone!; @@enhance_timezone = true; end;
38
+
28
39
  # adjust the timeout used when interactind with external web services
29
40
  #
30
41
  @@timeout = 15
@@ -32,6 +32,23 @@ class Demometer < Sinatra::Default
32
32
  { :weather_dot_com => { :keys => { :partner => partner_key, :license => license_key } } }
33
33
  end
34
34
 
35
+ def config_weather_bug
36
+ if File.exists?(@@config_file)
37
+ keys = YAML.load_file(@@config_file)
38
+ if keys["weather_bug"] && keys["weather_bug"]["code"]
39
+ code = keys["weather_bug"]["code"].to_s
40
+ else
41
+ raise RunTimeError "no weatherbug.com keys"
42
+ exit
43
+ end
44
+ else
45
+ File.open(@@config_file, 'w') {|f| f << "\weather_bug:\n code: API_CODE" }
46
+ raise RunTimeError "no weatherbug.com keys"
47
+ exit
48
+ end
49
+ { :weather_bug => { :keys => { :code => code } } }
50
+ end
51
+
35
52
  helpers do
36
53
  def data(title, value)
37
54
  return if value.nil?
@@ -58,6 +75,13 @@ class Demometer < Sinatra::Default
58
75
  Barometer::Base.config[1] << config_weather_dot_com
59
76
  end
60
77
 
78
+ # setup weatherbug.com
79
+ if Barometer::Base.config && Barometer::Base.config[1] &&
80
+ Barometer::Base.config[1].include?(:weather_bug)
81
+ Barometer::Base.config[1].delete(:weather_bug)
82
+ Barometer::Base.config[1] << config_weather_bug
83
+ end
84
+
61
85
  if params[:query] && !params[:query][:q].empty?
62
86
  @barometer = Barometer.new(params[:query][:q])
63
87
  @weather = @barometer.measure(metric)
@@ -72,5 +96,9 @@ class Demometer < Sinatra::Default
72
96
  get '/readme.html' do
73
97
  erb :readme
74
98
  end
99
+
100
+ get '/about.html' do
101
+ erb :about
102
+ end
75
103
 
76
104
  end