barometer 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.rdoc +1 -1
  2. data/VERSION.yml +1 -1
  3. data/bin/barometer +4 -12
  4. data/lib/barometer/data.rb +2 -5
  5. data/lib/barometer/data/local_datetime.rb +2 -2
  6. data/lib/barometer/measurements/measurement.rb +6 -6
  7. data/lib/barometer/measurements/result.rb +207 -0
  8. data/lib/barometer/measurements/{forecast_array.rb → result_array.rb} +16 -13
  9. data/lib/barometer/translations/weather_country_codes.yml +3 -3
  10. data/lib/barometer/weather_services/google.rb +3 -3
  11. data/lib/barometer/weather_services/weather_bug.rb +3 -3
  12. data/lib/barometer/weather_services/weather_dot_com.rb +65 -38
  13. data/lib/barometer/weather_services/wunderground.rb +3 -3
  14. data/lib/barometer/weather_services/yahoo.rb +3 -3
  15. data/lib/demometer/demometer.rb +2 -2
  16. data/lib/demometer/public/css/master.css +4 -75
  17. data/lib/demometer/public/css/print.css +1 -2
  18. data/lib/demometer/public/css/syntax.css +1 -2
  19. data/lib/demometer/views/about.erb +1 -1
  20. data/lib/demometer/views/contributing.erb +4 -4
  21. data/lib/demometer/views/index.erb +8 -9
  22. data/lib/demometer/views/layout.erb +1 -2
  23. data/spec/measurements/measurement_spec.rb +29 -53
  24. data/spec/measurements/{forecast_array_spec.rb → result_array_spec.rb} +8 -8
  25. data/spec/measurements/result_spec.rb +660 -0
  26. data/spec/spec_helper.rb +1 -0
  27. data/spec/weather_services/google_spec.rb +4 -4
  28. data/spec/weather_services/services_spec.rb +1 -1
  29. data/spec/weather_services/weather_bug_spec.rb +3 -3
  30. data/spec/weather_services/weather_dot_com_spec.rb +19 -22
  31. data/spec/weather_services/wunderground_spec.rb +2 -2
  32. data/spec/weather_services/yahoo_spec.rb +2 -2
  33. data/spec/weather_spec.rb +14 -39
  34. metadata +6 -12
  35. data/lib/barometer/measurements/common.rb +0 -113
  36. data/lib/barometer/measurements/current.rb +0 -76
  37. data/lib/barometer/measurements/forecast.rb +0 -62
  38. data/lib/barometer/measurements/night.rb +0 -27
  39. data/spec/measurements/common_spec.rb +0 -352
  40. data/spec/measurements/current_spec.rb +0 -186
  41. data/spec/measurements/forecast_spec.rb +0 -135
  42. data/spec/measurements/night_measurement_spec.rb +0 -49
@@ -3,6 +3,7 @@ module Barometer
3
3
  # = Weather.com
4
4
  # www.weather.com
5
5
  #
6
+ # - usage restrictions: YES ... many !!!
6
7
  # - key required: YES (partnerid & licensekey)
7
8
  # - registration required: YES
8
9
  # - supported countries: US (by zipcode), International (by Weather Location ID)
@@ -27,16 +28,32 @@ module Barometer
27
28
  # - Weather Location ID (International)
28
29
  #
29
30
  # = Weather.com terms of use
30
- # ???
31
+ # There are many conditions when using weather.com. Please read the EULA you
32
+ # received when you registered for your API keys. In a nutshell (but not limited
33
+ # to), do the following:
34
+ # - display the weather.com links (all 5)
35
+ # - respect the data refresh rates
36
+ # - do not alter/delete content
37
+ # - display when weather was last updated
38
+ # - do not display data in combination with other 3rd party data (except NOAA or GOV)
39
+ # - do not reproduce, rent, lease, lend, distribute or re-market data
40
+ # - do not resell
41
+ # - do not use in combination with a service that charges a fee
42
+ # - do not use in a mobile application
43
+ # - use the images properly
44
+ # - do not display weather for more then 3 locations at a time
45
+ # - do not allow the data to be scraped (via robots, spiders, web crawlers, etc)
46
+ # - do not use the latitude and longitude information
31
47
  #
32
48
  # == notes
33
- # - the Weather Location ID is a propreitary number (possibly shared with yahoo.com)
49
+ # - the Weather Location ID is a propreitary number (shared with yahoo.com)
34
50
  #
35
51
  # == TODO
36
52
  # - improve "forecasted_wet_by_icon?" to determine if day or night and use right code
37
53
  # - improve "forecasted_sunny_by_icon?" to determine if day or night and use right code
38
54
  # - improve "forcasted_wet_by_humidity?" to use forecasted values
39
55
  # - improve "forcasted_windy?" to use forecasted values
56
+ # - collect moon and uv information
40
57
  #
41
58
  class WeatherService::WeatherDotCom < WeatherService
42
59
 
@@ -100,7 +117,7 @@ module Barometer
100
117
 
101
118
  def self._build_current(data, metric=true)
102
119
  raise ArgumentError unless data.is_a?(Hash)
103
- current = Measurement::Current.new
120
+ current = Measurement::Result.new
104
121
  if data
105
122
  if data['cc']
106
123
  current.updated_at = Data::LocalDateTime.parse(data['cc']['lsup'])
@@ -132,60 +149,76 @@ module Barometer
132
149
 
133
150
  def self._build_forecast(data, metric=true)
134
151
  raise ArgumentError unless data.is_a?(Hash)
135
- forecasts = Measurement::ForecastArray.new
152
+ forecasts = Measurement::ResultArray.new
136
153
 
137
154
  if data && data['dayf'] && data['dayf']['day']
138
155
  local_date = data['dayf']['lsup']
139
156
  data['dayf']['day'].each do |forecast|
140
- forecast_measurement = Measurement::Forecast.new
141
- forecast_measurement.date = Date.parse(forecast['dt'])
157
+ day_measurement = Measurement::Result.new
158
+ night_measurement = Measurement::Result.new
142
159
 
143
- forecast_measurement.high = Data::Temperature.new(metric)
144
- forecast_measurement.high << forecast['hi']
145
- forecast_measurement.low = Data::Temperature.new(metric)
146
- forecast_measurement.low << forecast['low']
160
+ # as stated by weather.com "day = 7am-7pm"
161
+ # and "night = 7pm-7am"
162
+ date = Date.parse(forecast['dt'])
163
+ date_string = date.strftime("%b %d")
164
+ day_measurement.valid_start_date = Data::LocalDateTime.new(date.year,date.month,date.day,7,0,0)
165
+ day_measurement.valid_end_date = Data::LocalDateTime.new(date.year,date.month,date.day,18,59,59)
166
+ night_measurement.valid_start_date = Data::LocalDateTime.new(date.year,date.month,date.day,19,0,0)
167
+ night_measurement.valid_end_date = Data::LocalDateTime.new(date.year,date.month,date.day+1,6,59,59)
168
+
169
+ high = Data::Temperature.new(metric)
170
+ high << forecast['hi']
171
+ low = Data::Temperature.new(metric)
172
+ low << forecast['low']
173
+ day_measurement.high = high
174
+ day_measurement.low = low
175
+ night_measurement.high = high
176
+ night_measurement.low = low
147
177
 
148
178
  # build sun
149
179
  rise_local_time = Data::LocalTime.parse(forecast['sunr'])
150
180
  set_local_time = Data::LocalTime.parse(forecast['suns'])
151
181
  sun = Data::Sun.new(rise_local_time, set_local_time)
152
- forecast_measurement.sun = sun
182
+ day_measurement.sun = sun
183
+ night_measurement.sun = sun
153
184
 
154
185
  if forecast['part']
155
186
  forecast['part'].each do |part|
156
187
  if part['p'] == 'd'
157
- # add this to the ForecastMeasurement
158
- forecast_measurement.condition = part['t']
159
- forecast_measurement.icon = part['icon']
160
- forecast_measurement.pop = part['ppcp'].to_i
161
- forecast_measurement.humidity = part['hmid'].to_i
188
+ # add this to the day
189
+ day_measurement.description = "#{date_string} - Day"
190
+ day_measurement.condition = part['t']
191
+ day_measurement.icon = part['icon']
192
+ day_measurement.pop = part['ppcp'].to_i
193
+ day_measurement.humidity = part['hmid'].to_i
162
194
 
163
195
  if part['wind']
164
- forecast_measurement.wind = Data::Speed.new(metric)
165
- forecast_measurement.wind << part['wind']['s']
166
- forecast_measurement.wind.degrees = part['wind']['d'].to_i
167
- forecast_measurement.wind.direction = part['wind']['t']
196
+ day_measurement.wind = Data::Speed.new(metric)
197
+ day_measurement.wind << part['wind']['s']
198
+ day_measurement.wind.degrees = part['wind']['d'].to_i
199
+ day_measurement.wind.direction = part['wind']['t']
168
200
  end
169
201
 
170
202
  elsif part['p'] == 'n'
171
- # add this to the NightMeasurement
172
- forecast_measurement.night = Measurement::ForecastNight.new
173
- forecast_measurement.night.condition = part['t']
174
- forecast_measurement.night.icon = part['icon']
175
- forecast_measurement.night.pop = part['ppcp'].to_i
176
- forecast_measurement.night.humidity = part['hmid'].to_i
203
+ # add this to the night
204
+ night_measurement.description = "#{date_string} - Night"
205
+ night_measurement.condition = part['t']
206
+ night_measurement.icon = part['icon']
207
+ night_measurement.pop = part['ppcp'].to_i
208
+ night_measurement.humidity = part['hmid'].to_i
177
209
 
178
210
  if part['wind']
179
- forecast_measurement.night.wind = Data::Speed.new(metric)
180
- forecast_measurement.night.wind << part['wind']['s']
181
- forecast_measurement.night.wind.degrees = part['wind']['d'].to_i
182
- forecast_measurement.night.wind.direction = part['wind']['t']
211
+ night_measurement.wind = Data::Speed.new(metric)
212
+ night_measurement.wind << part['wind']['s']
213
+ night_measurement.wind.degrees = part['wind']['d'].to_i
214
+ night_measurement.wind.direction = part['wind']['t']
183
215
  end
184
216
 
185
217
  end
186
218
  end
187
219
  end
188
- forecasts << forecast_measurement
220
+ forecasts << day_measurement
221
+ forecasts << night_measurement
189
222
  end
190
223
  end
191
224
  forecasts
@@ -243,10 +276,4 @@ module Barometer
243
276
  end
244
277
 
245
278
  end
246
- end
247
-
248
- # FUTURE DATA TO SUPPORT?
249
- # "cc"=>
250
- # {"obst"=>"Santa Monica, CA",
251
- # "uv"=>{"i"=>"0", "t"=>"Low"},
252
- # "moon"=>{"icon"=>"9", "t"=>"Waxing Gibbous"}
279
+ end
@@ -102,7 +102,7 @@ module Barometer
102
102
  def self._build_current(data, metric=true)
103
103
  raise ArgumentError unless data.is_a?(Hash)
104
104
 
105
- current = Measurement::Current.new
105
+ current = Measurement::Result.new
106
106
  current.updated_at = Data::LocalDateTime.parse(data['observation_time']) if data['observation_time']
107
107
  current.humidity = data['relative_humidity'].to_i
108
108
  current.icon = data['icon'] if data['icon']
@@ -135,13 +135,13 @@ module Barometer
135
135
 
136
136
  def self._build_forecast(data, metric=true)
137
137
  raise ArgumentError unless data.is_a?(Hash)
138
- forecasts = Measurement::ForecastArray.new
138
+ forecasts = Measurement::ResultArray.new
139
139
  # go through each forecast and create an instance
140
140
  if data && data['simpleforecast'] &&
141
141
  data['simpleforecast']['forecastday']
142
142
 
143
143
  data['simpleforecast']['forecastday'].each do |forecast|
144
- forecast_measurement = Measurement::Forecast.new
144
+ forecast_measurement = Measurement::Result.new
145
145
  forecast_measurement.icon = forecast['icon']
146
146
  forecast_measurement.date = Date.parse(forecast['date']['pretty'])
147
147
  forecast_measurement.pop = forecast['pop'].to_i
@@ -92,7 +92,7 @@ module Barometer
92
92
 
93
93
  def self._build_current(data, metric=true)
94
94
  raise ArgumentError unless data.is_a?(Hash)
95
- current = Measurement::Current.new(metric)
95
+ current = Measurement::Result.new(metric)
96
96
  if data
97
97
  if data['item'] && data['item']['yweather:condition']
98
98
  condition_result = data['item']['yweather:condition']
@@ -124,13 +124,13 @@ module Barometer
124
124
 
125
125
  def self._build_forecast(data, metric=true)
126
126
  raise ArgumentError unless data.is_a?(Hash)
127
- forecasts = Measurement::ForecastArray.new
127
+ forecasts = Measurement::ResultArray.new
128
128
 
129
129
  if data && data['item'] && data['item']['yweather:forecast']
130
130
  forecast_result = data['item']['yweather:forecast']
131
131
 
132
132
  forecast_result.each do |forecast|
133
- forecast_measurement = Measurement::Forecast.new
133
+ forecast_measurement = Measurement::Result.new
134
134
  forecast_measurement.icon = forecast['code']
135
135
  forecast_measurement.date = Date.parse(forecast['date'])
136
136
  forecast_measurement.condition = forecast['text']
@@ -12,7 +12,7 @@ else
12
12
  exit
13
13
  end
14
14
 
15
- class Demometer < Sinatra::Default
15
+ #class Demometer < Sinatra::Default
16
16
 
17
17
  def config_weather_dot_com
18
18
  if File.exists?(@@config_file)
@@ -101,4 +101,4 @@ class Demometer < Sinatra::Default
101
101
  erb :about
102
102
  end
103
103
 
104
- end
104
+ #end
@@ -1,11 +1,10 @@
1
1
  /*
2
- Copyright: Blake Mizerany, www.sinatrarb.com
3
- Permission Pending
2
+ Inspired By: Blake Mizerany, www.sinatrarb.com
4
3
  */
5
4
 
6
5
  body {
7
6
  color:#000;
8
- font-family:'lucida grande', 'lucida sans unicade', sans-serif;
7
+ font-family:"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Helvetica, Arial, sans-serif;
9
8
  font-size:100%;
10
9
  line-height:1.3;
11
10
  background-color:#fff;
@@ -17,21 +16,14 @@ body {
17
16
  #head {
18
17
  text-align:center;
19
18
  }
20
- #head img {
21
- vertical-align:middle;
22
- margin:-10px 0 0 -82px;
23
- padding:0 15px 0 0;
24
- border:0;
25
- }
26
19
  #head h1 {
27
20
  color:#000;
28
- font-family:'georgia', 'bitstream vera serif', serif;
29
21
  font-size:4em;
30
22
  font-weight:normal;
31
23
  letter-spacing:-3px;
32
24
  line-height:1;
33
25
  margin:0;
34
- padding:20px 0 8px 0;
26
+ padding:20px 0 15px 0;
35
27
  }
36
28
  #head h1 a, #head h1 a:link, #head h1 a:visited, #head h1 a:hover {
37
29
  color:#100;
@@ -39,8 +31,6 @@ body {
39
31
  }
40
32
  #head ul {
41
33
  font-size:1.1em;
42
- font-family:"lucida console", "monaco", "andale mono", "bitstream vera sans mono",
43
- "consolas", monospace;
44
34
  font-weight:normal;
45
35
  text-transform:uppercase;
46
36
  letter-spacing:2px;
@@ -68,7 +58,7 @@ body {
68
58
  color:#333;
69
59
  font-size:1.1em;
70
60
  max-width:44em;
71
- min-width:27em;
61
+ min-width:30em;
72
62
  margin:7px auto;
73
63
  border-top:2px solid #837d7c;
74
64
  }
@@ -83,7 +73,6 @@ h1, h2, h3, h4, h5, h6 {
83
73
  }
84
74
  h1, h2 {
85
75
  color:#211d1f;
86
- font-family:'georgia', 'bitstream vera serif', serif;
87
76
  font-weight:normal;
88
77
  }
89
78
  h1 a, h2 a { color:#222 }
@@ -163,9 +152,6 @@ hr {
163
152
 
164
153
  /* HOME */
165
154
 
166
- body#home {
167
- background: #fff url(../images/legend.gif) no-repeat fixed right 130px;
168
- }
169
155
  #home #content {
170
156
  font-size:1.05em;
171
157
  margin:20px 0 0 0;
@@ -175,62 +161,6 @@ body#home {
175
161
  #home #head, #home #foot {
176
162
  display:none;
177
163
  }
178
- .pipe {
179
- clear:both;
180
- padding:50px 0;
181
- }
182
- .pipe p {
183
- color:#000;
184
- font-size:62px;
185
- font-family:'georgia', 'bitstream vera serif', serif;
186
- letter-spacing:-3px;
187
- line-height:1;
188
- text-align:right;
189
- margin:0em 43% 0 0;
190
- padding:0 60px 0 0;
191
- }
192
- .pipe pre {
193
- float:right;
194
- background:transparent;
195
- font-size:28px;
196
- margin:0;
197
- padding:5px 0 0 0;
198
- width:42%;
199
- border-width:0;
200
- }
201
- .pipe pre code {
202
- color:#666;
203
- background:transparent;
204
- }
205
- .pipe.shell p {
206
- font-size:56px;
207
- }
208
- .pipe.shell pre {
209
- font-size:18px;
210
- }
211
- .pipe.nav p {
212
- font-size:100px;
213
- letter-spacing:-6px;
214
- }
215
- .pipe.nav pre {
216
- font-size:36px;
217
- padding-top:20px;
218
- text-transform:uppercase;
219
- letter-spacing:4px;
220
- line-height:1.25;
221
- }
222
- .pipe.nav {
223
- padding:25px 0 50px 0;
224
- }
225
- .pipe.nav a, .pipe.nav a:link, .pipe.nav a:visited {
226
- color:#444;
227
- text-decoration:none;
228
- }
229
- .pipe.nav a:hover {
230
- color:#000;
231
- text-decoration:underline;
232
- }
233
-
234
164
  form {
235
165
  text-align: center;
236
166
  }
@@ -253,7 +183,6 @@ form .submit-input input {
253
183
  form .options-input {
254
184
  position: relative;
255
185
  margin: 0 7% 0 0;
256
- float: left;
257
186
  text-align: left;
258
187
  }
259
188
 
@@ -1,6 +1,5 @@
1
1
  /*
2
- Copyright: Blake Mizerany, www.sinatrarb.com
3
- Permission Pending
2
+ Inspired By: Blake Mizerany, www.sinatrarb.com
4
3
  */
5
4
  body
6
5
  { color: #000;
@@ -1,6 +1,5 @@
1
1
  /*
2
- Copyright: Blake Mizerany, www.sinatrarb.com
3
- Permission Pending
2
+ Inspired By: Blake Mizerany, www.sinatrarb.com
4
3
  */
5
4
  .highlight { background: #ffffff; }
6
5
  .highlight .c { color: #999988; font-style: italic } /* Comment */
@@ -6,5 +6,5 @@
6
6
 
7
7
  <ul>
8
8
  <li><a href='http://sinatra.github.com/'>Blake Mizerany</a> (bmizerany) for Sinatra and
9
- the layout for this demo app (permission pending).</li>
9
+ the inspiration for the layout of the demo app.</li>
10
10
  </ul>
@@ -1,12 +1,12 @@
1
1
  <h1 id='contribute'>Contribute</h1>
2
2
 
3
- <p>Want to advance Barometer? Help out by contributing!</p>
3
+ <p>Help build Barometer.</p>
4
4
 
5
- <h2 id='find_a_bug'>Find a bug?</h2>
5
+ <h2>Find a bug?</h2>
6
6
 
7
7
  <p>Add it to GitHub by <a href='http://github.com/attack/barometer/issues'>creating a new issue</a>. Be sure to include all relevant information, like the versions of Barometer and Ruby you&#8217;re using. A <a href='http://gist.github.com/'>gist</a> of the code that caused the issue as well as any error messages are also very helpful.</p>
8
8
 
9
- <h2 id='have_a_patch'>Have a patch?</h2>
9
+ <h2>Have a patch?</h2>
10
10
 
11
11
  <p>Bugs and feature requests that include patches are much more likely to get attention. Here are some guidelines that will help ensure your patch can be applied as quickly as possible:</p>
12
12
 
@@ -22,7 +22,7 @@
22
22
  </li>
23
23
 
24
24
  <li>
25
- <p><strong>Mind the <code>README</code>:</strong> If the patch adds or modifies a major feature, modify the <code>README.rdoc</code> file to reflect that.</p>
25
+ <p><strong>Update the <code>README</code>:</strong> If the patch adds or modifies a major feature, modify the <code>README.rdoc</code> file to reflect that.</p>
26
26
 
27
27
  </li>
28
28
 
@@ -14,21 +14,20 @@
14
14
  <input id="query_metric" name="query[metric]" type="checkbox" value="1" checked="checked" />
15
15
  <br/>
16
16
  Source :
17
- <input type="checkbox" name="query[source]" value="wunderground" checked="checked" /> Wunderground
18
- <input type="checkbox" name="query[source]" value="yahoo" /> Yahoo
19
- <input type="checkbox" name="query[source]" value="google" /> Google
20
- <input type="checkbox" name="query[source]" value="weather_dot_com" /> Weather.com
21
- <input type="checkbox" name="query[source]" value="weather_bug" /> Weather Bug
22
- <br/>
17
+ <ul>
18
+ <li><input type="checkbox" name="query[source]" value="wunderground" checked="checked" /> Wunderground</li>
19
+ <li><input type="checkbox" name="query[source]" value="yahoo" /> Yahoo</li>
20
+ <li><input type="checkbox" name="query[source]" value="google" /> Google</li>
21
+ <li><input type="checkbox" name="query[source]" value="weather_dot_com" /> Weather.com</li>
22
+ <li><input type="checkbox" name="query[source]" value="weather_bug" /> Weather Bug</li>
23
+ </ul>
23
24
  Force Geocode? :
24
25
  <input id="query_geocode" name="query[geocode]" type="checkbox" value="1" checked="checked" />
25
26
  </div>
26
27
  </form>
27
28
 
28
- <p>&nbsp;</p>
29
- <br/>
30
-
31
29
  <% if params[:query] && !params[:query][:q].empty? %>
30
+ <hr/>
32
31
  <h2>query: "<%= params[:query][:q] %>"</h2>
33
32
  <% end %>
34
33