sunwatch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc61d157134686bb9e81364c4e6256c8c19cfa76
4
+ data.tar.gz: cbd1035338fb569bff8d9b19f978eed5f6ed65b2
5
+ SHA512:
6
+ metadata.gz: b0fde179369635f18a32b9f6bf381d067f0dc953c9d45ff8fedcfe1a623193a18016c5ef09acb3f06280e0d1550fff6eefa06d9ba27382f3125e40f33fc2801c
7
+ data.tar.gz: fe3c0d01527cfd07b15ef4da21eae03902816cbd4728871d0b146a92247e622e2b2353c02ee44804f2b97449a24bb944fbdb3e16622f5db863ab1364d4641e5a
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jason Stenhouse
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.
@@ -0,0 +1,40 @@
1
+ ## Sunwatch
2
+
3
+ Provides daily or hourly UV information for the US by zipcode or city/state. UV data is provided by the EPA.
4
+
5
+ ### Usage
6
+
7
+ Daily UV info:
8
+
9
+ require 'sunwatch'
10
+
11
+ Sunwatch.daily_uv_info_for(city: 'Seattle', state: 'WA')
12
+ # or
13
+ Sunwatch.daily_uv_info_for(zipcode: '98103')
14
+
15
+ # return type
16
+ uv_info = Sunwatch.daily_uv_info_for(zipcode: '98103')
17
+ uv_info.zipcode # => 98103
18
+ uv_info.uv_index # => 3
19
+ uv_info.uv_alert # => 1
20
+
21
+ Hourly UV info:
22
+
23
+ require 'sunwatch'
24
+
25
+ Sunwatch.hourly_uv_info_for(city: 'Seattle', state: 'WA')
26
+ Sunwatch.hourly_uv_info_for(zipcode: '98103')
27
+
28
+ # return type
29
+ uv_info = Sunwatch.hourly_uv_info_for(zipcode: '98103')
30
+ uv_info.zipcode # => 98103
31
+
32
+ uv_info.hours.each do |hour|
33
+
34
+ ## Contributing
35
+
36
+ 1. [Fork it](https://github/jstenhouse/sunwatch/fork)
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create a new Pull Request
@@ -0,0 +1,5 @@
1
+ require 'sunwatch/version'
2
+ require 'sunwatch/errors'
3
+ require 'sunwatch/response'
4
+ require 'sunwatch/client'
5
+ require 'sunwatch/sunwatch'
@@ -0,0 +1,70 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module Sunwatch
5
+ class Client
6
+
7
+ EPA_UV_URI = 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUV'
8
+
9
+ def self.uv_info_for(opts)
10
+ url = build_url(opts)
11
+ response = HTTParty.get(url)
12
+ raise_unavailable_error if response.code != 200
13
+ build_response(JSON.parse(response.body))
14
+ rescue HTTParty::Error => e
15
+ raise_unavailable_error(e.message)
16
+ end
17
+
18
+ private
19
+
20
+ def self.build_response(response)
21
+ if response.size == 1
22
+ build_daily_response(response.first)
23
+ else
24
+ build_hourly_response(response)
25
+ end
26
+ end
27
+
28
+ def self.build_daily_response(response)
29
+ Sunwatch::Response.new(city: response['CITY'],
30
+ state: response['STATE'],
31
+ zipcode: response['ZIP_CODE'],
32
+ uv_index: response['UV_INDEX'],
33
+ uv_alert: response['UV_ALERT'])
34
+ end
35
+
36
+ def self.build_hourly_response(response)
37
+ hours = []
38
+ response.each do |hour|
39
+ hours << { datetime: hour['DATE_TIME'], uv_value: hour['UV_VALUE'] }
40
+ end
41
+ Sunwatch::Response.new(city: response.first['CITY'],
42
+ state: response.first['STATE'],
43
+ zipcode: response.first['ZIP'], # wat. API uses ZIP for hourly, and ZIP_CODE for daily
44
+ hours: hours)
45
+ end
46
+
47
+ def self.raise_unavailable_error(msg = '')
48
+ raise Sunwatch::UnavailableError.new("UV Index info is unavailable: #{msg}")
49
+ end
50
+
51
+ def self.build_url(opts)
52
+ uri_timewindow = build_url_timewindow(opts)
53
+ uri_location = build_url_location(opts)
54
+ "#{EPA_UV_URI}#{uri_timewindow}/#{uri_location}/json"
55
+ end
56
+
57
+ def self.build_url_timewindow(opts)
58
+ opts[:timewindow] == :daily ? 'DAILY' : 'HOURLY'
59
+ end
60
+
61
+ def self.build_url_location(opts)
62
+ if opts[:zipcode]
63
+ "ZIP/#{opts[:zipcode]}"
64
+ else
65
+ "CITY/#{opts[:city]}/STATE/#{opts[:state]}"
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ module Sunwatch
2
+ class ConfigurationError < StandardError; end
3
+ class UnavailableError < StandardError; end
4
+ end
@@ -0,0 +1,46 @@
1
+ module Sunwatch
2
+ class Response
3
+ Hour = Struct.new(:datetime, :uv_value)
4
+
5
+ attr_accessor :city, :state, :zipcode, :uv_index, :uv_alert, :hours
6
+
7
+ def initialize(opts)
8
+ @city = opts[:city]
9
+ @state = opts[:state]
10
+ @zipcode = opts[:zipcode]
11
+ @uv_index = opts[:uv_index]
12
+ @uv_alert = opts[:uv_alert]
13
+ if opts[:hours]
14
+ @hours = []
15
+ opts[:hours].each do |hour|
16
+ @hours << Hour.new(to_datetime(hour[:datetime]), hour[:uv_value])
17
+ end
18
+ end
19
+ end
20
+
21
+ def hourly?
22
+ @hours != nil
23
+ end
24
+
25
+ def daily?
26
+ @hours == nil
27
+ end
28
+
29
+ def ==(other)
30
+ self.class == other.class &&
31
+ @city == other.city &&
32
+ @state == other.state &&
33
+ @zipcode == other.zipcode &&
34
+ @uv_index == other.uv_index &&
35
+ @uv_alert == other.uv_alert &&
36
+ @hours == other.hours
37
+ end
38
+
39
+ private
40
+
41
+ def to_datetime(str_datetime)
42
+ # OCT/19/2014 05 AM
43
+ DateTime.strptime(str_datetime, "%b/%d/%Y %I %p")
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,40 @@
1
+ module Sunwatch
2
+ def self.daily_uv_info_for(opts = {})
3
+ validate_opts!(opts)
4
+ opts[:zipcode] = opts[:zipcode].to_s if opts[:zipcode] # allow integers
5
+ opts[:timewindow] = :daily
6
+ Sunwatch::Client.uv_info_for(opts)
7
+ end
8
+
9
+ def self.hourly_uv_info_for(opts = {})
10
+ validate_opts!(opts)
11
+ opts[:zipcode] = opts[:zipcode].to_s if opts[:zipcode] # allow integers
12
+ opts[:timewindow] = :hourly
13
+ Sunwatch::Client.uv_info_for(opts)
14
+ end
15
+
16
+ private
17
+
18
+ def self.validate_opts!(opts)
19
+ if opts[:zipcode]
20
+ validate_string_or_number!(:zipcode, opts[:zipcode])
21
+ elsif opts[:city] && opts[:state]
22
+ validate_string!(:city, opts[:city])
23
+ validate_string!(:state, opts[:state])
24
+ else
25
+ raise ConfigurationError.new('city/state or zipcode must be provided')
26
+ end
27
+ end
28
+
29
+ def self.validate_string!(opt, value)
30
+ unless value.respond_to?(:to_str)
31
+ raise ConfigurationError.new("#{opt.to_s} must be a string")
32
+ end
33
+ end
34
+
35
+ def self.validate_string_or_number!(opt, value)
36
+ unless value.respond_to?(:to_str) || value.respond_to?(:to_int)
37
+ raise ConfigurationError.new("#{opt.to_s} must be a string or integer")
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Sunwatch
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'webmock/rspec'
2
+ require 'sunwatch'
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sunwatch::Client do
4
+
5
+ describe '.uv_info_for' do
6
+
7
+ let(:daily_zipcode_json_response) { '[{"ZIP_CODE":12345,"UV_INDEX":2,"UV_ALERT":0}]' }
8
+ let(:daily_zipcode_response) { Sunwatch::Response.new(zipcode: 12345, uv_index: 2, uv_alert: 0) }
9
+
10
+ let(:daily_citystate_json_response) { '[{"CITY":"WASHINGTON","STATE":"DC","UV_INDEX":3,"UV_ALERT":1}]' }
11
+ let(:daily_citystate_response) { Sunwatch::Response.new(city: 'WASHINGTON', state: 'DC', uv_index: 3, uv_alert: 1) }
12
+
13
+ let(:hourly_zipcode_json_response) { '[{"ORDER":1,"ZIP":12345,"DATE_TIME":"OCT/18/2014 04 AM","UV_VALUE":0},{"ORDER":2,"ZIP":12345,"DATE_TIME":"OCT/18/2014 05 AM","UV_VALUE":1}]' }
14
+ let(:hourly_zipcode_response) { Sunwatch::Response.new(zipcode: 12345, hours: [{datetime: 'OCT/18/2014 04 AM', uv_value: 0}, {datetime: 'OCT/18/2014 05 AM', uv_value: 1}]) }
15
+
16
+ let(:hourly_citystate_json_response) { '[{"SEQUENCE":1,"CITY":"SEATTLE","STATE":"WA","DATE_TIME":"OCT/19/2014 04 AM","UV_VALUE":0},{"SEQUENCE":2,"CITY":"SEATTLE","STATE":"WA","DATE_TIME":"OCT/19/2014 05 AM","UV_VALUE":1}]' }
17
+ let(:hourly_citystate_response) { Sunwatch::Response.new(city: 'SEATTLE', state: 'WA', hours: [{datetime: 'OCT/19/2014 04 AM', uv_value: 0}, {datetime: 'OCT/19/2014 05 AM', uv_value: 1}]) }
18
+
19
+ before do
20
+ stub_request(:get, 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/ZIP/12345/json').to_return(body: daily_zipcode_json_response)
21
+ stub_request(:get, 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/CITY/Seattle/STATE/WA/json').to_return(body: daily_citystate_json_response)
22
+ stub_request(:get, 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/ZIP/12345/json').to_return(body: hourly_zipcode_json_response)
23
+ stub_request(:get, 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/CITY/Seattle/STATE/WA/json').to_return(body: hourly_citystate_json_response)
24
+ end
25
+
26
+ context 'a daily timewindow' do
27
+ context 'with zipcode' do
28
+ it 'fetches uv index info' do
29
+ response = Sunwatch::Client.uv_info_for(timewindow: :daily, zipcode: '12345')
30
+ expect(response).to eq(daily_zipcode_response)
31
+ end
32
+ end
33
+
34
+ context 'with city/state' do
35
+ it 'fetches uv index info' do
36
+ response = Sunwatch::Client.uv_info_for(timewindow: :daily, city: 'Seattle', state: 'WA')
37
+ expect(response).to eq(daily_citystate_response)
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'an hourly timewindow' do
43
+ context 'with zipcode' do
44
+ it 'fetches uv index info' do
45
+ response = Sunwatch::Client.uv_info_for(timewindow: :hourly, zipcode: '12345')
46
+ expect(response).to eq(hourly_zipcode_response)
47
+ end
48
+ end
49
+
50
+ context 'with city/state' do
51
+ it 'fetches uv index info' do
52
+ response = Sunwatch::Client.uv_info_for(timewindow: :hourly, city: 'Seattle', state: 'WA')
53
+ expect(response).to eq(hourly_citystate_response)
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'service unavailable' do
59
+
60
+ before do
61
+ stub_request(:get, 'http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/ZIP/12345/json').to_return(
62
+ :status => ["503", "Temporarily Unavailable"])
63
+ end
64
+
65
+ it 'raises a service unavailable error' do
66
+ expect { Sunwatch::Client.uv_info_for(timewindow: :hourly, zipcode: '12345') }.to raise_error Sunwatch::UnavailableError
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ describe '.build_url' do
73
+ context 'a daily timewindow' do
74
+ context 'with zipcode' do
75
+ it 'builds a daily timewindow with zipcode url' do
76
+ url = Sunwatch::Client.build_url(timewindow: :daily, zipcode: '12345')
77
+ expect(url).to eq('http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/ZIP/12345/json')
78
+ end
79
+ end
80
+
81
+ context 'with city/state' do
82
+ it 'builds a daily timewindow with city/state url' do
83
+ url = Sunwatch::Client.build_url(timewindow: :daily, city: 'Seattle', state: 'WA')
84
+ expect(url).to eq('http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/CITY/Seattle/STATE/WA/json')
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'an hourly timewindow' do
90
+ context 'with zipcode' do
91
+ it 'builds an hourly timewindow with zipcode url' do
92
+ url = Sunwatch::Client.build_url(timewindow: :hourly, zipcode: '12345')
93
+ expect(url).to eq('http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/ZIP/12345/json')
94
+ end
95
+ end
96
+
97
+ context 'with city/state' do
98
+ it 'builds an hourly timewindow with city/state url' do
99
+ url = Sunwatch::Client.build_url(timewindow: :hourly, city: 'Seattle', state: 'WA')
100
+ expect(url).to eq('http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/CITY/Seattle/STATE/WA/json')
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sunwatch do
4
+
5
+ describe '.daily_uv_info_for' do
6
+
7
+ context 'invalid options' do
8
+ context 'with only city' do
9
+ it 'raises a configuration error' do
10
+ expect { Sunwatch.daily_uv_info_for(city: 'Seattle') }.to raise_error Sunwatch::ConfigurationError
11
+ end
12
+ end
13
+
14
+ context 'with only state' do
15
+ it 'raises a configuration error' do
16
+ expect { Sunwatch.daily_uv_info_for(state: 'WA') }.to raise_error Sunwatch::ConfigurationError
17
+ end
18
+ end
19
+
20
+ context 'with non-string/non-number zipcode' do
21
+ it 'raises a configuration error' do
22
+ expect { Sunwatch.daily_uv_info_for(zipcode: Object.new) }.to raise_error Sunwatch::ConfigurationError
23
+ end
24
+ end
25
+
26
+ context 'with non-string city' do
27
+ it 'raises a configuration error' do
28
+ expect { Sunwatch.daily_uv_info_for(city: 1) }.to raise_error Sunwatch::ConfigurationError
29
+ end
30
+ end
31
+
32
+ context 'with non-string state' do
33
+ it 'raises a configuration error' do
34
+ expect { Sunwatch.daily_uv_info_for(state: 1) }.to raise_error Sunwatch::ConfigurationError
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'valid options' do
40
+ context 'with city and state' do
41
+ let(:valid_options) { { city: 'Seattle', state: 'WA' } }
42
+
43
+ it 'will send appropriate options to client' do
44
+ expect(Sunwatch::Client).to receive(:uv_info_for) { valid_options.merge(timewindow: :daily) }
45
+ Sunwatch.daily_uv_info_for(valid_options)
46
+ end
47
+ end
48
+
49
+ context 'with zipcode' do
50
+ let(:valid_options) { { zipcode: '12345' } }
51
+
52
+ it 'will send appropriate options to client' do
53
+ expect(Sunwatch::Client).to receive(:uv_info_for) { valid_options.merge(timewindow: :daily) }
54
+ Sunwatch.daily_uv_info_for(valid_options)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '.hourly_uv_info_for' do
61
+
62
+ context 'invalid options' do
63
+ context 'with only city' do
64
+ it 'raises a configuration error' do
65
+ expect { Sunwatch.hourly_uv_info_for(city: 'Seattle') }.to raise_error Sunwatch::ConfigurationError
66
+ end
67
+ end
68
+
69
+ context 'with only state' do
70
+ it 'raises a configuration error' do
71
+ expect { Sunwatch.hourly_uv_info_for(state: 'WA') }.to raise_error Sunwatch::ConfigurationError
72
+ end
73
+ end
74
+
75
+ context 'with non-string/non-number zipcode' do
76
+ it 'raises a configuration error' do
77
+ expect { Sunwatch.hourly_uv_info_for(zipcode: Object.new) }.to raise_error Sunwatch::ConfigurationError
78
+ end
79
+ end
80
+
81
+ context 'with non-string city' do
82
+ it 'raises a configuration error' do
83
+ expect { Sunwatch.hourly_uv_info_for(city: 1) }.to raise_error Sunwatch::ConfigurationError
84
+ end
85
+ end
86
+
87
+ context 'with non-string state' do
88
+ it 'raises a configuration error' do
89
+ expect { Sunwatch.hourly_uv_info_for(state: 1) }.to raise_error Sunwatch::ConfigurationError
90
+ end
91
+ end
92
+ end
93
+
94
+ context 'valid options' do
95
+ context 'with city and state' do
96
+ let(:valid_options) { { city: 'Seattle', state: 'WA' } }
97
+
98
+ it 'will send appropriate options to client' do
99
+ expect(Sunwatch::Client).to receive(:uv_info_for) { valid_options.merge(timewindow: :hourly) }
100
+ Sunwatch.hourly_uv_info_for(valid_options)
101
+ end
102
+ end
103
+
104
+ context 'with zipcode' do
105
+ let(:valid_options) { { zipcode: '12345' } }
106
+
107
+ it 'will send appropriate options to client' do
108
+ expect(Sunwatch::Client).to receive(:uv_info_for) { valid_options.merge(timewindow: :hourly) }
109
+ Sunwatch.hourly_uv_info_for(valid_options)
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ end
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
+
3
+ require 'sunwatch/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'sunwatch'
7
+ spec.version = Sunwatch::VERSION
8
+ spec.summary = 'Provides EPA UV index information for the US'
9
+ spec.description = 'Provides EPA UV index information for the US'
10
+ spec.authors = ['jstenhouse']
11
+ spec.email = 'jason.stenhouse@gmail.com'
12
+ spec.homepage = 'https://github.com/jstenhouse/sunwatch'
13
+ spec.licenses = ['MIT']
14
+
15
+ spec.files = `git ls-files`.split("\n")
16
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.add_dependency 'httparty'
20
+
21
+ spec.add_development_dependency 'rspec'
22
+ spec.add_development_dependency 'webmock'
23
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sunwatch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - jstenhouse
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
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
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Provides EPA UV index information for the US
56
+ email: jason.stenhouse@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".gitignore"
62
+ - Gemfile
63
+ - LICENSE
64
+ - README.md
65
+ - lib/sunwatch.rb
66
+ - lib/sunwatch/client.rb
67
+ - lib/sunwatch/errors.rb
68
+ - lib/sunwatch/response.rb
69
+ - lib/sunwatch/sunwatch.rb
70
+ - lib/sunwatch/version.rb
71
+ - spec/spec_helper.rb
72
+ - spec/sunwatch/client_spec.rb
73
+ - spec/sunwatch/sunwatch_spec.rb
74
+ - sunwatch.gemspec
75
+ homepage: https://github.com/jstenhouse/sunwatch
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.2.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Provides EPA UV index information for the US
99
+ test_files:
100
+ - spec/spec_helper.rb
101
+ - spec/sunwatch/client_spec.rb
102
+ - spec/sunwatch/sunwatch_spec.rb