wunderground 1.0.0

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.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "json", "> 1.4.0"
4
+ gem "httparty", "> 0.6.0"
5
+ gem "addressable"
6
+
7
+ group :development, :test do
8
+ gem "shoulda", ">= 0"
9
+ gem "bundler", "~> 1.0.0"
10
+ gem "jeweler", "~> 1.5.1"
11
+ gem "simplecov", ">= 0"
12
+ gem "mocha", "> 0.9.11"
13
+ gem "ruby-debug19", :require => "ruby-debug", :platforms => [:ruby_19]
14
+ gem "ruby-debug", :platforms => [:ruby_18]
15
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Winfred Nadeau
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.markdown ADDED
@@ -0,0 +1,145 @@
1
+ # Wunderground Ruby API wrapper
2
+
3
+ Wunderground Ruby is an API wrapper for interacting with the [Wunderground API](http://www.wunderground.com/weather/api/)
4
+
5
+
6
+ ##Installation
7
+
8
+ $ gem install wunderground_ruby
9
+
10
+ or in your Gemfile
11
+
12
+ gem 'wunderground_ruby'
13
+
14
+ ##Requirements
15
+
16
+ A Wunderground account and API key.
17
+ If a request is attempted without an APIkey, this wrapper will raise a MissingAPIKey exception
18
+
19
+ JSON only at the moment.
20
+
21
+ ##Usage
22
+
23
+ You can create an instance of the API wrapper and pass it the API key:
24
+
25
+ w_api = Wunderground.new("your apikey")
26
+
27
+ You can also set the environment variable "WUNDERGROUND_API_KEY" and wunderground_ruby will use it when you create an instance:
28
+
29
+ w_api = Wunderground.new
30
+
31
+ This gem/wrapper uses some method_missing fun to make it easier to get feature and location data from Wunderground
32
+
33
+ Any number of [features](http://www.wunderground.com/weather/api/d/documentation.html#request) work by passing the features from the method straight into the request URL.
34
+
35
+ Check out below and test file for more examples.
36
+
37
+ Standard request breakdown:
38
+
39
+ wrapper_instance.[feature]_and_[another feature]_for("location string",optional: "hash", values: "at the end")
40
+
41
+ ##Optional Hash
42
+
43
+ This ugly little guy handles the nonconformists in Wunderground's API request structure and the pervasive request timeout option.
44
+ Luckily there are only three of these baddies, and only if you need them. (details below)
45
+
46
+ optional_hash = {lang: "FR", geo_ip:"127.0.0.1", timeout: 20}
47
+
48
+ Note: If needing to use these options, please place them as the last parameter(s) to the method call.
49
+
50
+ Can you think of a better way to handle these? Pull requests welcome.
51
+
52
+ ##Features
53
+
54
+ The method_missing magic happens here.
55
+
56
+ w_api.forecast_for("WA","Spokane")
57
+ w_api.forecast_and_conditions_for("1234.1234,-1234.1234") #a lat/long string
58
+ w_api.webcams_and_conditions_and_alerts_for("33043") #a zipcode
59
+
60
+ ##Locations
61
+
62
+ Any location string that Wunderground accepts will pass straight through this wrapper to their API, _except for a specific geo-ip._ (examples below)
63
+
64
+ #there is some handy array joining, if needed
65
+ w_api.forecast_for("WA/Spokane") #equivalent to the next example
66
+ w_api.forecast_for("WA","Spokane") #equivalent to the previous example
67
+
68
+ #zipcodes,lat/long, aiport codes, all of them just pass straight through this wrapper and into the request URL
69
+ w_api.conditions_for("77898")
70
+
71
+ #weather station code uniqueness - they use the 'pws:' prefix for weather station codes. So does this wrapper.
72
+ w_api.conditions_for("pws:STATIONCODE")
73
+
74
+ w_api.conditions_for("autoip") #passes straight through, but only gets the weather for your server's IP, so not very useful probably
75
+
76
+ For geocoding a specific ip address as the location, just provide an IP like this:
77
+
78
+ w_api.alerts_for(geo_ip: "127.0.0.1")
79
+
80
+ This was the quickest workaround to the non-conformity of the auto_ip request format.
81
+
82
+
83
+ ##Language Support
84
+
85
+ Because the Language modifier in Wunderground's request structure uses a colon, which doesn't jive with the method_missing design, adding a specific language to one request can be done like this:
86
+
87
+ w_api.forecast_for("France","Paris", lang 'FR')
88
+
89
+ Also, you can set the default language in the constructor or with a setter.
90
+
91
+ w_api = Wunderground.new("apikey",language: "FR")
92
+ w_api.language = 'FR'
93
+ w_api.forecast_for("France","Paris") #automatically includes /lang:FR/ in the request url, so results will be in French
94
+ w_api.forecast_for("France","Paris",lang: 'DE') #this will override the French(FR) default with German(DE)
95
+
96
+ ##History and Planner Helpers
97
+
98
+ While it is possible to call
99
+
100
+ w_api.history20101231_for("77789")
101
+ w_api.planner03150323_for("FL","Destin")
102
+
103
+ to get the history/planner data for this date/location. You may enjoy more flexibility when using history_for and planner_for:
104
+
105
+ w_api.history_for("20101010","AL","Birmingham")
106
+ w_api.history_for(1.year.ago,"33909")
107
+ w_api.history_for(Date.now, "France/Paris",lang: "FR")
108
+ w_api.history_for(Date.now, geo_ip:"123.4.5.6", lang: "FR")
109
+ w_api.planner_for("03150323","AL","Gulf Shores")
110
+ w_api.planner_for(Time.now,Time.now+7.days, geo_ip: "10.0.0.1")
111
+ w_api.planner_for(Time.now,Time.now+7.days,"33030")
112
+
113
+ .history_for and .planner_for accepts a preformatted string or any Date/Time/DateTime-like object that responds to .strftime to auto-format the date.
114
+
115
+
116
+ ## Request Timeout
117
+
118
+ wunderground_ruby defaults to a 30 second timeout. You can optionally set your own timeout (in seconds) in three ways like so:
119
+
120
+ w_api = Wunderground.new("apikey",timeout: 60)
121
+ w_api.timeout = 5
122
+ w_api.history_for(1.year.ago, geo_ip: '127.0.0.1', timeout:60)
123
+
124
+
125
+ ### Error Handling
126
+
127
+ By default you are expected to handle errors returned by the APIs manually. (see their documentation for more information about these errors)
128
+
129
+ If you set the `throws_exceptions` boolean attribute for a given instance then
130
+ wunderground_ruby will attempt to intercept the errors and raise an APIError exception if you feel like catching it.
131
+
132
+ ##Contributing
133
+
134
+ Do eet.
135
+
136
+ ##Thanks
137
+
138
+ * [Amro Mousa](https://github.com/amro) - design inspiration
139
+
140
+
141
+ ##Copyrights
142
+
143
+ * Copyright (c) 2012 Winfred Nadeau. See LICENSE.txt for details.
144
+
145
+ Winfred Nadeau is not affiliated with [Wunderground.com](http://wunderground.com), so check them out for licensing/copyright/legal/TOS details regarding their API and their data.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "wunderground"
16
+ gem.homepage = "http://github.com/wnadeau/wunderground_ruby"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{A simple ruby API wrapper for interacting with the Wunderground API}
19
+ gem.description = %Q{A simple ruby API wrapper for interacting with the Wunderground API}
20
+ gem.email = "winfred.nadeau@gmail.com"
21
+ gem.authors = ["Winfred Nadeau"]
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ task :default => :test
33
+
34
+ require 'rdoc/task'
35
+ Rake::RDocTask.new do |rdoc|
36
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
37
+
38
+ rdoc.rdoc_dir = 'rdoc'
39
+ rdoc.title = "Wunderground #{version}"
40
+ rdoc.rdoc_files.include('README*')
41
+ rdoc.rdoc_files.include('lib/**/*.rb')
42
+ end
43
+ desc "Open an irb session preloaded with this library"
44
+ task :console do
45
+ exec "irb -rubygems -I lib -r wunderground"
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,75 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'cgi'
4
+ require 'addressable/uri'
5
+
6
+ class Wunderground
7
+ include HTTParty
8
+ format :json
9
+ default_timeout 30
10
+
11
+ class MissingAPIKey < RuntimeError; end
12
+ class APIError < RuntimeError; end
13
+
14
+ attr_accessor :api_key, :timeout, :throws_exceptions, :language
15
+
16
+ def initialize(api_key = nil, extra_params = {})
17
+ @api_key = api_key || ENV['WUNDERGROUND_API_KEY'] || ENV['WUNDERGROUND_APIKEY'] || self.class.api_key
18
+ @timeout = extra_params[:timeout] || 30
19
+ @throws_exceptions = extra_params[:throws_exceptions] || false
20
+ @language = extra_params[:language]
21
+ end
22
+
23
+ def base_api_url
24
+ "http://api.wunderground.com/api/#{api_key}/"
25
+ end
26
+ def history_for(date,*args)
27
+ history = (date.class == String ? "history_#{date}" : "history_#{date.strftime("%Y%m%d")}")
28
+ send("#{history}_for",*args)
29
+ end
30
+ def planner_for(date,*args)
31
+ send("planner_#{date}_for",args) and return if date.class == String
32
+ range = date.strftime("%m%d") << args[0].strftime("%m%d")
33
+ args.delete_at(0)
34
+ send("planner_#{range}_for",*args)
35
+ end
36
+
37
+ protected
38
+
39
+ def call(method, timeout)
40
+ raise MissingAPIKey if @api_key.nil?
41
+ response = self.class.get(base_api_url << method, :timeout => (timeout || @timeout))
42
+ begin
43
+ response = JSON.parse(response.body)
44
+ rescue
45
+ response = response.body
46
+ end
47
+
48
+ if @throws_exceptions && response.is_a?(Hash) && response["response"]["error"]
49
+ raise APIError, "#{response["response"]["error"]["type"]}: #{response["response"]["error"]["description"]})"
50
+ end
51
+
52
+ response
53
+ end
54
+
55
+ def method_missing(method, *args)
56
+ raise NoMethodError, "undefined method: #{method} for Wunderground" unless method.to_s.end_with?("_for")
57
+ url = method.to_s.gsub("_for","").gsub("_and_","/")
58
+ url << "/lang:#{@language}" if @language
59
+ if args.last.instance_of? Hash
60
+ opts = args.pop
61
+ url = url.sub(/\/lang:.*/,'') and url << "/lang:#{opts[:lang]}" if opts[:lang]
62
+ ip_address = opts[:geo_ip] and args.push("autoip") if opts[:geo_ip]
63
+ timeout = opts[:timeout]
64
+ end
65
+ call(url <<'/q/'<< args.join('/') << ".json" << (ip_address ? "?geo_ip=#{ip_address}" : ''),timeout)
66
+ end
67
+
68
+ class << self
69
+ attr_accessor :api_key, :timeout
70
+ def method_missing(sym, *args, &block)
71
+ new(self.api_key, self.attributes).send(sym, *args, &block)
72
+ end
73
+ end
74
+ end
75
+
data/test/helper.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'test/unit'
13
+ require 'shoulda'
14
+ require 'mocha'
15
+
16
+
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+ require 'wunderground'
@@ -0,0 +1,201 @@
1
+ require 'helper'
2
+ require 'cgi'
3
+ require 'ruby-debug'
4
+ require 'addressable/uri'
5
+
6
+ class TestWunderground < Test::Unit::TestCase
7
+
8
+ context "attributes" do
9
+
10
+ setup do
11
+ @api_key = "12345"
12
+ end
13
+
14
+ should "have no API by default" do
15
+ @wunderground = Wunderground.new
16
+ assert_equal(nil, @wunderground.api_key)
17
+ end
18
+
19
+ should "set an API key in constructor" do
20
+ @wunderground = Wunderground.new(@api_key)
21
+ assert_equal(@api_key, @wunderground.api_key)
22
+ end
23
+ should 'set timeout and language in constructor' do
24
+ @wunderground = Wunderground.new(@api_key,timeout: 60, language: 'FR')
25
+ assert_equal(60,@wunderground.timeout)
26
+ assert_equal('FR',@wunderground.language)
27
+ end
28
+ should "set an API key from the 'WUNDERGROUND_API_KEY' ENV variable" do
29
+ ENV['WUNDERGROUND_API_KEY'] = @api_key
30
+ @wunderground = Wunderground.new
31
+ assert_equal(@api_key, @wunderground.api_key)
32
+ ENV.delete('WUNDERGROUND_API_KEY')
33
+ end
34
+
35
+ should "set an API key from the 'WUNDERGROUND_APIKEY' ENV variable" do
36
+ ENV['WUNDERGROUND_APIKEY'] = @api_key
37
+ @wunderground = Wunderground.new
38
+ assert_equal(@api_key, @wunderground.api_key)
39
+ ENV.delete('WUNDERGROUND_APIKEY')
40
+ end
41
+
42
+ should "set an API key via setter" do
43
+ @wunderground = Wunderground.new
44
+ @wunderground.api_key = @api_key
45
+ assert_equal(@api_key, @wunderground.api_key)
46
+ end
47
+
48
+ should "set and get timeout" do
49
+ @wunderground = Wunderground.new
50
+ timeout = 30
51
+ @wunderground.timeout = timeout
52
+ assert_equal(timeout, @wunderground.timeout)
53
+ end
54
+ end
55
+
56
+ context "api url" do
57
+ setup do
58
+ @wunderground = Wunderground.new("123")
59
+ @url = "http://api.wunderground.com/api/123/"
60
+ end
61
+ should "raise exception at empty api key" do
62
+ @wunderground.api_key=nil
63
+ expect_get(@url,{timeout:30})
64
+ assert_raise Wunderground::MissingAPIKey do
65
+ @wunderground.forecast_for("CA","San Fransisco")
66
+ end
67
+ end
68
+
69
+ should "contain api key" do
70
+ expect_get(@url+"forecast/q/ME/Portland.json",{timeout:30})
71
+ @wunderground.forecast_for("ME","Portland")
72
+ end
73
+ should 'contain multiple Wunderground methods from ruby method' do
74
+ expect_get(@url+"forecast/conditions/q/.json",{timeout: 30})
75
+ @wunderground.forecast_and_conditions_for()
76
+ end
77
+ should 'contain language modifier for method with {lang:"code"} hash' do
78
+ expect_get(@url+"forecast/lang:FR/q/ME/Portland.json",{timeout: 30})
79
+ @wunderground.forecast_for("ME","Portland", lang: 'FR')
80
+ end
81
+ context 'location parameter' do
82
+ should 'formats query of type array' do
83
+ expect_get(@url+"forecast/q/ME/Portland.json",{timeout: 30})
84
+ @wunderground.forecast_for("ME","Portland")
85
+ end
86
+ should 'formats query of type string' do
87
+ expect_get(@url+"forecast/q/1234.1234,-1234.1234.json",{timeout: 30})
88
+ @wunderground.forecast_for("1234.1234,-1234.1234")
89
+ expect_get(@url+"forecast/q/pws:WHAT.json",{timeout: 30})
90
+ @wunderground.forecast_for("pws:WHAT")
91
+ end
92
+ should 'formats query of type geo_ip' do
93
+ expect_get(@url+"forecast/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
94
+ @wunderground.forecast_for(geo_ip: "127.0.0.1")
95
+ end
96
+ end
97
+ context 'language support' do
98
+ setup {@wunderground.language = "FR"}
99
+ should 'automatically set language for all location types' do
100
+ expect_get(@url+"forecast/lang:FR/q/pws:KCATAHOE2.json",{timeout: 30})
101
+ @wunderground.forecast_for("pws:KCATAHOE2")
102
+ end
103
+ should 'have optional language override on call' do
104
+ expect_get(@url+"forecast/lang:DE/q/ME/Portland.json",{timeout: 30})
105
+ @wunderground.forecast_for("ME","Portland", lang: 'DE')
106
+ end
107
+ should 'pass language through history helper' do
108
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/lang:DE/q/ME/Portland.json",{timeout: 30})
109
+ @wunderground.history_for(Time.now,"ME","Portland",lang: 'DE')
110
+ end
111
+ should 'pass language through planner helper' do
112
+ expect_get(@url+"planner_#{Time.now.strftime("%m%d")}#{(Time.now + 700000).strftime('%m%d')}/lang:DE/q/ME/Portland.json",{timeout: 30})
113
+ @wunderground.planner_for(Time.now,(Time.now+700000),"ME","Portland", lang: 'DE')
114
+ end
115
+ should 'pass language through planner helper with IP' do
116
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now +
117
+ 700000).strftime('%m%d')}/lang:DE/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
118
+ @wunderground.planner_for(Time.now,(Time.now+700000),lang: "DE",geo_ip: "127.0.0.1")
119
+ end
120
+ should 'encode string arguments' do
121
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now +
122
+ 700000).strftime('%m%d')}/lang:DE/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
123
+ @wunderground.planner_for(Time.now,(Time.now+700000),lang: "DE",geo_ip: "127.0.0.1")
124
+ end
125
+ end
126
+ context 'for history_for(date,location) helper' do
127
+ should 'pass string dates straight to URL' do
128
+ expect_get(@url+"history_20110121/q/ME/Portland.json",{timeout: 30})
129
+ @wunderground.history_for("20110121","ME","Portland")
130
+ end
131
+ should 'accept Time objects' do
132
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
133
+ @wunderground.history_for(Time.now,"ME","Portland")
134
+ end
135
+ should 'accept Date objects' do
136
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
137
+ @wunderground.history_for(Time.now.to_date,"ME","Portland")
138
+ end
139
+ should 'accept Date object and pass optional hash object' do
140
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/lang:FR/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
141
+ @wunderground.history_for(Time.now.to_datetime,geo_ip: '127.0.0.1',lang: 'FR')
142
+ end
143
+ end
144
+ context 'for planner_for helper' do
145
+ should 'pass string date ranges through' do
146
+ expect_get(@url+"planner_03130323/q/ME/Portland.json",timeout: 30)
147
+ @wunderground.planner_for("03130323","ME","Portland")
148
+ end
149
+ should 'turn two date objects into a properly formatted string' do
150
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now +
151
+ 700000).strftime('%m%d')}/lang:FR/q/autoip.json?geo_ip=127.0.0.1",timeout: 30)
152
+ @wunderground.planner_for(Time.now,(Time.now + 700000),geo_ip: '127.0.0.1',lang:'FR')
153
+ end
154
+ end
155
+ context 'timeout passed through optional hash' do
156
+ should 'work for helper' do
157
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now+700000).strftime('%m%d')}/lang:FR/q/autoip.json?geo_ip=127.0.0.1",timeout: 60)
158
+ @wunderground.planner_for(Time.now,(Time.now + 700000),geo_ip: '127.0.0.1',lang:'FR',timeout: 60)
159
+ end
160
+ should 'work for regular calls' do
161
+ expect_get(@url+"forecast/q/pws:WHAT.json",timeout: 60)
162
+ @wunderground.forecast_for("pws:WHAT", timeout: 60)
163
+ end
164
+ end
165
+ end
166
+
167
+
168
+ context "Wunderground instances" do
169
+ setup do
170
+ @key = "TESTKEY"
171
+ @wunderground = Wunderground.new(@key)
172
+ @url = "http://api.wunderground.com/api/TESTKEY/forecast/q/ME/Portland.json"
173
+ @returns = Struct.new(:body).new(["array", "entries"].to_json)
174
+ end
175
+
176
+
177
+ should 'throw exception if non-standard function_for(location) method is called' do
178
+ assert_raise NoMethodError do
179
+ @wunderground.scramble
180
+ end
181
+ end
182
+
183
+ should "throw exception if configured to and the API replies with a JSON hash containing a key called 'error'" do
184
+ @wunderground.throws_exceptions = true
185
+ Wunderground.stubs(:get).returns(Struct.new(:body).new({response:{'error' => 'bad things'}}.to_json))
186
+ assert_raise Wunderground::APIError do
187
+ @wunderground.forecast_for("CA","San_Fransisco")
188
+ end
189
+ end
190
+ end
191
+
192
+
193
+ private
194
+
195
+ def expect_get(expected_url,expected_options={})
196
+ Wunderground.expects(:get).with{|url, opts|
197
+ url == expected_url &&
198
+ opts[:timeout] == expected_options[:timeout]
199
+ }.returns(Struct.new(:body).new("") )
200
+ end
201
+ end
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "wunderground"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Winfred Nadeau"]
12
+ s.date = "2012-07-03"
13
+ s.description = "A simple ruby API wrapper for interacting with the Wunderground API"
14
+ s.email = "winfred.nadeau@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "LICENSE.txt",
22
+ "README.markdown",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/wunderground.rb",
26
+ "test/helper.rb",
27
+ "test/test_wunderground.rb",
28
+ "wunderground.gemspec",
29
+ "wunderground_ruby.gemspec"
30
+ ]
31
+ s.homepage = "http://github.com/wnadeau/wunderground_ruby"
32
+ s.licenses = ["MIT"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = "1.8.10"
35
+ s.summary = "A simple ruby API wrapper for interacting with the Wunderground API"
36
+ s.test_files = [
37
+ "test/helper.rb",
38
+ "test/test_wunderground.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<json>, ["> 1.4.0"])
46
+ s.add_runtime_dependency(%q<httparty>, ["> 0.6.0"])
47
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
48
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
49
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
51
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
52
+ s.add_development_dependency(%q<mocha>, ["> 0.9.11"])
53
+ s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
54
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
55
+ else
56
+ s.add_dependency(%q<json>, ["> 1.4.0"])
57
+ s.add_dependency(%q<httparty>, ["> 0.6.0"])
58
+ s.add_dependency(%q<addressable>, [">= 0"])
59
+ s.add_dependency(%q<shoulda>, [">= 0"])
60
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
62
+ s.add_dependency(%q<simplecov>, [">= 0"])
63
+ s.add_dependency(%q<mocha>, ["> 0.9.11"])
64
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
65
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
66
+ end
67
+ else
68
+ s.add_dependency(%q<json>, ["> 1.4.0"])
69
+ s.add_dependency(%q<httparty>, ["> 0.6.0"])
70
+ s.add_dependency(%q<addressable>, [">= 0"])
71
+ s.add_dependency(%q<shoulda>, [">= 0"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
73
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
74
+ s.add_dependency(%q<simplecov>, [">= 0"])
75
+ s.add_dependency(%q<mocha>, ["> 0.9.11"])
76
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
77
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
78
+ end
79
+ end
80
+
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "wunderground_ruby"
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Winfred Nadeau"]
12
+ s.date = "2012-01-22"
13
+ s.description = "A simple ruby API wrapper for interacting with the Wunderground API"
14
+ s.email = "winfred.nadeau@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "LICENSE.txt",
22
+ "README.markdown",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/wunderground.rb",
26
+ "test/helper.rb",
27
+ "test/test_wunderground.rb",
28
+ "wunderground_ruby.gemspec"
29
+ ]
30
+ s.homepage = "http://github.com/wnadeau/wunderground_ruby"
31
+ s.licenses = ["MIT"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = "1.8.10"
34
+ s.summary = "A simple ruby API wrapper for interacting with the Wunderground API"
35
+ s.test_files = [
36
+ "test/helper.rb",
37
+ "test/test_wunderground.rb"
38
+ ]
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<json>, ["> 1.4.0"])
45
+ s.add_runtime_dependency(%q<httparty>, ["> 0.6.0"])
46
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
47
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
50
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
51
+ s.add_development_dependency(%q<mocha>, ["> 0.9.11"])
52
+ s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
53
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<json>, ["> 1.4.0"])
56
+ s.add_dependency(%q<httparty>, ["> 0.6.0"])
57
+ s.add_dependency(%q<addressable>, [">= 0"])
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
61
+ s.add_dependency(%q<simplecov>, [">= 0"])
62
+ s.add_dependency(%q<mocha>, ["> 0.9.11"])
63
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
64
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<json>, ["> 1.4.0"])
68
+ s.add_dependency(%q<httparty>, ["> 0.6.0"])
69
+ s.add_dependency(%q<addressable>, [">= 0"])
70
+ s.add_dependency(%q<shoulda>, [">= 0"])
71
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
72
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
73
+ s.add_dependency(%q<simplecov>, [">= 0"])
74
+ s.add_dependency(%q<mocha>, ["> 0.9.11"])
75
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
76
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
77
+ end
78
+ end
79
+
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wunderground
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Winfred Nadeau
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-03 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70184098296440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>'
20
+ - !ruby/object:Gem::Version
21
+ version: 1.4.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70184098296440
25
+ - !ruby/object:Gem::Dependency
26
+ name: httparty
27
+ requirement: &70184098295860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>'
31
+ - !ruby/object:Gem::Version
32
+ version: 0.6.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70184098295860
36
+ - !ruby/object:Gem::Dependency
37
+ name: addressable
38
+ requirement: &70184098295260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70184098295260
47
+ - !ruby/object:Gem::Dependency
48
+ name: shoulda
49
+ requirement: &70184098294680 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70184098294680
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &70184098294100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70184098294100
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &70184098293560 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.5.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70184098293560
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &70184098292980 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70184098292980
91
+ - !ruby/object:Gem::Dependency
92
+ name: mocha
93
+ requirement: &70184098292400 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>'
97
+ - !ruby/object:Gem::Version
98
+ version: 0.9.11
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70184098292400
102
+ - !ruby/object:Gem::Dependency
103
+ name: ruby-debug19
104
+ requirement: &70184098291460 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70184098291460
113
+ - !ruby/object:Gem::Dependency
114
+ name: ruby-debug
115
+ requirement: &70184098288900 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70184098288900
124
+ description: A simple ruby API wrapper for interacting with the Wunderground API
125
+ email: winfred.nadeau@gmail.com
126
+ executables: []
127
+ extensions: []
128
+ extra_rdoc_files:
129
+ - LICENSE.txt
130
+ - README.markdown
131
+ files:
132
+ - Gemfile
133
+ - LICENSE.txt
134
+ - README.markdown
135
+ - Rakefile
136
+ - VERSION
137
+ - lib/wunderground.rb
138
+ - test/helper.rb
139
+ - test/test_wunderground.rb
140
+ - wunderground.gemspec
141
+ - wunderground_ruby.gemspec
142
+ homepage: http://github.com/wnadeau/wunderground_ruby
143
+ licenses:
144
+ - MIT
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ segments:
156
+ - 0
157
+ hash: -3588021643652236154
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.10
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: A simple ruby API wrapper for interacting with the Wunderground API
170
+ test_files:
171
+ - test/helper.rb
172
+ - test/test_wunderground.rb