api_object 0.6.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -94,12 +94,12 @@ stations = data.map {|d| Station.new(d)}
94
94
 
95
95
  6) Getting location based data by ip.
96
96
 
97
+ A) Getting location using ipinfodb.com (requires api key)
98
+
97
99
  This gem uses [geo_ip gem](https://github.com/jeroenj/geo_ip) and [ipinfodb.com](http://ipinfodb.com/) webservice to retrieve location based on ip.
98
100
 
99
101
  The service requires an API key, in order to get it [register](http://ipinfodb.com/register.php) at the web site.
100
102
 
101
- Consider making a donation to [ipinfodb.com](http://ipinfodb.com/) at [http://ipinfodb.com/donate.php](http://ipinfodb.com/donate.php).
102
-
103
103
  The [geo_ip gem](https://github.com/jeroenj/geo_ip) retrieves location as:
104
104
 
105
105
  ```
@@ -125,6 +125,40 @@ data = Weather.get_results_by_ip('99.156.82.20', :key => <KEY>, :weather => :zip
125
125
 
126
126
  The function takes parameters to define what fields from the location object are passed as what parameter. In this case, "zip_code" field is passed as "weather" parameter and the original function is:
127
127
 
128
+ ```
129
+ data = Weather.get_results(:weather => '99.156.82.20')
130
+ ```
131
+ *This service is allowed to be used only for internal business purposes.* Please, verify with the Terms and Conditions when registering for a key.
132
+
133
+
134
+ B) Getting location using freegeoip.net (requires no key)
135
+
136
+ As the ipinfodb.com service has limitations in the terms of use, the gem [freegeoip gem](https://github.com/ezkl/freegeoip) is used whenever no api key is provided. Unfortunatelly, their database last update was April 29, 2011.
137
+
138
+ The [freegeoip gem](https://github.com/ezkl/freegeoip) retrieves location as:
139
+
140
+ ```
141
+ {
142
+ "city" => "Round Rock"
143
+ "region_code" => "TX"
144
+ "region_name" => "Texas"
145
+ "metrocode" => "635"
146
+ "zipcode" => "78681"
147
+ "longitude" => "-97.7286"
148
+ "latitude" => "30.5321"
149
+ "country_code" => "US"
150
+ "ip" => "99.156.82.20"
151
+ "country_name" => "United States"
152
+ }
153
+ ```
154
+ To get the data, call "get_results_by_ip" instead of "get_results":
155
+
156
+ ```
157
+ data = Weather.get_results_by_ip('99.156.82.20', :weather => :zipcode)
158
+ ```
159
+
160
+ The function takes parameters to define what fields from the location object are passed as what parameter. In this case, "zipcode" field is passed as "weather" parameter and the original function is:
161
+
128
162
  ```
129
163
  data = Weather.get_results(:weather => '99.156.82.20')
130
164
  ```
@@ -142,7 +176,7 @@ errors = station.errors
142
176
 
143
177
  The gem has been tested on BART, Google Weather and NextBus APIs.
144
178
 
145
- To run test by ip location, please, [register](http://ipinfodb.com/register.php) for an API key.
179
+ To run tests by ip location for ipinfodb.com service, please, [register](http://ipinfodb.com/register.php) for an API key.
146
180
 
147
181
  The key should be either placed into the test/data/keys/ipinfodb_key.txt file or passed as an environment variable:
148
182
 
@@ -152,6 +186,8 @@ API_KEY='<your key>' rake test
152
186
 
153
187
  There is no existing api key provided with this gem as per the Terms and Conditions of the ipinfodb service.
154
188
 
189
+ If there is no key provided, those tests will be avoided.
190
+
155
191
  9) Limitations
156
192
 
157
193
  * Api data must be presented either in XML or in JSON format. The distinction between XML and JSON is determinted automatically.
@@ -30,5 +30,6 @@ Gem::Specification.new do |s|
30
30
  s.add_dependency('nori', '>=1.1')
31
31
  s.add_dependency('rest-client', '>= 1.6')
32
32
  s.add_dependency 'geo_ip'
33
+ s.add_dependency 'freegeoip'
33
34
 
34
35
  end
@@ -2,6 +2,7 @@ require "api_object/version"
2
2
  require "api_object/query"
3
3
  require "active_support/all"
4
4
  require "geo_ip"
5
+ require 'freegeoip'
5
6
 
6
7
  module ActiveApi
7
8
 
@@ -19,13 +20,18 @@ module ActiveApi
19
20
 
20
21
 
21
22
  def get_results_by_ip ip, arguments = {}
22
- self.api_key = arguments.delete(:key) if arguments[:key]
23
- location = GeoIp.geolocation(ip)
24
- raise unless location[:status_code] == "OK"
25
- get_results [*arguments.keys].inject({}) { |opts, a| opts.merge(a.to_sym => location[arguments[a.to_sym]]) }
23
+ self.api_key = arguments.delete(:key) if arguments.include?(:key)
24
+ if self.api_key
25
+ location = GeoIp.geolocation(ip)
26
+ raise unless location[:status_code] == "OK"
27
+ return get_results [*arguments.keys].inject({}) { |opts, a| opts.merge(a.to_sym => location[arguments[a.to_sym]]) }
28
+ else
29
+ location = FreeGeoIP.locate(ip)
30
+ get_results [*arguments.keys].inject({}) { |opts, a| opts.merge(a.to_sym => location[arguments[a.to_sym].to_s]) }
31
+ end
26
32
  rescue
27
- puts "ERROR: Cannot get results or location by ip. Verify that you have a valid key for the ipinfodb.com service"
28
- return ApiObjectError.new(:class => self, :errors => invalid_loc_msg)
33
+ puts "ERROR: Cannot get results or location by ip. Verify that you have a valid key for the location service"
34
+ return ApiObjectError.new(:class => self, :errors => invalid_loc_msg)
29
35
  end
30
36
 
31
37
  def get_results options = {}
@@ -1,3 +1,3 @@
1
1
  module ApiObject
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
@@ -0,0 +1,49 @@
1
+ <xml_api_reply version="1">
2
+ <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0">
3
+ <forecast_information>
4
+ <city data="Round Rock, TX"/>
5
+ <postal_code data="78681"/>
6
+ <latitude_e6 data=""/>
7
+ <longitude_e6 data=""/>
8
+ <forecast_date data="2012-06-20"/>
9
+ <current_date_time data="2012-06-20 22:47:00 +0000"/>
10
+ <unit_system data="US"/>
11
+ </forecast_information>
12
+ <current_conditions>
13
+ <condition data="Clear"/>
14
+ <temp_f data="84"/>
15
+ <temp_c data="29"/>
16
+ <humidity data="Humidity: 55%"/>
17
+ <icon data="/ig/images/weather/sunny.gif"/>
18
+ <wind_condition data="Wind: S at 12 mph"/>
19
+ </current_conditions>
20
+ <forecast_conditions>
21
+ <day_of_week data="Wed"/>
22
+ <low data="75"/>
23
+ <high data="90"/>
24
+ <icon data="/ig/images/weather/chance_of_storm.gif"/>
25
+ <condition data="Chance of Storm"/>
26
+ </forecast_conditions>
27
+ <forecast_conditions>
28
+ <day_of_week data="Thu"/>
29
+ <low data="73"/>
30
+ <high data="95"/>
31
+ <icon data="/ig/images/weather/chance_of_storm.gif"/>
32
+ <condition data="Chance of Storm"/>
33
+ </forecast_conditions>
34
+ <forecast_conditions>
35
+ <day_of_week data="Fri"/>
36
+ <low data="73"/>
37
+ <high data="97"/>
38
+ <icon data="/ig/images/weather/mostly_sunny.gif"/>
39
+ <condition data="Mostly Sunny"/>
40
+ </forecast_conditions>
41
+ <forecast_conditions>
42
+ <day_of_week data="Sat"/>
43
+ <low data="75"/>
44
+ <high data="99"/>
45
+ <icon data="/ig/images/weather/sunny.gif"/>
46
+ <condition data="Clear"/>
47
+ </forecast_conditions>
48
+ </weather>
49
+ </xml_api_reply>
@@ -24,6 +24,7 @@ class ApiObjectTest < MiniTest::Unit::TestCase
24
24
 
25
25
  @@weather_mv = Weather.load_from_xml(File.read(@@weather_directory + '/mountain_view.xml'))
26
26
  @@weather_au = Weather.load_from_xml(File.read(@@weather_directory + '/austin.xml'))
27
+ @@weather_rr = Weather.load_from_xml(File.read(@@weather_directory + '/round_rock.xml'))
27
28
  @@ip_key = File.read(@@key_directory + "/ipinfodb_key.txt") rescue ENV['API_KEY']
28
29
 
29
30
  @@muni_routes = Route.load_from_xml(File.read(@@bus_directory + "/muni_routes.xml"))
@@ -53,7 +54,6 @@ class ApiObjectTest < MiniTest::Unit::TestCase
53
54
  end
54
55
  end
55
56
 
56
-
57
57
  def test_should_get_correct_weather
58
58
  weather_mv = Weather.new(Weather.get_results(:weather => 'Mountain+View'))
59
59
  assert_equal(weather_mv, @@weather_mv)
@@ -62,27 +62,31 @@ class ApiObjectTest < MiniTest::Unit::TestCase
62
62
  end
63
63
 
64
64
 
65
- def test_should_get_correct_weather_by_ip
66
- unless @@ip_key.nil?
65
+ # Note that the 2 services give slightly different location
66
+ def test_should_get_correct_weather_by_ip_with_no_key
67
+ GeoIp.api_key = nil
68
+ weather_rr = Weather.new(Weather.get_results_by_ip(IP, :key => nil, :weather => :zipcode))
69
+ assert_equal(weather_rr, @@weather_rr)
70
+ refute_has_errors(weather_rr)
71
+ end
72
+
73
+ def test_should_get_correct_weather_with_key
74
+ unless @@ip_key.nil?
67
75
  weather_au = Weather.new(Weather.get_results_by_ip(IP, :key => @@ip_key, :weather => :zip_code))
68
76
  assert_equal(weather_au, @@weather_au)
69
77
  refute_has_errors(weather_au)
70
78
  end
71
79
  end
72
-
80
+
73
81
  def test_should_get_correct_weather_with_key_preset
74
- GeoIp.api_key = @@ip_key
75
- weather_au = Weather.new(Weather.get_results_by_ip(IP, :weather => :zip_code))
76
- assert_equal(weather_au, @@weather_au)
77
- refute_has_errors(weather_au)
82
+ unless @@ip_key.nil?
83
+ GeoIp.api_key = @@ip_key
84
+ weather_au = Weather.new(Weather.get_results_by_ip(IP, :weather => :zip_code))
85
+ assert_equal(weather_au, @@weather_au)
86
+ refute_has_errors(weather_au)
87
+ end
78
88
  end
79
89
 
80
- def test_should_not_get_correct_weather_with_no_key
81
- GeoIp.api_key = nil
82
- weather_au = Weather.new(Weather.get_results_by_ip(IP, :weather => :zip_code))
83
- assert_empty(weather_au)
84
- assert_has_errors(weather_au)
85
- end
86
90
 
87
91
  def test_should_get_correct_bus_routes
88
92
  routes = Route.get_results(:a => 'sf-muni', :command => 'routeList').map {|r| Route.new(r)}
@@ -111,7 +115,7 @@ class ApiObjectTest < MiniTest::Unit::TestCase
111
115
  assert(routes.errors, Route.invalid_url_msg)
112
116
  end
113
117
 
114
-
118
+
115
119
  private
116
120
 
117
121
  #ensure that the estimates of the first station include the sample
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-16 00:00:00.000000000 Z
12
+ date: 2012-06-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
16
- requirement: &76922910 !ruby/object:Gem::Requirement
16
+ requirement: &80888390 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *76922910
24
+ version_requirements: *80888390
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &76922660 !ruby/object:Gem::Requirement
27
+ requirement: &80888180 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *76922660
35
+ version_requirements: *80888180
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitest
38
- requirement: &77001800 !ruby/object:Gem::Requirement
38
+ requirement: &80887970 !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: :development
45
45
  prerelease: false
46
- version_requirements: *77001800
46
+ version_requirements: *80887970
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &77001550 !ruby/object:Gem::Requirement
49
+ requirement: &80887760 !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: :runtime
56
56
  prerelease: false
57
- version_requirements: *77001550
57
+ version_requirements: *80887760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: nori
60
- requirement: &77001240 !ruby/object:Gem::Requirement
60
+ requirement: &80887510 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '1.1'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *77001240
68
+ version_requirements: *80887510
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rest-client
71
- requirement: &77000930 !ruby/object:Gem::Requirement
71
+ requirement: &80887260 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '1.6'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *77000930
79
+ version_requirements: *80887260
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: geo_ip
82
- requirement: &77000700 !ruby/object:Gem::Requirement
82
+ requirement: &80886970 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,18 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *77000700
90
+ version_requirements: *80886970
91
+ - !ruby/object:Gem::Dependency
92
+ name: freegeoip
93
+ requirement: &80886190 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *80886190
91
102
  description: An interface to load objects from external APIs provided in XML and JSON
92
103
  formats
93
104
  email:
@@ -113,6 +124,7 @@ files:
113
124
  - test/data/estimate/twenty_fourth.xml
114
125
  - test/data/weather/austin.xml
115
126
  - test/data/weather/mountain_view.xml
127
+ - test/data/weather/round_rock.xml
116
128
  - test/unit/api_object_test.rb
117
129
  - test/unit/load_from_xml.rb
118
130
  - test/unit/route.rb