wunderground_ruby 0.2.0 → 0.3.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.
@@ -36,13 +36,16 @@ Check out below and test file for more examples.
36
36
 
37
37
  Standard request breakdown:
38
38
 
39
- wrapper_object.get_[feature]_and_[another feature]_for(optional_hash,"and/or location string")
39
+ wrapper_instance.get_[feature]_and_[another feature]_for("location string",optional: "hash", values: "at the end")
40
40
 
41
41
  ##Optional Hash
42
42
 
43
- This ugly little guy handles the nonconformists in Wunderground's API request structure. Luckily there are only two of these baddies, and only if you need them. (details below)
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)
44
45
 
45
- optional_hash = {lang: "FR", geo_ip:"127.0.0.1"}
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.
46
49
 
47
50
  Can you think of a better way to handle these? Pull requests welcome.
48
51
 
@@ -72,7 +75,7 @@ Any location string that Wunderground accepts will pass straight through this wr
72
75
 
73
76
  For geocoding a specific ip address as the location, just provide an IP like this:
74
77
 
75
- w_api.get_alerts_for({geo_ip: "127.0.0.1"})
78
+ w_api.get_alerts_for(geo_ip: "127.0.0.1")
76
79
 
77
80
  This was the quickest workaround to the non-conformity of the auto_ip request format.
78
81
 
@@ -81,14 +84,14 @@ This was the quickest workaround to the non-conformity of the auto_ip request fo
81
84
 
82
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:
83
86
 
84
- w_api.get_forecast_for({lang:"FR"},"France","Paris")
87
+ w_api.get_forecast_for("France","Paris", lang 'FR')
85
88
 
86
89
  Also, you can set the default language in the constructor or with a setter.
87
90
 
88
- w_api = Wunderground.new("apikey",{language: "FR"})
91
+ w_api = Wunderground.new("apikey",language: "FR")
89
92
  w_api.language = 'FR'
90
93
  w_api.get_forecast_for("France","Paris") #automatically includes /lang:FR/ in the request url, so results will be in French
91
- w_api.get_forecast_for({lang:"DE"},"France","Paris") #this will override the French(FR) default with German(DE)
94
+ w_api.get_forecast_for("France","Paris",lang: 'DE') #this will override the French(FR) default with German(DE)
92
95
 
93
96
  ##History and Planner Helpers
94
97
 
@@ -101,21 +104,22 @@ to get the history/planner data for this date/location. You may enjoy more flexi
101
104
 
102
105
  w_api.get_history_for("20101010","AL","Birmingham")
103
106
  w_api.get_history_for(1.year.ago,"33909")
104
- w_api.get_history_for(Date.now, {lang: "FR"}, "France/Paris")
105
- w_api.get_history_for(Date.now, {lang: "DE", geo_ip:"123.4.5.6"})
107
+ w_api.get_history_for(Date.now, "France/Paris",lang: "FR")
108
+ w_api.get_history_for(Date.now, geo_ip:"123.4.5.6", lang: "FR")
106
109
  w_api.get_planner_for("03150323","AL","Gulf Shores")
107
- w_api.get_planner_for(Time.now,Time.now+7.days,{geo_ip: "10.0.0.1"})
110
+ w_api.get_planner_for(Time.now,Time.now+7.days, geo_ip: "10.0.0.1")
108
111
  w_api.get_planner_for(Time.now,Time.now+7.days,"33030")
109
112
 
110
- .get_history_for and .get_planner_for accepts a string or any Date/Time/DateTime-like object that responds to .strftime("%Y%m%d") to auto-format the date.
113
+ .get_history_for and .get_planner_for accepts a preformatted string or any Date/Time/DateTime-like object that responds to .strftime to auto-format the date.
111
114
 
112
115
 
113
- ### Other Stuff
116
+ ### Request Timeout
114
117
 
115
- wunderground_ruby defaults to a 30 second timeout. You can optionally set your own timeout (in seconds) like so:
118
+ wunderground_ruby defaults to a 30 second timeout. You can optionally set your own timeout (in seconds) in three ways like so:
116
119
 
117
- w_api = Wunderground.new("apikey",{timeout: 60})
120
+ w_api = Wunderground.new("apikey",timeout: 60)
118
121
  w_api.timeout = 5
122
+ w_api.get_history_for(1.year.ago, geo_ip: '127.0.0.1', timeout:60)
119
123
 
120
124
 
121
125
  ### Error Handling
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -36,9 +36,9 @@ class Wunderground
36
36
 
37
37
  protected
38
38
 
39
- def call(method, params = {})
39
+ def call(method, timeout)
40
40
  raise MissingAPIKey if @api_key.nil?
41
- response = self.class.get(base_api_url << method, :timeout => @timeout)
41
+ response = self.class.get(base_api_url << method, :timeout => (timeout || @timeout))
42
42
  begin
43
43
  response = JSON.parse(response.body)
44
44
  rescue
@@ -56,12 +56,13 @@ protected
56
56
  raise NoMethodError, "undefined method: #{method} for Wunderground" unless method.to_s.start_with?("get_") and method.to_s.end_with?("_for")
57
57
  url = method.to_s.gsub("get_","").gsub("_for","").gsub("_and_","/")
58
58
  url << "/lang:#{@language}" if @language
59
- if args[0].class == Hash
60
- url = url.sub(/\/lang:.*/,'') and url << "/lang:#{args[0][:lang]}" if args[0][:lang]
61
- ip_address = args[0][:geo_ip] and args.push("autoip") if args[0][:geo_ip]
62
- args.delete_at(0)
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]
63
64
  end
64
- call(url <<'/q/'<< args.join('/') << ".json" << (ip_address.nil? ? '': "?geo_ip=#{ip_address}"))
65
+ call(url <<'/q/'<< args.join('/') << ".json" << (ip_address ? "?geo_ip=#{ip_address}" : ''),timeout)
65
66
  end
66
67
 
67
68
  class << self
@@ -20,15 +20,11 @@ class TestWunderground < Test::Unit::TestCase
20
20
  @wunderground = Wunderground.new(@api_key)
21
21
  assert_equal(@api_key, @wunderground.api_key)
22
22
  end
23
- should 'set timeout in constructor' do
24
- @wunderground = Wunderground.new(@api_key,{timeout: 60})
23
+ should 'set timeout and language in constructor' do
24
+ @wunderground = Wunderground.new(@api_key,timeout: 60, language: 'FR')
25
25
  assert_equal(60,@wunderground.timeout)
26
- end
27
- should 'set language in constructor' do
28
- @wunderground = Wunderground.new(@apikey,{language:"FR"})
29
26
  assert_equal('FR',@wunderground.language)
30
27
  end
31
-
32
28
  should "set an API key from the 'WUNDERGROUND_API_KEY' ENV variable" do
33
29
  ENV['WUNDERGROUND_API_KEY'] = @api_key
34
30
  @wunderground = Wunderground.new
@@ -59,9 +55,8 @@ class TestWunderground < Test::Unit::TestCase
59
55
 
60
56
  context "api url" do
61
57
  setup do
62
- @wunderground = Wunderground.new
63
- @wunderground.api_key = '123'
64
- @url = "http://api.wunderground.com/api/"
58
+ @wunderground = Wunderground.new("123")
59
+ @url = "http://api.wunderground.com/api/123/"
65
60
  end
66
61
  should "raise exception at empty api key" do
67
62
  @wunderground.api_key=nil
@@ -72,83 +67,94 @@ class TestWunderground < Test::Unit::TestCase
72
67
  end
73
68
 
74
69
  should "contain api key" do
75
- expect_get(@url+"123/forecast/q/ME/Portland.json",{timeout:30})
70
+ expect_get(@url+"forecast/q/ME/Portland.json",{timeout:30})
76
71
  @wunderground.get_forecast_for("ME","Portland")
77
72
  end
78
73
  should 'contain multiple Wunderground methods from ruby method' do
79
- expect_get(@url+"123/forecast/conditions/q/.json",{timeout: 30})
74
+ expect_get(@url+"forecast/conditions/q/.json",{timeout: 30})
80
75
  @wunderground.get_forecast_and_conditions_for()
81
76
  end
82
77
  should 'contain language modifier for method with {lang:"code"} hash' do
83
- expect_get(@url+"123/forecast/lang:FR/q/ME/Portland.json",{timeout: 30})
84
- @wunderground.get_forecast_for({lang:'FR'},"ME","Portland")
78
+ expect_get(@url+"forecast/lang:FR/q/ME/Portland.json",{timeout: 30})
79
+ @wunderground.get_forecast_for("ME","Portland", lang: 'FR')
85
80
  end
86
81
  context 'location parameter' do
87
82
  should 'formats query of type array' do
88
- expect_get(@url+"123/forecast/q/ME/Portland.json",{timeout: 30})
83
+ expect_get(@url+"forecast/q/ME/Portland.json",{timeout: 30})
89
84
  @wunderground.get_forecast_for("ME","Portland")
90
85
  end
91
86
  should 'formats query of type string' do
92
- expect_get(@url+"123/forecast/q/1234.1234,-1234.1234.json",{timeout: 30})
87
+ expect_get(@url+"forecast/q/1234.1234,-1234.1234.json",{timeout: 30})
93
88
  @wunderground.get_forecast_for("1234.1234,-1234.1234")
94
- expect_get(@url+"123/forecast/q/pws:WHAT.json",{timeout: 30})
89
+ expect_get(@url+"forecast/q/pws:WHAT.json",{timeout: 30})
95
90
  @wunderground.get_forecast_for("pws:WHAT")
96
91
  end
97
92
  should 'formats query of type geo_ip' do
98
- expect_get(@url+"123/forecast/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
99
- @wunderground.get_forecast_for({geo_ip: "127.0.0.1"})
93
+ expect_get(@url+"forecast/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
94
+ @wunderground.get_forecast_for(geo_ip: "127.0.0.1")
100
95
  end
101
96
  end
102
97
  context 'language support' do
103
98
  setup {@wunderground.language = "FR"}
104
99
  should 'automatically set language for all location types' do
105
- expect_get(@url+"123/forecast/lang:FR/q/pws:KCATAHOE2.json",{timeout: 30})
100
+ expect_get(@url+"forecast/lang:FR/q/pws:KCATAHOE2.json",{timeout: 30})
106
101
  @wunderground.get_forecast_for("pws:KCATAHOE2")
107
102
  end
108
103
  should 'have optional language override on call' do
109
- expect_get(@url+"123/forecast/lang:DE/q/ME/Portland.json",{timeout: 30})
110
- @wunderground.get_forecast_for({lang: "DE"},"ME","Portland")
104
+ expect_get(@url+"forecast/lang:DE/q/ME/Portland.json",{timeout: 30})
105
+ @wunderground.get_forecast_for("ME","Portland", lang: 'DE')
111
106
  end
112
107
  should 'pass language through history helper' do
113
- expect_get(@url+"123/history_#{Time.now.strftime("%Y%m%d")}/lang:DE/q/ME/Portland.json",{timeout: 30})
114
- @wunderground.get_history_for(Time.now,{lang: "DE"},"ME","Portland")
108
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/lang:DE/q/ME/Portland.json",{timeout: 30})
109
+ @wunderground.get_history_for(Time.now,"ME","Portland",lang: 'DE')
115
110
  end
116
111
  should 'pass language through planner helper' do
117
- expect_get(@url+"123/planner_#{Time.now.strftime("%m%d")}#{(Time.now + 700000).strftime('%m%d')}/lang:DE/q/ME/Portland.json",{timeout: 30})
118
- @wunderground.get_planner_for(Time.now,(Time.now+700000),{lang: "DE"},"ME","Portland")
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.get_planner_for(Time.now,(Time.now+700000),"ME","Portland", lang: 'DE')
119
114
  end
120
115
  should 'pass language through planner helper with IP' do
121
- expect_get(@url+"123/planner_#{Time.now.strftime('%m%d')}#{(Time.now +
116
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now +
122
117
  700000).strftime('%m%d')}/lang:DE/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
123
- @wunderground.get_planner_for(Time.now,(Time.now+700000),{lang: "DE",geo_ip: "127.0.0.1"})
118
+ @wunderground.get_planner_for(Time.now,(Time.now+700000),lang: "DE",geo_ip: "127.0.0.1")
124
119
  end
125
120
  end
126
121
  context 'for get_history_for(date,location) helper' do
127
122
  should 'pass string dates straight to URL' do
128
- expect_get(@url+"123/history_20110121/q/ME/Portland.json",{timeout: 30})
123
+ expect_get(@url+"history_20110121/q/ME/Portland.json",{timeout: 30})
129
124
  @wunderground.get_history_for("20110121","ME","Portland")
130
125
  end
131
126
  should 'accept Time objects' do
132
- expect_get(@url+"123/history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
127
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
133
128
  @wunderground.get_history_for(Time.now,"ME","Portland")
134
129
  end
135
130
  should 'accept Date objects' do
136
- expect_get(@url+"123/history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
131
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/q/ME/Portland.json",{timeout: 30})
137
132
  @wunderground.get_history_for(Time.now.to_date,"ME","Portland")
138
133
  end
139
134
  should 'accept Date object and pass optional hash object' do
140
- expect_get(@url+"123/history_#{Time.now.strftime("%Y%m%d")}/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
141
- @wunderground.get_history_for(Time.now.to_datetime,{geo_ip: '127.0.0.1'})
135
+ expect_get(@url+"history_#{Time.now.strftime("%Y%m%d")}/lang:FR/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
136
+ @wunderground.get_history_for(Time.now.to_datetime,geo_ip: '127.0.0.1',lang: 'FR')
142
137
  end
143
138
  end
144
139
  context 'for get_planner_for helper' do
145
140
  should 'pass string date ranges through' do
146
- expect_get(@url+"123/planner_03130323/q/ME/Portland.json",{timeout: 30})
141
+ expect_get(@url+"planner_03130323/q/ME/Portland.json",timeout: 30)
147
142
  @wunderground.get_planner_for("03130323","ME","Portland")
148
143
  end
149
144
  should 'turn two date objects into a properly formatted string' do
150
- expect_get(@url+"123/planner_#{Time.now.strftime('%m%d')}#{(Time.now + 700000).strftime('%m%d')}/q/autoip.json?geo_ip=127.0.0.1",{timeout: 30})
151
- @wunderground.get_planner_for(Time.now,(Time.now + 700000),{geo_ip: '127.0.0.1'})
145
+ expect_get(@url+"planner_#{Time.now.strftime('%m%d')}#{(Time.now +
146
+ 700000).strftime('%m%d')}/lang:FR/q/autoip.json?geo_ip=127.0.0.1",timeout: 30)
147
+ @wunderground.get_planner_for(Time.now,(Time.now + 700000),geo_ip: '127.0.0.1',lang:'FR')
148
+ end
149
+ end
150
+ context 'timeout passed through optional hash' do
151
+ should 'work for helper' do
152
+ 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)
153
+ @wunderground.get_planner_for(Time.now,(Time.now + 700000),geo_ip: '127.0.0.1',lang:'FR',timeout: 60)
154
+ end
155
+ should 'work for regular calls' do
156
+ expect_get(@url+"forecast/q/pws:WHAT.json",timeout: 60)
157
+ @wunderground.get_forecast_for("pws:WHAT", timeout: 60)
152
158
  end
153
159
  end
154
160
  end
@@ -181,7 +187,7 @@ class TestWunderground < Test::Unit::TestCase
181
187
 
182
188
  private
183
189
 
184
- def expect_get(expected_url,expected_options)
190
+ def expect_get(expected_url,expected_options={})
185
191
  Wunderground.expects(:get).with{|url, opts|
186
192
  url == expected_url &&
187
193
  opts[:timeout] == expected_options[:timeout]
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "wunderground_ruby"
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Winfred Nadeau"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wunderground_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-22 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &70237028968260 !ruby/object:Gem::Requirement
16
+ requirement: &70230066419980 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>'
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.4.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70237028968260
24
+ version_requirements: *70230066419980
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: httparty
27
- requirement: &70237028967400 !ruby/object:Gem::Requirement
27
+ requirement: &70230066417940 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>'
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.6.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70237028967400
35
+ version_requirements: *70230066417940
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: addressable
38
- requirement: &70237028966500 !ruby/object:Gem::Requirement
38
+ requirement: &70230066416940 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70237028966500
46
+ version_requirements: *70230066416940
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: shoulda
49
- requirement: &70237028965620 !ruby/object:Gem::Requirement
49
+ requirement: &70230066416140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70237028965620
57
+ version_requirements: *70230066416140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bundler
60
- requirement: &70237028964540 !ruby/object:Gem::Requirement
60
+ requirement: &70230066415280 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70237028964540
68
+ version_requirements: *70230066415280
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: jeweler
71
- requirement: &70237028963480 !ruby/object:Gem::Requirement
71
+ requirement: &70230066414380 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 1.5.1
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70237028963480
79
+ version_requirements: *70230066414380
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov
82
- requirement: &70237028960840 !ruby/object:Gem::Requirement
82
+ requirement: &70230066413400 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70237028960840
90
+ version_requirements: *70230066413400
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mocha
93
- requirement: &70237028960200 !ruby/object:Gem::Requirement
93
+ requirement: &70230066412420 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>'
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 0.9.11
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70237028960200
101
+ version_requirements: *70230066412420
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: ruby-debug19
104
- requirement: &70237028959400 !ruby/object:Gem::Requirement
104
+ requirement: &70230066409800 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70237028959400
112
+ version_requirements: *70230066409800
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: ruby-debug
115
- requirement: &70237028958340 !ruby/object:Gem::Requirement
115
+ requirement: &70230066409120 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70237028958340
123
+ version_requirements: *70230066409120
124
124
  description: A simple ruby API wrapper for interacting with the Wunderground API
125
125
  email: winfred.nadeau@gmail.com
126
126
  executables: []
@@ -153,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
153
  version: '0'
154
154
  segments:
155
155
  - 0
156
- hash: -306578686232459491
156
+ hash: -2893557894893877548
157
157
  required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  none: false
159
159
  requirements: