barometer-weather_bug 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +57 -0
- data/Rakefile +11 -0
- data/barometer-weather_bug.gemspec +25 -0
- data/lib/barometer/weather_bug.rb +41 -0
- data/lib/barometer/weather_bug/current_api.rb +24 -0
- data/lib/barometer/weather_bug/current_response.rb +31 -0
- data/lib/barometer/weather_bug/forecast_api.rb +24 -0
- data/lib/barometer/weather_bug/forecast_response.rb +27 -0
- data/lib/barometer/weather_bug/query.rb +40 -0
- data/lib/barometer/weather_bug/response/current_weather.rb +80 -0
- data/lib/barometer/weather_bug/response/forecasted_weather.rb +65 -0
- data/lib/barometer/weather_bug/response/location.rb +21 -0
- data/lib/barometer/weather_bug/response/station.rb +41 -0
- data/lib/barometer/weather_bug/response/sun.rb +30 -0
- data/lib/barometer/weather_bug/response/time_helper.rb +50 -0
- data/lib/barometer/weather_bug/response/timezone.rb +13 -0
- data/lib/barometer/weather_bug/version.rb +5 -0
- data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/weather_bug/current_response_spec.rb +64 -0
- data/spec/weather_bug/forecast_response_spec.rb +23 -0
- data/spec/weather_bug/query_spec.rb +44 -0
- data/spec/weather_bug_spec.rb +80 -0
- metadata +106 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a31444023e366197794d252581b83670556eea74
|
|
4
|
+
data.tar.gz: 258204151d1f49d6fa32c425b299802df1cde018
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3defeebf481c0ffc3aa6b60c50f43268aceeddcee5cc4bc960f8de5105e719d6bae1ee3b82db25db439dedbeb0c25b75d3084e040a1e1436503a383d4725113a
|
|
7
|
+
data.tar.gz: a5d8c680a0aed1dab17a9c2443043202fa5af6d4d49ae7cb9950bf4e5347d2a3c3f2a26372197a7112ab90c85a55c3223c95e21214870fe922d5fcbd34e25f3f
|
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 Mark Gangl
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Barometer::WeatherBug
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/attack/barometer-weather_bug)
|
|
4
|
+
[](http://badge.fury.io/rb/barometer-weather_bug)
|
|
5
|
+
[](https://codeclimate.com/github/attack/barometer-weather_bug)
|
|
6
|
+
|
|
7
|
+
A wrapper for the WeatherBug weather API. This wrapper is
|
|
8
|
+
barometer compatiable and can be used with or without barometer.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
This wrapper was designed to be used via [Barometer](https://github.com/attack/barometer), or on its own.
|
|
13
|
+
|
|
14
|
+
### Directly
|
|
15
|
+
|
|
16
|
+
By using this wrapper directly, you lose any Barometer aggregation and
|
|
17
|
+
failover capabilities. Barometer is still dependency to provide a
|
|
18
|
+
framework for query conversion, weather service integration and data
|
|
19
|
+
processing.
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
query = Barometer::Query.new('42.7243,-73.6927')
|
|
23
|
+
keys = {api: 'forecast io apikey'}
|
|
24
|
+
|
|
25
|
+
result = Barometer::WeatherBug.call(query, keys: keys)
|
|
26
|
+
puts result.current.temperature.c
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### via Barometer
|
|
30
|
+
|
|
31
|
+
Barometer is a weather service framework, providing aggregation and failover
|
|
32
|
+
capabilities. To make WeatherBug available to Barometer, you must register
|
|
33
|
+
it as an available weather service.
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
Barometer::WeatherService.register(:weather_bug, Barometer::WeatherBug)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then follow the instructions provided by [Barometer](https://github.com/attack/barometer).
|
|
40
|
+
|
|
41
|
+
## Contributing
|
|
42
|
+
|
|
43
|
+
1. Fork it
|
|
44
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
45
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
46
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
47
|
+
5. Create new Pull Request
|
|
48
|
+
|
|
49
|
+
## Links
|
|
50
|
+
|
|
51
|
+
* repo: http://github.com/attack/barometer-weather_bug
|
|
52
|
+
* travis ci: https://travis-ci.org/attack/barometer-weather_bug
|
|
53
|
+
* code climate: https://codeclimate.com/github/attack/barometer-weather_bug
|
|
54
|
+
|
|
55
|
+
## Copyright
|
|
56
|
+
|
|
57
|
+
Copyright (c) 2009-2014 Mark Gangl. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
|
3
|
+
require 'barometer/weather_bug/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'barometer-weather_bug'
|
|
7
|
+
spec.version = Barometer::WeatherBug::VERSION
|
|
8
|
+
spec.authors = ['Mark Gangl']
|
|
9
|
+
spec.email = ['mark@attackcorp.com']
|
|
10
|
+
spec.description = 'A barometer adapter for WeatherBug'
|
|
11
|
+
spec.summary = spec.description
|
|
12
|
+
spec.homepage = 'http://github.com/attack/barometer-weather_bug'
|
|
13
|
+
spec.license = 'MIT'
|
|
14
|
+
|
|
15
|
+
spec.platform = Gem::Platform::RUBY
|
|
16
|
+
spec.required_ruby_version = '>= 1.9.2'
|
|
17
|
+
|
|
18
|
+
spec.files = `git ls-files`.split($/)
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
|
|
22
|
+
spec.add_dependency 'barometer', '~> 0.9.5'
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency 'bundler'
|
|
25
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'barometer'
|
|
2
|
+
require_relative 'weather_bug/version'
|
|
3
|
+
require_relative 'weather_bug/current_api'
|
|
4
|
+
require_relative 'weather_bug/current_response'
|
|
5
|
+
require_relative 'weather_bug/forecast_api'
|
|
6
|
+
require_relative 'weather_bug/forecast_response'
|
|
7
|
+
|
|
8
|
+
module Barometer
|
|
9
|
+
class WeatherBug
|
|
10
|
+
def self.call(query, config={})
|
|
11
|
+
WeatherBug.new(query, config).measure!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(query, config={})
|
|
15
|
+
@query = query
|
|
16
|
+
@api_code = config[:keys][:code] if config[:keys]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def measure!
|
|
20
|
+
validate_key!
|
|
21
|
+
|
|
22
|
+
current_weather_api = CurrentApi.new(query, api_code)
|
|
23
|
+
response = CurrentResponse.new.parse(current_weather_api.get)
|
|
24
|
+
|
|
25
|
+
forecast_weather_api = ForecastApi.new(current_weather_api.query, api_code)
|
|
26
|
+
ForecastResponse.new(response).parse(forecast_weather_api.get)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
attr_reader :query, :api_code
|
|
32
|
+
|
|
33
|
+
def validate_key!
|
|
34
|
+
unless api_code && !api_code.empty?
|
|
35
|
+
raise Barometer::WeatherService::KeyRequired
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Barometer::WeatherService.register(:weather_bug, Barometer::WeatherBug)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'query'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
class WeatherBug
|
|
5
|
+
class CurrentApi < Utils::Api
|
|
6
|
+
def initialize(query, api_code)
|
|
7
|
+
@query = WeatherBug::Query.new(query)
|
|
8
|
+
@api_code = api_code
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def url
|
|
12
|
+
"http://#{@api_code}.api.wxbug.net/getLiveWeatherRSS.aspx"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def params
|
|
16
|
+
{ACode: @api_code, OutputType: '1'}.merge(@query.to_param)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unwrap_nodes
|
|
20
|
+
['weather', 'ob']
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require_relative 'response/timezone'
|
|
2
|
+
require_relative 'response/current_weather'
|
|
3
|
+
require_relative 'response/station'
|
|
4
|
+
|
|
5
|
+
module Barometer
|
|
6
|
+
class WeatherBug
|
|
7
|
+
class CurrentResponse
|
|
8
|
+
def initialize
|
|
9
|
+
@response = Barometer::Response.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def parse(payload)
|
|
13
|
+
response.add_query(payload.query)
|
|
14
|
+
|
|
15
|
+
response.timezone = WeatherBug::Response::TimeZone.new(payload).parse
|
|
16
|
+
response.current = WeatherBug::Response::CurrentWeather.new(payload, timezone).parse
|
|
17
|
+
response.station = WeatherBug::Response::Station.new(payload).parse
|
|
18
|
+
|
|
19
|
+
response
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
attr_reader :response
|
|
25
|
+
|
|
26
|
+
def timezone
|
|
27
|
+
response.timezone
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'query'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
class WeatherBug
|
|
5
|
+
class ForecastApi < Utils::Api
|
|
6
|
+
def initialize(query, api_code)
|
|
7
|
+
@query = WeatherBug::Query.new(query)
|
|
8
|
+
@api_code = api_code
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def url
|
|
12
|
+
"http://#{@api_code}.api.wxbug.net/getForecastRSS.aspx"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def params
|
|
16
|
+
{ACode: @api_code, OutputType: '1'}.merge(@query.to_param)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unwrap_nodes
|
|
20
|
+
['weather', 'forecasts']
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'response/forecasted_weather'
|
|
2
|
+
require_relative 'response/location'
|
|
3
|
+
|
|
4
|
+
module Barometer
|
|
5
|
+
class WeatherBug
|
|
6
|
+
class ForecastResponse
|
|
7
|
+
def initialize(response)
|
|
8
|
+
@response = response
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def parse(payload)
|
|
12
|
+
response.forecast = WeatherBug::Response::ForecastedWeather.new(payload, timezone).parse
|
|
13
|
+
response.location = WeatherBug::Response::Location.new(payload).parse
|
|
14
|
+
|
|
15
|
+
response
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :response
|
|
21
|
+
|
|
22
|
+
def timezone
|
|
23
|
+
response.timezone
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'delegate'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
class WeatherBug
|
|
5
|
+
class Query < SimpleDelegator
|
|
6
|
+
attr_reader :converted_query
|
|
7
|
+
|
|
8
|
+
def self.accepted_formats
|
|
9
|
+
[:short_zipcode, :coordinates]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(query)
|
|
13
|
+
super
|
|
14
|
+
@converted_query = convert_query
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_param
|
|
18
|
+
{UnitType: unit_type}.merge(format_query)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def convert_query
|
|
24
|
+
convert!(*self.class.accepted_formats)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def format_query
|
|
28
|
+
if converted_query.format == :short_zipcode
|
|
29
|
+
{zipCode: converted_query.q}
|
|
30
|
+
else
|
|
31
|
+
{lat: converted_query.geo.latitude, long: converted_query.geo.longitude}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def unit_type
|
|
36
|
+
converted_query.metric? ? '1' : '0'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require_relative 'time_helper'
|
|
2
|
+
require_relative 'sun'
|
|
3
|
+
|
|
4
|
+
module Barometer
|
|
5
|
+
class WeatherBug
|
|
6
|
+
class Response
|
|
7
|
+
class CurrentWeather
|
|
8
|
+
def initialize(payload, timezone)
|
|
9
|
+
@payload = payload
|
|
10
|
+
@timezone = timezone
|
|
11
|
+
@current = Barometer::Response::Current.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def parse
|
|
15
|
+
current.observed_at = observed_at
|
|
16
|
+
current.stale_at = stale_at
|
|
17
|
+
current.humidity = humidity
|
|
18
|
+
current.condition = condition
|
|
19
|
+
current.icon = icon
|
|
20
|
+
current.temperature = temperature
|
|
21
|
+
current.dew_point = dew_point
|
|
22
|
+
current.wind_chill = wind_chill
|
|
23
|
+
current.wind = wind
|
|
24
|
+
current.pressure = pressure
|
|
25
|
+
current.sun = WeatherBug::Response::Sun.new(payload, timezone).parse
|
|
26
|
+
|
|
27
|
+
current
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
attr_reader :payload, :timezone, :current
|
|
33
|
+
|
|
34
|
+
def units
|
|
35
|
+
payload.units
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def observed_at
|
|
39
|
+
@observed_at ||= TimeHelper.new(payload, timezone).parse('ob_date')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def stale_at
|
|
43
|
+
Utils::Time.add_one_hour(observed_at)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def humidity
|
|
47
|
+
payload.fetch('humidity')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def condition
|
|
51
|
+
payload.fetch('current_condition')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def icon
|
|
55
|
+
payload.using(/cond(\d*)\.gif/).fetch('current_condition', '@icon')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def temperature
|
|
59
|
+
[units, payload.fetch('temp')]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def dew_point
|
|
63
|
+
[units, payload.fetch('dew_point')]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def wind_chill
|
|
67
|
+
[units, payload.fetch('feels_like')]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def wind
|
|
71
|
+
[units, payload.fetch('wind_speed'), payload.fetch('wind_direction_degrees')]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def pressure
|
|
75
|
+
[units, payload.fetch('pressure')]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Barometer
|
|
2
|
+
class WeatherBug
|
|
3
|
+
class Response
|
|
4
|
+
class ForecastedWeather
|
|
5
|
+
def initialize(payload, timezone)
|
|
6
|
+
@payload = payload
|
|
7
|
+
@timezone = timezone
|
|
8
|
+
@predictions = Barometer::Response::PredictionCollection.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def parse
|
|
12
|
+
each_prediction do |prediction, forecast_payload, index|
|
|
13
|
+
prediction.date = date(index), timezone
|
|
14
|
+
prediction.condition = condition(forecast_payload)
|
|
15
|
+
prediction.icon = icon(forecast_payload)
|
|
16
|
+
prediction.high = high(forecast_payload)
|
|
17
|
+
prediction.low = low(forecast_payload)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
predictions
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
attr_reader :payload, :timezone, :predictions
|
|
26
|
+
|
|
27
|
+
def units
|
|
28
|
+
payload.units
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each_prediction
|
|
32
|
+
payload.fetch_each_with_index('forecast') do |forecast_payload, index|
|
|
33
|
+
predictions.build do |prediction|
|
|
34
|
+
yield prediction, forecast_payload, index
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def start_date
|
|
40
|
+
Date.strptime(payload.fetch('@date'), '%m/%d/%Y %H:%M:%S %p')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def date(index)
|
|
44
|
+
start_date + index
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def condition(forecast_payload)
|
|
48
|
+
forecast_payload.fetch('short_prediction')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def icon(forecast_payload)
|
|
52
|
+
forecast_payload.using(/cond0*([1-9][0-9]*)\.gif$/).fetch('image')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def high(forecast_payload)
|
|
56
|
+
[units, forecast_payload.fetch('high')]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def low(forecast_payload)
|
|
60
|
+
[units, forecast_payload.fetch('low')]
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Barometer
|
|
2
|
+
class WeatherBug
|
|
3
|
+
class Response
|
|
4
|
+
class Location < WeatherService::Response::Location
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def city
|
|
8
|
+
payload.fetch('location', 'city')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def state_code
|
|
12
|
+
payload.fetch('location', 'state')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def zip_code
|
|
16
|
+
payload.fetch('location', 'zip')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Barometer
|
|
2
|
+
class WeatherBug
|
|
3
|
+
class Response
|
|
4
|
+
class Station < WeatherService::Response::Location
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
payload.fetch('station_id')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def name
|
|
12
|
+
payload.fetch('station')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def city
|
|
16
|
+
payload.using(/^([\w ]*?),/).fetch('city_state')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def state_code
|
|
20
|
+
payload.using(/^[\w ^,]*?,([\w ^,]*)/).fetch('city_state')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def country
|
|
24
|
+
payload.fetch('country')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def zip_code
|
|
28
|
+
payload.fetch('city_state', '@zipcode')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def latitude
|
|
32
|
+
payload.fetch('latitude')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def longitude
|
|
36
|
+
payload.fetch('longitude')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative 'time_helper'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
class WeatherBug
|
|
5
|
+
class Response
|
|
6
|
+
class Sun
|
|
7
|
+
def initialize(payload, timezone)
|
|
8
|
+
@payload = payload
|
|
9
|
+
@timezone = timezone
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def parse
|
|
13
|
+
Data::Sun.new(rise: local_sunrise_time, set: local_sunset_time)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
attr_reader :payload, :timezone
|
|
19
|
+
|
|
20
|
+
def local_sunrise_time
|
|
21
|
+
TimeHelper.new(payload, timezone).parse('sunrise')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def local_sunset_time
|
|
25
|
+
TimeHelper.new(payload, timezone).parse('sunset')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Barometer
|
|
2
|
+
class WeatherBug
|
|
3
|
+
class Response
|
|
4
|
+
class TimeHelper
|
|
5
|
+
def initialize(payload, timezone)
|
|
6
|
+
@payload = payload
|
|
7
|
+
@timezone = timezone
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parse(key)
|
|
11
|
+
return unless local_time(key)
|
|
12
|
+
timezone.local_to_utc(local_time(key))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
attr_reader :payload, :timezone, :key
|
|
18
|
+
|
|
19
|
+
def local_time(key)
|
|
20
|
+
@key = key
|
|
21
|
+
@local_time ||= Utils::Time.parse(year, month, day, hour, minute, second)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def year
|
|
25
|
+
payload.fetch(key, 'year', '@number')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def month
|
|
29
|
+
payload.fetch(key, 'month', '@number')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def day
|
|
33
|
+
payload.fetch(key, 'day', '@number')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def hour
|
|
37
|
+
payload.fetch(key, 'hour', '@hour_24')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def minute
|
|
41
|
+
payload.fetch(key, 'minute', '@number')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def second
|
|
45
|
+
payload.fetch(key, 'second', '@number')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"http_interactions":[{"request":{"method":"get","uri":"http://WEATHERBUG_CODE.api.wxbug.net/getLiveWeatherRSS.aspx?ACode=WEATHERBUG_CODE&OutputType=1&UnitType=1&zipCode=90210","body":{"encoding":"UTF-8","string":""},"headers":{}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Cache-Control":["private"],"Content-Type":["application/xml; charset=utf-8"],"Date":["Sat, 26 Oct 2013 14:55:07 GMT"],"Server":["Microsoft-IIS/7.5"],"Set-Cookie":["ASP.NET_SessionId=2q2lm10ejga21x3jdps0f0rm; path=/; HttpOnly"],"X-Aspnet-Version":["4.0.30319"],"X-Powered-By":["ASP.NET"],"Content-Length":["4076"],"Connection":["keep-alive"]},"body":{"encoding":"UTF-8","string":"<aws:weather xmlns:aws=\"http://www.aws.com/aws\"><aws:api version=\"2.0\" /><aws:WebURL>http://weather.weatherbug.com/CA/Valley Village-weather.html?ZCode=Z5546&Units=1&stat=NRTSH</aws:WebURL><aws:InputLocationURL>http://weather.weatherbug.com/CA/Beverly Hills-weather.html?ZCode=Z5546&Units=1</aws:InputLocationURL><aws:ob><aws:ob-date><aws:year number=\"2013\" /><aws:month number=\"10\" text=\"October\" abbrv=\"Oct\" /><aws:day number=\"26\" text=\"Saturday\" abbrv=\"Sat\" /><aws:hour number=\"7\" hour-24=\"07\" /><aws:minute number=\"54\" /><aws:second number=\"00\" /><aws:am-pm abbrv=\"AM\" /><aws:time-zone offset=\"-7\" text=\"Pacific Daylight Time (USA)\" abbrv=\"PDT\" /></aws:ob-date><aws:requested-station-id /><aws:station-id>NRTSH</aws:station-id><aws:station>Campbell Hall School</aws:station><aws:city-state zipcode=\"91617\">Valley Village, CA</aws:city-state><aws:country>USA</aws:country><aws:latitude>34.1536102294922</aws:latitude><aws:longitude>-118.398056030273</aws:longitude><aws:site-url>http://www.campbell.pvt.k12.ca.us/</aws:site-url><aws:aux-temp units=\"&deg;C\">18</aws:aux-temp><aws:aux-temp-rate units=\"&deg;C\">0.0</aws:aux-temp-rate><aws:current-condition icon=\"http://deskwx.weatherbug.com/images/Forecast/icons/cond026.gif\">Mostly Sunny</aws:current-condition><aws:dew-point units=\"&deg;C\">11</aws:dew-point><aws:elevation units=\"m\">192</aws:elevation><aws:feels-like units=\"&deg;C\">12</aws:feels-like><aws:gust-time><aws:year number=\"2013\" /><aws:month number=\"10\" text=\"October\" abbrv=\"Oct\" /><aws:day number=\"26\" text=\"Saturday\" abbrv=\"Sat\" /><aws:hour number=\"12\" hour-24=\"00\" /><aws:minute number=\"59\" /><aws:second number=\"00\" /><aws:am-pm abbrv=\"AM\" /><aws:time-zone offset=\"-7\" text=\"Pacific Daylight Time (USA)\" abbrv=\"PDT\" /></aws:gust-time><aws:gust-direction>S</aws:gust-direction><aws:gust-direction-degrees>174</aws:gust-direction-degrees><aws:gust-speed units=\"km/h\">2</aws:gust-speed><aws:humidity units=\"%\">97</aws:humidity><aws:humidity-high units=\"%\">97</aws:humidity-high><aws:humidity-low units=\"%\">89</aws:humidity-low><aws:humidity-rate>0</aws:humidity-rate><aws:indoor-temp units=\"&deg;C\">24</aws:indoor-temp><aws:indoor-temp-rate units=\"&deg;C\">0</aws:indoor-temp-rate><aws:light>0</aws:light><aws:light-rate>0</aws:light-rate><aws:moon-phase moon-phase-img=\"http://api.wxbug.net/images/moonphase/mphase19.gif\">59</aws:moon-phase><aws:pressure units=\"mb\">1017.27</aws:pressure><aws:pressure-high units=\"mb\">1017.27</aws:pressure-high><aws:pressure-low units=\"mb\">1016.60</aws:pressure-low><aws:pressure-rate units=\"mb/h\">0.68</aws:pressure-rate><aws:rain-month units=\"mm\">0.00</aws:rain-month><aws:rain-rate units=\"mm/h\">0.00</aws:rain-rate><aws:rain-rate-max units=\"mm/h\">0.00</aws:rain-rate-max><aws:rain-today units=\"mm\">0.00</aws:rain-today><aws:rain-year units=\"mm\">87.63</aws:rain-year><aws:temp units=\"&deg;C\">11.9</aws:temp><aws:temp-high units=\"&deg;C\">16</aws:temp-high><aws:temp-low units=\"&deg;C\">11</aws:temp-low><aws:temp-rate units=\"&deg;C/h\">0.6</aws:temp-rate><aws:sunrise><aws:year number=\"2013\" /><aws:month number=\"10\" text=\"October\" abbrv=\"Oct\" /><aws:day number=\"26\" text=\"Saturday\" abbrv=\"Sat\" /><aws:hour number=\"7\" hour-24=\"07\" /><aws:minute number=\"07\" /><aws:second number=\"55\" /><aws:am-pm abbrv=\"AM\" /><aws:time-zone offset=\"-7\" text=\"Pacific Daylight Time (USA)\" abbrv=\"PDT\" /></aws:sunrise><aws:sunset><aws:year number=\"2013\" /><aws:month number=\"10\" text=\"October\" abbrv=\"Oct\" /><aws:day number=\"26\" text=\"Saturday\" abbrv=\"Sat\" /><aws:hour number=\"6\" hour-24=\"18\" /><aws:minute number=\"06\" /><aws:second number=\"47\" /><aws:am-pm abbrv=\"PM\" /><aws:time-zone offset=\"-7\" text=\"Pacific Daylight Time (USA)\" abbrv=\"PDT\" /></aws:sunset><aws:wet-bulb units=\"&deg;C\">11.65</aws:wet-bulb><aws:wind-speed units=\"km/h\">0</aws:wind-speed><aws:wind-speed-avg units=\"km/h\">0</aws:wind-speed-avg><aws:wind-direction>S</aws:wind-direction><aws:wind-direction-degrees>173</aws:wind-direction-degrees><aws:wind-direction-avg>S</aws:wind-direction-avg></aws:ob></aws:weather>\r\n"},"http_version":null},"recorded_at":"Sat, 26 Oct 2013 14:55:07 GMT"},{"request":{"method":"get","uri":"http://WEATHERBUG_CODE.api.wxbug.net/getForecastRSS.aspx?ACode=WEATHERBUG_CODE&OutputType=1&UnitType=1&zipCode=90210","body":{"encoding":"UTF-8","string":""},"headers":{}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Cache-Control":["private"],"Content-Type":["application/xml; charset=utf-8"],"Date":["Sat, 26 Oct 2013 14:55:07 GMT"],"Server":["Microsoft-IIS/7.5"],"Set-Cookie":["ASP.NET_SessionId=ppstsmui0taeaponkcny3cjz; path=/; HttpOnly"],"X-Aspnet-Version":["4.0.30319"],"X-Powered-By":["ASP.NET"],"Content-Length":["4096"],"Connection":["keep-alive"]},"body":{"encoding":"UTF-8","string":"<aws:weather xmlns:aws=\"http://www.aws.com/aws\"><aws:api version=\"2.0\" /><aws:WebURL>http://weather.weatherbug.com/CA/Beverly Hills-weather/local-forecast/7-day-forecast.html?ZCode=Z5546&Units=1</aws:WebURL><aws:forecasts type=\"Detailed\" date=\"10/26/2013 3:15:00 AM\"><aws:location><aws:city>Beverly Hills</aws:city><aws:state>CA</aws:state><aws:zip>90210</aws:zip><aws:zone>CA041</aws:zone></aws:location><aws:forecast><aws:title alttitle=\"SAT\">Saturday</aws:title><aws:short-prediction>Partly Cloudy</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond003.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond003.gif</aws:image><aws:description>Saturday</aws:description><aws:prediction>Areas of low clouds and fog in the morning then sunny. Highs from the lower to mid 70s at the beaches to around 80 inland.</aws:prediction><aws:high units=\"&deg;C\">27</aws:high><aws:low units=\"&deg;C\">15</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"SUN\">Sunday</aws:title><aws:short-prediction>Partly Cloudy</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond003.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond003.gif</aws:image><aws:description>Sunday</aws:description><aws:prediction>Areas of low clouds and fog in the morning then sunny. Highs from the upper 60s at the beaches to the upper 70s inland.</aws:prediction><aws:high units=\"&deg;C\">26</aws:high><aws:low units=\"&deg;C\">13</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"MON\">Monday</aws:title><aws:short-prediction>40% Chance Rain Shower</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond109.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond109.gif</aws:image><aws:description>Monday</aws:description><aws:prediction>Mostly cloudy. A slight chance of showers in the morning then a chance of showers in the afternoon. Highs in the 60s. Southeast winds around 15 mph in the afternoon. Chance of precipitation 40 percent.</aws:prediction><aws:high units=\"&deg;C\">18</aws:high><aws:low units=\"&deg;C\">11</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"TUE\">Tuesday</aws:title><aws:short-prediction>Partly Cloudy</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond003.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond003.gif</aws:image><aws:description>Tuesday</aws:description><aws:prediction>Mostly cloudy with a 20 percent chance of showers in the morning then partly cloudy in the afternoon. Highs in the lower to mid 60s.</aws:prediction><aws:high units=\"&deg;C\">17</aws:high><aws:low units=\"&deg;C\">12</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"WED\">Wednesday</aws:title><aws:short-prediction>Mostly Sunny</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond026.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond026.gif</aws:image><aws:description>Wednesday</aws:description><aws:prediction>Mostly clear. Highs from the mid 60s at the beaches to the mid 70s inland. Lows in the 50s.</aws:prediction><aws:high units=\"&deg;C\">22</aws:high><aws:low units=\"&deg;C\">12</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"THU\">Thursday</aws:title><aws:short-prediction>Mostly Sunny</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond026.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond026.gif</aws:image><aws:description>Thursday</aws:description><aws:prediction>Mostly clear. Highs from the mid 60s at the beaches to the mid 70s inland. Lows in the 50s.</aws:prediction><aws:high units=\"&deg;C\">23</aws:high><aws:low units=\"&deg;C\">13</aws:low></aws:forecast><aws:forecast><aws:title alttitle=\"FRI\">Friday</aws:title><aws:short-prediction>Sunny</aws:short-prediction><aws:image isNight=\"0\" icon=\"cond007.gif\">http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif</aws:image><aws:description>Friday</aws:description><aws:prediction>Sunny. Highs from around 70 at the beaches to around 80 inland.</aws:prediction><aws:high units=\"&deg;C\">26</aws:high><aws:low units=\"&deg;C\">--</aws:low></aws:forecast></aws:forecasts></aws:weather>\r\n"},"http_version":null},"recorded_at":"Sat, 26 Oct 2013 14:55:07 GMT"}],"recorded_with":"VCR 2.6.0"}
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'pry'
|
|
3
|
+
require 'vcr'
|
|
4
|
+
require 'webmock/rspec'
|
|
5
|
+
require 'barometer/support'
|
|
6
|
+
|
|
7
|
+
require_relative '../lib/barometer/weather_bug'
|
|
8
|
+
|
|
9
|
+
Dir['./spec/support/**/*.rb'].sort.each {|f| require f}
|
|
10
|
+
|
|
11
|
+
WEATHERBUG_CODE = Barometer::Support::KeyFileParser.find(:weather_bug, :code) || 'weatherbug'
|
|
12
|
+
downcased_weatherbug_code = WEATHERBUG_CODE.to_s
|
|
13
|
+
downcased_weatherbug_code[0] = WEATHERBUG_CODE.to_s[0..0].downcase
|
|
14
|
+
|
|
15
|
+
VCR.configure do |config|
|
|
16
|
+
config.cassette_library_dir = 'spec/cassettes'
|
|
17
|
+
config.hook_into :webmock
|
|
18
|
+
config.default_cassette_options = { record: :none, serialize_with: :json }
|
|
19
|
+
|
|
20
|
+
config.filter_sensitive_data('WEATHERBUG_CODE') { WEATHERBUG_CODE.to_s }
|
|
21
|
+
# weather bug uses api as host name. this is downcased when the request it made
|
|
22
|
+
config.filter_sensitive_data('WEATHERBUG_CODE') { downcased_weatherbug_code }
|
|
23
|
+
|
|
24
|
+
config.configure_rspec_metadata!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
RSpec.configure do |config|
|
|
28
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
29
|
+
config.include Barometer::Support::Matchers
|
|
30
|
+
config.include Barometer::Support::Factory
|
|
31
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
describe WeatherBug::CurrentResponse do
|
|
5
|
+
it "parses the timezones correctly" do
|
|
6
|
+
payload = Barometer::Utils::Payload.new({
|
|
7
|
+
'ob_date' => {
|
|
8
|
+
'year' => { '@number' => '2013' },
|
|
9
|
+
'month' => { '@number' => '5' },
|
|
10
|
+
'day' => { '@number' => '18' },
|
|
11
|
+
'hour' => { '@hour_24' => '10' },
|
|
12
|
+
'minute' => { '@number' => '46' },
|
|
13
|
+
'second' => { '@number' => '0' },
|
|
14
|
+
'time_zone' => { '@abbrv' => 'PDT' }
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
response = WeatherBug::CurrentResponse.new.parse(payload)
|
|
18
|
+
|
|
19
|
+
utc_observed_at = Time.utc(2013,5,18,17,46,0)
|
|
20
|
+
utc_stale_at = Time.utc(2013,5,18,18,46,0)
|
|
21
|
+
|
|
22
|
+
expect( response.current.observed_at.utc ).to eq utc_observed_at
|
|
23
|
+
expect( response.current.stale_at.utc ).to eq utc_stale_at
|
|
24
|
+
expect( response.timezone.to_s ).to eq 'PDT'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "parses sun timezones correctly" do
|
|
28
|
+
payload = Barometer::Utils::Payload.new({
|
|
29
|
+
'ob_date' => {
|
|
30
|
+
'year' => { '@number' => '2013' },
|
|
31
|
+
'month' => { '@number' => '4' },
|
|
32
|
+
'day' => { '@number' => '13' },
|
|
33
|
+
'hour' => { '@hour_24' => '10' },
|
|
34
|
+
'minute' => { '@number' => '23' },
|
|
35
|
+
'second' => { '@number' => '0' },
|
|
36
|
+
'time_zone' => { '@abbrv' => 'PDT' }
|
|
37
|
+
},
|
|
38
|
+
'sunrise' => {
|
|
39
|
+
'year' => { '@number' => '2013' },
|
|
40
|
+
'month' => { '@number' => '4' },
|
|
41
|
+
'day' => { '@number' => '13' },
|
|
42
|
+
'hour' => { '@hour_24' => '6' },
|
|
43
|
+
'minute' => { '@number' => '44' },
|
|
44
|
+
'second' => { '@number' => '19' },
|
|
45
|
+
},
|
|
46
|
+
'sunset' => {
|
|
47
|
+
'year' => { '@number' => '2013' },
|
|
48
|
+
'month' => { '@number' => '4' },
|
|
49
|
+
'day' => { '@number' => '13' },
|
|
50
|
+
'hour' => { '@hour_24' => '17' },
|
|
51
|
+
'minute' => { '@number' => '31' },
|
|
52
|
+
'second' => { '@number' => '50' },
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
response = WeatherBug::CurrentResponse.new.parse(payload)
|
|
56
|
+
|
|
57
|
+
utc_current_sun_rise = Time.utc(2013,4,13,13,44,19)
|
|
58
|
+
utc_current_sun_set = Time.utc(2013,4,14,0,31,50)
|
|
59
|
+
|
|
60
|
+
expect( response.current.sun.rise.utc ).to eq utc_current_sun_rise
|
|
61
|
+
expect( response.current.sun.set.utc ).to eq utc_current_sun_set
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
describe WeatherBug::ForecastResponse do
|
|
5
|
+
let(:current_response) { Barometer::Response.new }
|
|
6
|
+
|
|
7
|
+
it "parses the timezones correctly" do
|
|
8
|
+
current_response.timezone = Barometer::Data::Zone.new('PDT')
|
|
9
|
+
|
|
10
|
+
payload = Barometer::Utils::Payload.new({
|
|
11
|
+
"@date" => "4/13/2013 10:23:00 AM",
|
|
12
|
+
"forecast" => [{"high" => "13"}]
|
|
13
|
+
})
|
|
14
|
+
response = WeatherBug::ForecastResponse.new(current_response).parse(payload)
|
|
15
|
+
|
|
16
|
+
utc_starts_at = Time.utc(2013,4,13,7,0,0)
|
|
17
|
+
utc_ends_at = Time.utc(2013,4,14,6,59,59)
|
|
18
|
+
|
|
19
|
+
expect( response.forecast[0].starts_at.utc ).to eq utc_starts_at
|
|
20
|
+
expect( response.forecast[0].ends_at.utc ).to eq utc_ends_at
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
describe WeatherBug::Query do
|
|
5
|
+
describe '#to_param' do
|
|
6
|
+
let(:converted_query) { double(:converted_query).as_null_object }
|
|
7
|
+
let(:query) { WeatherBug::Query.new(converted_query) }
|
|
8
|
+
|
|
9
|
+
context 'when the query is a :short_zipcode' do
|
|
10
|
+
before { converted_query.stub(format: :short_zipcode, q: '90210') }
|
|
11
|
+
|
|
12
|
+
it 'includes the correct parameters' do
|
|
13
|
+
expect( query.to_param[:zipCode] ).to eq '90210'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'and the query is a :coordinates' do
|
|
18
|
+
let(:geo) { double(:geo, latitude: '11.22', longitude: '33.44') }
|
|
19
|
+
before { converted_query.stub(format: :coordinates, geo: geo) }
|
|
20
|
+
|
|
21
|
+
it 'includes the correct parameters' do
|
|
22
|
+
expect( query.to_param[:lat] ).to eq '11.22'
|
|
23
|
+
expect( query.to_param[:long] ).to eq '33.44'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'and the query is metric' do
|
|
28
|
+
before { converted_query.stub(metric?: true) }
|
|
29
|
+
|
|
30
|
+
it 'includes the correct parameters' do
|
|
31
|
+
expect( query.to_param[:UnitType] ).to eq '1'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'and the query is imperial' do
|
|
36
|
+
before { converted_query.stub(metric?: false) }
|
|
37
|
+
|
|
38
|
+
it 'includes the correct parameters' do
|
|
39
|
+
expect( query.to_param[:UnitType] ).to eq '0'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require_relative 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Barometer
|
|
4
|
+
describe WeatherBug, vcr: {
|
|
5
|
+
cassette_name: 'WeatherService::WeatherBug'
|
|
6
|
+
} do
|
|
7
|
+
|
|
8
|
+
it 'auto-registers this weather service as :weather_bug' do
|
|
9
|
+
expect( Barometer::WeatherService.source(:weather_bug) ).to eq Barometer::WeatherBug
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '.call' do
|
|
13
|
+
context 'when no keys are provided' do
|
|
14
|
+
let(:query) { build_query }
|
|
15
|
+
|
|
16
|
+
it 'raises an error' do
|
|
17
|
+
expect {
|
|
18
|
+
WeatherBug.call(query)
|
|
19
|
+
}.to raise_error(Barometer::WeatherService::KeyRequired)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'when keys are provided' do
|
|
24
|
+
let(:converted_query) { ConvertedQuery.new('90210', :short_zipcode, :metric) }
|
|
25
|
+
let(:query) { build_query.tap{|q|q.stub(:convert! => converted_query)} }
|
|
26
|
+
let(:config) { {keys: {code: WEATHERBUG_CODE}} }
|
|
27
|
+
|
|
28
|
+
subject { WeatherBug.call(query, config) }
|
|
29
|
+
|
|
30
|
+
it 'converts the query to accepted formats' do
|
|
31
|
+
subject
|
|
32
|
+
expect( query ).to have_received(:convert!).with(:short_zipcode, :coordinates).at_least(:once)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'includes the expected data' do
|
|
36
|
+
expect( subject.query ).to eq '90210'
|
|
37
|
+
expect( subject.format ).to eq :short_zipcode
|
|
38
|
+
expect( subject ).to be_metric
|
|
39
|
+
|
|
40
|
+
should have_data(:current, :observed_at).as_format(:time)
|
|
41
|
+
should have_data(:current, :stale_at).as_format(:time)
|
|
42
|
+
|
|
43
|
+
should have_data(:current, :humidity).as_format(:float)
|
|
44
|
+
should have_data(:current, :condition).as_format(:string)
|
|
45
|
+
should have_data(:current, :icon).as_format(:number)
|
|
46
|
+
should have_data(:current, :temperature).as_format(:temperature)
|
|
47
|
+
should have_data(:current, :dew_point).as_format(:temperature)
|
|
48
|
+
should have_data(:current, :wind_chill).as_format(:temperature)
|
|
49
|
+
should have_data(:current, :wind).as_format(:vector)
|
|
50
|
+
should have_data(:current, :pressure).as_format(:pressure)
|
|
51
|
+
should have_data(:current, :sun, :rise).as_format(:time)
|
|
52
|
+
should have_data(:current, :sun, :set).as_format(:time)
|
|
53
|
+
|
|
54
|
+
should have_data(:station, :id).as_value('NRTSH')
|
|
55
|
+
should have_data(:station, :name).as_value('Campbell Hall School')
|
|
56
|
+
should have_data(:station, :city).as_value('Valley Village')
|
|
57
|
+
should have_data(:station, :state_code).as_value('CA')
|
|
58
|
+
should have_data(:station, :country).as_value('USA')
|
|
59
|
+
should have_data(:station, :zip_code).as_value('91617')
|
|
60
|
+
should have_data(:station, :latitude).as_value(34.1536102294922)
|
|
61
|
+
should have_data(:station, :longitude).as_value(-118.398056030273)
|
|
62
|
+
|
|
63
|
+
should have_data(:location, :city).as_value('Beverly Hills')
|
|
64
|
+
should have_data(:location, :state_code).as_value('CA')
|
|
65
|
+
should have_data(:location, :zip_code).as_value('90210')
|
|
66
|
+
|
|
67
|
+
should have_data(:timezone, :to_s).as_format(/^P[DS]T$/i)
|
|
68
|
+
|
|
69
|
+
expect( subject.forecast.size ).to eq 7
|
|
70
|
+
should have_forecast(:starts_at).as_format(:time)
|
|
71
|
+
should have_forecast(:ends_at).as_format(:time)
|
|
72
|
+
should have_forecast(:condition).as_format(:string)
|
|
73
|
+
should have_forecast(:icon).as_format(:number)
|
|
74
|
+
should have_forecast(:high).as_format(:temperature)
|
|
75
|
+
should have_forecast(:low).as_format(:temperature)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: barometer-weather_bug
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Mark Gangl
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-04-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: barometer
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.9.5
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.9.5
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
description: A barometer adapter for WeatherBug
|
|
42
|
+
email:
|
|
43
|
+
- mark@attackcorp.com
|
|
44
|
+
executables: []
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- ".gitignore"
|
|
49
|
+
- ".rspec"
|
|
50
|
+
- ".travis.yml"
|
|
51
|
+
- Gemfile
|
|
52
|
+
- LICENSE.txt
|
|
53
|
+
- README.md
|
|
54
|
+
- Rakefile
|
|
55
|
+
- barometer-weather_bug.gemspec
|
|
56
|
+
- lib/barometer/weather_bug.rb
|
|
57
|
+
- lib/barometer/weather_bug/current_api.rb
|
|
58
|
+
- lib/barometer/weather_bug/current_response.rb
|
|
59
|
+
- lib/barometer/weather_bug/forecast_api.rb
|
|
60
|
+
- lib/barometer/weather_bug/forecast_response.rb
|
|
61
|
+
- lib/barometer/weather_bug/query.rb
|
|
62
|
+
- lib/barometer/weather_bug/response/current_weather.rb
|
|
63
|
+
- lib/barometer/weather_bug/response/forecasted_weather.rb
|
|
64
|
+
- lib/barometer/weather_bug/response/location.rb
|
|
65
|
+
- lib/barometer/weather_bug/response/station.rb
|
|
66
|
+
- lib/barometer/weather_bug/response/sun.rb
|
|
67
|
+
- lib/barometer/weather_bug/response/time_helper.rb
|
|
68
|
+
- lib/barometer/weather_bug/response/timezone.rb
|
|
69
|
+
- lib/barometer/weather_bug/version.rb
|
|
70
|
+
- spec/cassettes/WeatherService_WeatherBug.json
|
|
71
|
+
- spec/spec_helper.rb
|
|
72
|
+
- spec/weather_bug/current_response_spec.rb
|
|
73
|
+
- spec/weather_bug/forecast_response_spec.rb
|
|
74
|
+
- spec/weather_bug/query_spec.rb
|
|
75
|
+
- spec/weather_bug_spec.rb
|
|
76
|
+
homepage: http://github.com/attack/barometer-weather_bug
|
|
77
|
+
licenses:
|
|
78
|
+
- MIT
|
|
79
|
+
metadata: {}
|
|
80
|
+
post_install_message:
|
|
81
|
+
rdoc_options: []
|
|
82
|
+
require_paths:
|
|
83
|
+
- lib
|
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 1.9.2
|
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
requirements: []
|
|
95
|
+
rubyforge_project:
|
|
96
|
+
rubygems_version: 2.2.2
|
|
97
|
+
signing_key:
|
|
98
|
+
specification_version: 4
|
|
99
|
+
summary: A barometer adapter for WeatherBug
|
|
100
|
+
test_files:
|
|
101
|
+
- spec/cassettes/WeatherService_WeatherBug.json
|
|
102
|
+
- spec/spec_helper.rb
|
|
103
|
+
- spec/weather_bug/current_response_spec.rb
|
|
104
|
+
- spec/weather_bug/forecast_response_spec.rb
|
|
105
|
+
- spec/weather_bug/query_spec.rb
|
|
106
|
+
- spec/weather_bug_spec.rb
|