weather-sage 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +88 -0
- data/Rakefile +16 -0
- data/bin/weather-sage +6 -0
- data/lib/weather-sage.rb +25 -0
- data/license.txt +20 -0
- data/test/make-csvs.sh +10 -0
- data/test/test-cache.rb +64 -0
- data/test/test-census-geocoder.rb +49 -0
- data/test/test-helpers.rb +24 -0
- data/test/test-http-cache.rb +103 -0
- data/test/test-weather-point.rb +32 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 390dc567cf5a2696830a36bd2a6a27020a2310721a95f69530ccbd0688c06d28
|
4
|
+
data.tar.gz: 9fc5165689410c41763750e06b5590452294f2588880cb2f027dbe98191e0be6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b23545938bb233191fb042f1cb7d45c098332421dbfb53c6fae126f5a3ef8f6543d75c16d4537582222e519e7da320fc11abbcaadaeed0f7fd4fcb31f83cdefc
|
7
|
+
data.tar.gz: 1541a3ef620d4667e45fe513f95f61e891ff259ab0309c4286ca709498eca8bca2972d9ede59e0587bd51dbacb9403c9ebdff1d491af33320f58400fae619c9f
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
Weather Sage
|
2
|
+
============
|
3
|
+
Ruby library and command-line tool to get the weather forecast and
|
4
|
+
current weather observations for an address.
|
5
|
+
|
6
|
+
Uses the [Census Bureau Geocoding API][census-api] to geocode street
|
7
|
+
addresses, and the [National Weather Service Weather API][weather-api]
|
8
|
+
to get weather forecasts and current weather observations.
|
9
|
+
|
10
|
+
Here's an example of using the command-line tool to get the current
|
11
|
+
weather forecast for the address "1600 pennsylvania ave nw, washington
|
12
|
+
dc":
|
13
|
+
|
14
|
+
```
|
15
|
+
> bin/weather-sage forecast '1600 pennsylvania ave nw washington dc'
|
16
|
+
address,name,temperature,temperature_unit,wind_speed,wind_direction,short_forecast
|
17
|
+
1600 pennsylvania ave washington dc,Today,97,F,7 mph,SW,Scattered Showers And Thunderstorms
|
18
|
+
1600 pennsylvania ave washington dc,Tonight,76,F,2 to 7 mph,SW,Scattered Showers And Thunderstorms then Mostly Cloudy
|
19
|
+
1600 pennsylvania ave washington dc,Tuesday,94,F,6 mph,E,Slight Chance Rain Showers then Chance Showers And Thunderstorms
|
20
|
+
1600 pennsylvania ave washington dc,Tuesday Night,75,F,2 to 6 mph,S,Chance Showers And Thunderstorms
|
21
|
+
1600 pennsylvania ave washington dc,Wednesday,94,F,3 to 9 mph,SW,Chance Showers And Thunderstorms
|
22
|
+
1600 pennsylvania ave washington dc,Wednesday Night,76,F,5 to 8 mph,SW,Chance Showers And Thunderstorms
|
23
|
+
...
|
24
|
+
```
|
25
|
+
|
26
|
+
Installation
|
27
|
+
------------
|
28
|
+
Install via [RubyGems][]:
|
29
|
+
|
30
|
+
```
|
31
|
+
# install weather-sage
|
32
|
+
> sudo gem install weather-sage
|
33
|
+
```
|
34
|
+
|
35
|
+
Examples
|
36
|
+
--------
|
37
|
+
**Get weather forecast for an address:**
|
38
|
+
```
|
39
|
+
# get weather forecast for address
|
40
|
+
> bin/weather-sage forecast '1600 pennsylvania ave washington dc'
|
41
|
+
address,name,temperature,temperature_unit,wind_speed,wind_direction,short_forecast
|
42
|
+
1600 pennsylvania ave washington dc,Today,97,F,7 mph,SW,Scattered Showers And Thunderstorms
|
43
|
+
1600 pennsylvania ave washington dc,Tonight,76,F,2 to 7 mph,SW,Scattered Showers And Thunderstorms then Mostly Cloudy
|
44
|
+
1600 pennsylvania ave washington dc,Tuesday,94,F,6 mph,E,Slight Chance Rain Showers then Chance Showers And Thunderstorms
|
45
|
+
1600 pennsylvania ave washington dc,Tuesday Night,75,F,2 to 6 mph,S,Chance Showers And Thunderstorms
|
46
|
+
1600 pennsylvania ave washington dc,Wednesday,94,F,3 to 9 mph,SW,Chance Showers And Thunderstorms
|
47
|
+
1600 pennsylvania ave washington dc,Wednesday Night,76,F,5 to 8 mph,SW,Chance Showers And Thunderstorms
|
48
|
+
...
|
49
|
+
```
|
50
|
+
|
51
|
+
**Get current observations from nearest weather station:**
|
52
|
+
```
|
53
|
+
# get current observations from nearest weather station
|
54
|
+
> weather-sage now '1600 pennsylvania ave washington dc'
|
55
|
+
address,name,type,value,unit,quality_control
|
56
|
+
1600 pennsylvania ave washington dc,timestamp,time,2019-08-19T06:52:00+00:00
|
57
|
+
1600 pennsylvania ave washington dc,textDescription,text,Mostly Cloudy
|
58
|
+
1600 pennsylvania ave washington dc,temperature,value,26.700000000000045,unit:degC,qc:V
|
59
|
+
1600 pennsylvania ave washington dc,relativeHumidity,value,81.65039907186703,unit:percent,qc:C
|
60
|
+
...
|
61
|
+
```
|
62
|
+
|
63
|
+
Commands
|
64
|
+
--------
|
65
|
+
Available commands in command-line interface.
|
66
|
+
|
67
|
+
* `forecast`: Get weather forecast for address.
|
68
|
+
* `geocode`: Geocode address.
|
69
|
+
* `help`: List commands.
|
70
|
+
* `hourly`: Get hourly weather forecast for address.
|
71
|
+
* `now`: Get current weather from station closest to address.
|
72
|
+
* `stations`: List weather stations near address.
|
73
|
+
|
74
|
+
Environment Variables
|
75
|
+
---------------------
|
76
|
+
The command-line tool can be configured via the following environment
|
77
|
+
variables:
|
78
|
+
|
79
|
+
* `WEATHER_SAGE_LOG_LEVEL`: Log level. One of: `fatal`, `error`,
|
80
|
+
`warning`, `info`, `debug`). Defaults to `warn`.
|
81
|
+
* `WEATHER_SAGE_LOG_PATH`: Path to log file. Defaults to standard error.
|
82
|
+
* `WEATHER_SAGE_CACHE_PATH`: Path to HTTP cache. Defaults to
|
83
|
+
`~/.config/weather-sage/http-cache.pstore`.
|
84
|
+
|
85
|
+
[ruby]: https://ruby-lang.org/ "Ruby programming language"
|
86
|
+
[rubygems]: https://rubygems.org/ "Ruby package manager"
|
87
|
+
[weather-api]: https://api.weather.gov/ "national Weather Service (NWS) Weather API"
|
88
|
+
[census-api]: https://geocoding.geo.census.gov/geocoder/ "Census Bureau Geocoding API"
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rdoc/task'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs << 'test'
|
6
|
+
end
|
7
|
+
|
8
|
+
RDoc::Task.new :docs do |t|
|
9
|
+
t.main = "lib/weather-sage.rb"
|
10
|
+
t.rdoc_files.include('lib/*.rb')
|
11
|
+
t.rdoc_dir = 'docs'
|
12
|
+
# t.options << "--all"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run tests"
|
16
|
+
task default: :test
|
data/bin/weather-sage
ADDED
data/lib/weather-sage.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Get weather forecast and current weather for address.
|
3
|
+
#
|
4
|
+
# Wrapper around the following APIs:
|
5
|
+
#
|
6
|
+
# * National Weather Service Weather API (https://api.weather.gov/)
|
7
|
+
# * Census Bureau Geocoder API (https://geocoding.geo.census.gov/geocoder/)
|
8
|
+
#
|
9
|
+
module WeatherSage
|
10
|
+
#
|
11
|
+
# Release version.
|
12
|
+
#
|
13
|
+
VERSION = '0.1.0'
|
14
|
+
|
15
|
+
# :nodoc:
|
16
|
+
LIB_DIR = File.join(__dir__, 'weather-sage').freeze
|
17
|
+
|
18
|
+
autoload :CacheEntry, File.join(LIB_DIR, 'cache-entry.rb')
|
19
|
+
autoload :Cache, File.join(LIB_DIR, 'cache.rb')
|
20
|
+
autoload :HTTP, File.join(LIB_DIR, 'http.rb')
|
21
|
+
autoload :Context, File.join(LIB_DIR, 'context.rb')
|
22
|
+
autoload :Census, File.join(LIB_DIR, 'census.rb')
|
23
|
+
autoload :Weather, File.join(LIB_DIR, 'weather.rb')
|
24
|
+
autoload :CLI, File.join(LIB_DIR, 'cli.rb')
|
25
|
+
end
|
data/license.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 Paul Duncan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included
|
12
|
+
in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/test/make-csvs.sh
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# TODO: move to rake task
|
4
|
+
ADDR='7309 carol ln falls church va 22042'
|
5
|
+
|
6
|
+
bin/weather-sage hourly -f "$ADDR" > hourly-full.csv
|
7
|
+
bin/weather-sage hourly -b "$ADDR" > hourly-brief.csv
|
8
|
+
bin/weather-sage forecast -b "$ADDR" > forecast-brief.csv
|
9
|
+
bin/weather-sage forecast -f "$ADDR" > forecast-full.csv
|
10
|
+
bin/weather-sage now "$ADDR" > now.csv
|
data/test/test-cache.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'fileutils'
|
3
|
+
require_relative '../lib/weather-sage'
|
4
|
+
|
5
|
+
class TestWeatherSageCache < Minitest::Test
|
6
|
+
def setup
|
7
|
+
# create temporary directory that is removed on exit
|
8
|
+
@dir = Dir.mktmpdir('test-cache')
|
9
|
+
at_exit { FileUtils.rm_r(@dir) }
|
10
|
+
|
11
|
+
# build absolute path to backing store for cache
|
12
|
+
path = File.join(@dir, 'cache.pstore')
|
13
|
+
|
14
|
+
# create cache instance
|
15
|
+
@cache = WeatherSage::Cache.new(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_new
|
19
|
+
# build absolute path to backing store for cache
|
20
|
+
path = File.join(@dir, 'test-new.pstore')
|
21
|
+
|
22
|
+
# asset that cache is not nil
|
23
|
+
assert WeatherSage::Cache.new(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_set
|
27
|
+
key, want = 'test_set', 'bar'
|
28
|
+
assert_equal want, @cache.set(key, want)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_get
|
32
|
+
# set value
|
33
|
+
key, want = 'test_get', 'bar'
|
34
|
+
@cache.set(key, want)
|
35
|
+
|
36
|
+
# get value, test result
|
37
|
+
got = @cache.get(key)
|
38
|
+
assert_equal want, got
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_key?
|
42
|
+
key, want = 'test_key?', 'bar'
|
43
|
+
@cache.set(key, want)
|
44
|
+
assert @cache.key?(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_set_timeout
|
48
|
+
key, want, timeout = 'test_set_timeout', 'bar', 10
|
49
|
+
|
50
|
+
# set long timeout, then get result before expiration
|
51
|
+
@cache.set(key, want, timeout)
|
52
|
+
assert_equal want, @cache.get(key)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_set_timeout_expired
|
56
|
+
key, want, timeout = 'test_set_timeout_expired', 'bar', 0.1
|
57
|
+
|
58
|
+
# set short timeout, then wait for it to pass
|
59
|
+
@cache.set(key, want, timeout)
|
60
|
+
sleep(timeout + 1)
|
61
|
+
|
62
|
+
assert_nil @cache.get(key)
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'logger'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../lib/weather-sage'
|
5
|
+
require_relative './test-helpers'
|
6
|
+
|
7
|
+
class TestWeatherSageCensusGeocoder < Minitest::Test
|
8
|
+
#
|
9
|
+
# Test addresses.
|
10
|
+
#
|
11
|
+
TESTS = [{
|
12
|
+
text: '2565 van buren st eugene or 97405',
|
13
|
+
want: [-123.109825, 44.03039],
|
14
|
+
}, {
|
15
|
+
text: '1600 pennsylvania ave nw washington dc',
|
16
|
+
want: [-77.03535, 38.898754],
|
17
|
+
}, {
|
18
|
+
text: '3150 fairview park dr falls church va 22042',
|
19
|
+
want: [-77.216194, 38.859795],
|
20
|
+
}]
|
21
|
+
|
22
|
+
def setup
|
23
|
+
# cache test context
|
24
|
+
@ctx = WeatherSage::Tests.get_test_context
|
25
|
+
|
26
|
+
# create and save geocoder
|
27
|
+
@geocoder = WeatherSage::Census::Geocoder.new(@ctx)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_new
|
31
|
+
# create new geocoder
|
32
|
+
assert WeatherSage::Census::Geocoder.new(@ctx)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_run
|
36
|
+
# assert that geocoder can geocode a single address
|
37
|
+
assert @geocoder.run(TESTS.first[:text])
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_results
|
41
|
+
TESTS.each do |test|
|
42
|
+
# geocode address, get first result
|
43
|
+
pt = @geocoder.run(test[:text]).first.point
|
44
|
+
|
45
|
+
assert_in_delta pt.x, test[:want][0]
|
46
|
+
assert_in_delta pt.y, test[:want][1]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WeatherSage::Tests
|
2
|
+
def self.get_test_context
|
3
|
+
unless @ctx
|
4
|
+
# create temporary directory that is removed on exit
|
5
|
+
@dir = Dir.mktmpdir('test-weather-sage')
|
6
|
+
at_exit { FileUtils.rm_r(@dir) }
|
7
|
+
|
8
|
+
# build absolute path to backing store for cache
|
9
|
+
cache_path = File.join(@dir, 'cache.pstore')
|
10
|
+
|
11
|
+
# create null logger
|
12
|
+
log = ::Logger.new('/dev/null')
|
13
|
+
|
14
|
+
# create cache instance
|
15
|
+
cache = WeatherSage::HTTP::Cache.new(cache_path, log)
|
16
|
+
|
17
|
+
# create and save context
|
18
|
+
@ctx = WeatherSage::Context.new(log, cache)
|
19
|
+
end
|
20
|
+
|
21
|
+
# return cached context
|
22
|
+
@ctx
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'logger'
|
5
|
+
require_relative '../lib/weather-sage'
|
6
|
+
|
7
|
+
class TestWeatherSageHttpCache < Minitest::Test
|
8
|
+
#
|
9
|
+
# list of test urls
|
10
|
+
#
|
11
|
+
URLS = {
|
12
|
+
good: 'https://pablotron.org/',
|
13
|
+
bad: 'https://pablotron.org/does-not-exist',
|
14
|
+
}
|
15
|
+
|
16
|
+
def setup
|
17
|
+
# create temporary directory that is removed on exit
|
18
|
+
@dir = Dir.mktmpdir('test-http-cache')
|
19
|
+
at_exit { FileUtils.rm_r(@dir) }
|
20
|
+
|
21
|
+
# build absolute path to backing store for cache
|
22
|
+
path = File.join(@dir, 'cache.pstore')
|
23
|
+
|
24
|
+
# create null logger
|
25
|
+
@log = ::Logger.new('/dev/null')
|
26
|
+
|
27
|
+
# create cache instance
|
28
|
+
@cache = WeatherSage::HTTP::Cache.new(path, @log)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_new
|
32
|
+
# build absolute path to backing store for cache
|
33
|
+
path = File.join(@dir, 'test-new.pstore')
|
34
|
+
|
35
|
+
# asset that cache is not nil
|
36
|
+
assert WeatherSage::HTTP::Cache.new(path, @log)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_new_timeout
|
40
|
+
# build absolute path to backing store for cache
|
41
|
+
path = File.join(@dir, 'test-new-timeout.pstore')
|
42
|
+
|
43
|
+
# set timeout to one second
|
44
|
+
timeout = 1
|
45
|
+
|
46
|
+
# create cache with timeout
|
47
|
+
cache = WeatherSage::HTTP::Cache.new(path, @log, timeout)
|
48
|
+
|
49
|
+
# asset that timeout is saved
|
50
|
+
assert_equal timeout, cache.timeout
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_new_timeout_expired
|
54
|
+
# build absolute path to backing store for cache
|
55
|
+
path = File.join(@dir, 'test-new-timeout.pstore')
|
56
|
+
|
57
|
+
# set timeout to one seconds
|
58
|
+
timeout = 1
|
59
|
+
|
60
|
+
# create cache with one second
|
61
|
+
cache = WeatherSage::HTTP::Cache.new(path, @log, timeout)
|
62
|
+
|
63
|
+
# get known good url
|
64
|
+
cache.get(URLS[:good])
|
65
|
+
|
66
|
+
# wait for entry to expire
|
67
|
+
sleep(timeout + 0.1)
|
68
|
+
|
69
|
+
# asset that entry is expired
|
70
|
+
assert !cache.key?(URLS[:good])
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_get
|
74
|
+
# read URl directly
|
75
|
+
want = read_url(URLS[:good])
|
76
|
+
|
77
|
+
# get URL through cache
|
78
|
+
got = @cache.get(URLS[:good])
|
79
|
+
|
80
|
+
# test result
|
81
|
+
assert_equal want, got
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_get_bad
|
85
|
+
assert_raises(WeatherSage::HTTP::Error) do
|
86
|
+
@cache.get(URLS[:bad])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
#
|
93
|
+
# Read given URL.
|
94
|
+
#
|
95
|
+
# Note: currently forces UTF-8 encoding.
|
96
|
+
#
|
97
|
+
def read_url(url)
|
98
|
+
# open(url, 'rb') { |fh| fh.read }
|
99
|
+
|
100
|
+
# read contents of URL, force UTF-8 encoding
|
101
|
+
open(url, 'rb', encoding: 'UTF-8') { |fh| fh.read }
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'logger'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../lib/weather-sage'
|
5
|
+
require_relative './test-helpers'
|
6
|
+
|
7
|
+
class WeatherSage::Tests::TestWeatherPoint < Minitest::Test
|
8
|
+
#
|
9
|
+
# Test addresses.
|
10
|
+
#
|
11
|
+
TESTS = [{
|
12
|
+
id: '2565 van buren st eugene or 97405',
|
13
|
+
pt: [-123.109825, 44.03039],
|
14
|
+
}, {
|
15
|
+
id: '1600 pennsylvania ave nw washington dc',
|
16
|
+
pt: [-77.03535, 38.898754],
|
17
|
+
}, {
|
18
|
+
id: '3150 fairview park dr falls church va 22042',
|
19
|
+
pt: [-77.216194, 38.859795],
|
20
|
+
}]
|
21
|
+
|
22
|
+
def setup
|
23
|
+
# cache test context
|
24
|
+
@ctx = WeatherSage::Tests.get_test_context
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_new
|
28
|
+
# create point from lat/long
|
29
|
+
x, y = TESTS.first[:pt]
|
30
|
+
assert WeatherSage::Weather::Point.new(@ctx, x, y)
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: weather-sage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Duncan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "\n Ruby library and command-line tool to get the weather forecast
|
14
|
+
and\n current weather observations for an address.\n\n Uses the Census Bureau
|
15
|
+
Geocoding API to geocode street addresses,\n and the National Weather Service
|
16
|
+
Weather API to get weather\n forecasts and current weather observations.\n "
|
17
|
+
email: pabs@pablotron.org
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- README.md
|
23
|
+
- Rakefile
|
24
|
+
- bin/weather-sage
|
25
|
+
- lib/weather-sage.rb
|
26
|
+
- license.txt
|
27
|
+
- test/make-csvs.sh
|
28
|
+
- test/test-cache.rb
|
29
|
+
- test/test-census-geocoder.rb
|
30
|
+
- test/test-helpers.rb
|
31
|
+
- test/test-http-cache.rb
|
32
|
+
- test/test-weather-point.rb
|
33
|
+
homepage: https://github.com/pablotron/weather-sage
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata:
|
37
|
+
bug_tracker_uri: https://github.com/pablotron/weather-sage/issues
|
38
|
+
documentation_uri: https://pablotron.github.io/weather-sage/
|
39
|
+
homepage_uri: https://github.com/pablotron/weather-sage
|
40
|
+
source_code_uri: https://github.com/pablotron/weather-sage
|
41
|
+
wiki_uri: https://github.com/pablotron/weather-sage/wiki
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 2.7.6.2
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: Get weather forecast for an address.
|
62
|
+
test_files: []
|