google-weather 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +33 -0
- data/bin/weather +16 -0
- data/examples/forecast.rb +13 -0
- data/google-weather.gemspec +27 -0
- data/lib/google_weather.rb +31 -0
- data/lib/google_weather/data.rb +23 -0
- data/test/fixtures/46544.xml +1 -0
- data/test/google_weather_test.rb +129 -0
- data/test/test_helper.rb +14 -0
- metadata +114 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 John Nunemaker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a 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
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= google-weather
|
2
|
+
|
3
|
+
Stupid simple fetching of the weather using google's api
|
4
|
+
|
5
|
+
= example
|
6
|
+
|
7
|
+
See the examples directory . Trust me it is easy though.
|
8
|
+
|
9
|
+
http://github.com/jnunemaker/google-weather/tree/master/examples
|
10
|
+
|
11
|
+
== Copyright
|
12
|
+
|
13
|
+
Copyright (c) 2009 John Nunemaker. See LICENSE for details.
|
14
|
+
|
15
|
+
== Docs
|
16
|
+
|
17
|
+
http://rdoc.info/projects/jnunemaker/google-weather
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
Rake::RDocTask.new do |rdoc|
|
6
|
+
rdoc.rdoc_dir = 'rdoc'
|
7
|
+
rdoc.title = 'google-weather'
|
8
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
9
|
+
rdoc.rdoc_files.include('README*')
|
10
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake/testtask'
|
14
|
+
Rake::TestTask.new(:test) do |test|
|
15
|
+
test.libs << 'lib' << 'test'
|
16
|
+
test.pattern = 'test/**/*_test.rb'
|
17
|
+
test.verbose = false
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
require 'rcov/rcovtask'
|
22
|
+
Rcov::RcovTask.new do |test|
|
23
|
+
test.libs << 'test'
|
24
|
+
test.pattern = 'test/**/*_test.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
rescue LoadError
|
28
|
+
task :rcov do
|
29
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task :default => :test
|
data/bin/weather
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/google_weather'
|
4
|
+
|
5
|
+
if ARGV.size == 0
|
6
|
+
puts 'Weather [Powered by Google]'
|
7
|
+
puts 'USAGE: weather [zip code or city]'
|
8
|
+
puts 'EXAMPLES:'
|
9
|
+
puts ' weather 46544'
|
10
|
+
puts ' weather "mishawaka, in"'
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
|
14
|
+
weather = GoogleWeather.new(ARGV[0])
|
15
|
+
current = weather.current_conditions
|
16
|
+
puts "#{current.temp_f}° #{current.condition} - #{current.wind_condition} - #{current.humidity}"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/google_weather'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
weather = GoogleWeather.new(46544)
|
5
|
+
|
6
|
+
forecast = weather.forecast_conditions[0]
|
7
|
+
puts forecast.day_of_week, forecast.low, forecast.high, forecast.condition
|
8
|
+
|
9
|
+
pp weather.forecast_information
|
10
|
+
puts
|
11
|
+
pp weather.current_conditions
|
12
|
+
puts
|
13
|
+
pp weather.forecast_conditions
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/google_weather/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "google-weather"
|
6
|
+
s.version = GoogleWeather::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["John Nunemaker"]
|
9
|
+
s.email = ["nunemaker@gmail.com"]
|
10
|
+
s.homepage = "http://rubygems.org/gems/google-weather"
|
11
|
+
s.summary = "stupid simple fetching of the weather using google's api"
|
12
|
+
s.description = "stupid simple fetching of the weather using google's api"
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
s.rubyforge_project = "google-weather"
|
16
|
+
|
17
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
18
|
+
s.add_dependency "httparty", "0.5.2"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
22
|
+
s.require_path = 'lib'
|
23
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
|
24
|
+
s.has_rdoc = true
|
25
|
+
s.homepage = "http://github.com/jnunemaker/google-weather"
|
26
|
+
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'httparty'
|
3
|
+
require 'httparty'
|
4
|
+
require File.dirname(__FILE__) + '/google_weather/data'
|
5
|
+
|
6
|
+
class GoogleWeather
|
7
|
+
include HTTParty
|
8
|
+
base_uri "www.google.com"
|
9
|
+
|
10
|
+
attr_reader :zip
|
11
|
+
|
12
|
+
def initialize(zip)
|
13
|
+
@zip = zip
|
14
|
+
end
|
15
|
+
|
16
|
+
def weather
|
17
|
+
@weather ||= self.class.get("/ig/api", :query => {:weather => @zip}, :format => :xml)['xml_api_reply']['weather']
|
18
|
+
end
|
19
|
+
|
20
|
+
def forecast_information
|
21
|
+
@forecast_information ||= ForecastInformation.new(weather['forecast_information'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_conditions
|
25
|
+
@current_conditions ||= CurrentConditions.new(weather['current_conditions'])
|
26
|
+
end
|
27
|
+
|
28
|
+
def forecast_conditions
|
29
|
+
@forecast_conditions ||= weather['forecast_conditions'].map { |cond| ForecastCondition.new(cond) }
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class GoogleWeather
|
2
|
+
class Data
|
3
|
+
attr_reader :data
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method)
|
10
|
+
key = data[method.to_s]
|
11
|
+
key && key['data']
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
data = @data.inject([]) { |collection, key| collection << "#{key[0]}: #{key[1]['data']}"; collection }.join("\n ")
|
16
|
+
"#<#{self.class}:0x#{object_id}\n #{data}>"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ForecastInformation < Data; end
|
21
|
+
class CurrentConditions < Data; end
|
22
|
+
class ForecastCondition < Data; end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1"><forecast_information><city data="Mishawaka, IN"/><postal_code data="46544"/><latitude_e6 data=""/><longitude_e6 data=""/><forecast_date data="2009-03-24"/><current_date_time data="2009-03-25 04:16:27 +0000"/><unit_system data="US"/></forecast_information><current_conditions><condition data="Overcast"/><temp_f data="62"/><temp_c data="17"/><humidity data="Humidity: 48%"/><icon data="/images/weather/cloudy.gif"/><wind_condition data="Wind: SE at 11 mph"/></current_conditions><forecast_conditions><day_of_week data="Tue"/><low data="45"/><high data="67"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="Partly Sunny"/></forecast_conditions><forecast_conditions><day_of_week data="Wed"/><low data="34"/><high data="52"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="Mostly Sunny"/></forecast_conditions><forecast_conditions><day_of_week data="Thu"/><low data="36"/><high data="54"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="Mostly Sunny"/></forecast_conditions><forecast_conditions><day_of_week data="Fri"/><low data="38"/><high data="56"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="Mostly Sunny"/></forecast_conditions></weather></xml_api_reply>
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GoogleWeatherTest < Test::Unit::TestCase
|
4
|
+
context "Initialization" do
|
5
|
+
should "require a zip code" do
|
6
|
+
lambda { GoogleWeather.new }.should raise_error
|
7
|
+
|
8
|
+
GoogleWeather.new(46544).zip.should == 46544
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "Data" do
|
13
|
+
setup do
|
14
|
+
@data = GoogleWeather::Data.new({'foo' => {'data' => 'bar'}})
|
15
|
+
end
|
16
|
+
|
17
|
+
should "use method missing to get value for existing keys" do
|
18
|
+
@data.foo.should == 'bar'
|
19
|
+
end
|
20
|
+
|
21
|
+
should "return nil for missing keys" do
|
22
|
+
@data.foobar.should be(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
context "Fetching" do
|
28
|
+
setup do
|
29
|
+
FakeWeb.register_uri(:get, "http://www.google.com/ig/api?weather=46544", :string => File.read("fixtures/46544.xml"))
|
30
|
+
@weather = GoogleWeather.new(46544)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "have forecast information" do
|
34
|
+
information = @weather.forecast_information
|
35
|
+
information.city.should == 'Mishawaka, IN'
|
36
|
+
information.postal_code.should == '46544'
|
37
|
+
information.unit_system.should == 'US'
|
38
|
+
information.forecast_date.should == '2009-03-24'
|
39
|
+
information.current_date_time.should == '2009-03-25 04:16:27 +0000'
|
40
|
+
end
|
41
|
+
|
42
|
+
should "have current conditions" do
|
43
|
+
conditions = @weather.current_conditions
|
44
|
+
conditions.humidity.should == 'Humidity: 48%'
|
45
|
+
conditions.icon.should == '/images/weather/cloudy.gif'
|
46
|
+
conditions.temp_c.should == '17'
|
47
|
+
conditions.temp_f.should == '62'
|
48
|
+
conditions.condition.should == 'Overcast'
|
49
|
+
conditions.wind_condition.should == 'Wind: SE at 11 mph'
|
50
|
+
end
|
51
|
+
|
52
|
+
should "have forecast conditions" do
|
53
|
+
conditions = @weather.forecast_conditions
|
54
|
+
conditions[0].low.should == '45'
|
55
|
+
conditions[0].high.should == '67'
|
56
|
+
conditions[0].icon.should == '/images/weather/mostly_sunny.gif'
|
57
|
+
conditions[0].condition.should == 'Partly Sunny'
|
58
|
+
conditions[0].day_of_week.should == 'Tue'
|
59
|
+
conditions[1].low.should == '34'
|
60
|
+
conditions[1].high.should == '52'
|
61
|
+
conditions[1].icon.should == '/images/weather/mostly_sunny.gif'
|
62
|
+
conditions[1].condition.should == 'Mostly Sunny'
|
63
|
+
conditions[1].day_of_week.should == 'Wed'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
__END__
|
69
|
+
|
70
|
+
Example hash that comes back from Google
|
71
|
+
|
72
|
+
{
|
73
|
+
"xml_api_reply"=> {
|
74
|
+
"version"=>"1",
|
75
|
+
"weather"=> {
|
76
|
+
"mobile_row"=>"0",
|
77
|
+
"mobile_zipped"=>"1",
|
78
|
+
"module_id"=>"0",
|
79
|
+
"forecast_information"=>{
|
80
|
+
"city"=>{"data"=>"Mishawaka, IN"},
|
81
|
+
"postal_code"=>{"data"=>"46544"},
|
82
|
+
"longitude_e6"=>{"data"=>""},
|
83
|
+
"current_date_time"=>{"data"=>"2009-03-25 04:16:27 +0000"},
|
84
|
+
"latitude_e6"=>{"data"=>""},
|
85
|
+
"forecast_date"=>{"data"=>"2009-03-24"},
|
86
|
+
"unit_system"=>{"data"=>"US"}
|
87
|
+
},
|
88
|
+
"current_conditions"=> {
|
89
|
+
"humidity"=>{"data"=>"Humidity: 48%"},
|
90
|
+
"icon"=>{"data"=>"/images/weather/cloudy.gif"},
|
91
|
+
"condition"=>{"data"=>"Overcast"},
|
92
|
+
"temp_c"=>{"data"=>"17"},
|
93
|
+
"wind_condition"=>{"data"=>"Wind: SE at 11 mph"},
|
94
|
+
"temp_f"=>{"data"=>"62"}
|
95
|
+
},
|
96
|
+
"tab_id"=>"0",
|
97
|
+
"forecast_conditions"=>[
|
98
|
+
{
|
99
|
+
"high"=>{"data"=>"67"},
|
100
|
+
"day_of_week"=>{"data"=>"Tue"},
|
101
|
+
"icon"=>{"data"=>"/images/weather/mostly_sunny.gif"},
|
102
|
+
"condition"=>{"data"=>"Partly Sunny"},
|
103
|
+
"low"=>{"data"=>"45"}
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"high"=>{"data"=>"52"},
|
107
|
+
"day_of_week"=>{"data"=>"Wed"},
|
108
|
+
"icon"=>{"data"=>"/images/weather/mostly_sunny.gif"},
|
109
|
+
"condition"=>{"data"=>"Mostly Sunny"},
|
110
|
+
"low"=>{"data"=>"34"}
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"high"=>{"data"=>"54"},
|
114
|
+
"day_of_week"=>{"data"=>"Thu"},
|
115
|
+
"icon"=>{"data"=>"/images/weather/mostly_sunny.gif"},
|
116
|
+
"condition"=>{"data"=>"Mostly Sunny"},
|
117
|
+
"low"=>{"data"=>"36"}
|
118
|
+
},
|
119
|
+
{
|
120
|
+
"high"=>{"data"=>"56"},
|
121
|
+
"day_of_week"=>{"data"=>"Fri"},
|
122
|
+
"icon"=>{"data"=>"/images/weather/mostly_sunny.gif"},
|
123
|
+
"condition"=>{"data"=>"Mostly Sunny"},
|
124
|
+
"low"=>{"data"=>"38"}
|
125
|
+
}
|
126
|
+
]
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'matchy'
|
5
|
+
require 'fakeweb'
|
6
|
+
|
7
|
+
FakeWeb.allow_net_connect = false
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
11
|
+
require 'google_weather'
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: google-weather
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- John Nunemaker
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-12 00:00:00 +10:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bundler
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 1.0.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: httparty
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - "="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 15
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 5
|
49
|
+
- 2
|
50
|
+
version: 0.5.2
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
description: stupid simple fetching of the weather using google's api
|
54
|
+
email:
|
55
|
+
- nunemaker@gmail.com
|
56
|
+
executables:
|
57
|
+
- weather
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files:
|
61
|
+
- README.rdoc
|
62
|
+
- LICENSE
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- LICENSE
|
66
|
+
- README.rdoc
|
67
|
+
- Rakefile
|
68
|
+
- bin/weather
|
69
|
+
- examples/forecast.rb
|
70
|
+
- google-weather.gemspec
|
71
|
+
- lib/google_weather.rb
|
72
|
+
- lib/google_weather/data.rb
|
73
|
+
- test/fixtures/46544.xml
|
74
|
+
- test/google_weather_test.rb
|
75
|
+
- test/test_helper.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/jnunemaker/google-weather
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --inline-source
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 23
|
101
|
+
segments:
|
102
|
+
- 1
|
103
|
+
- 3
|
104
|
+
- 6
|
105
|
+
version: 1.3.6
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: google-weather
|
109
|
+
rubygems_version: 1.3.7
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: stupid simple fetching of the weather using google's api
|
113
|
+
test_files: []
|
114
|
+
|