geo_ip 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +40 -0
- data/README.md +167 -0
- data/lib/geo_ip.rb +35 -12
- data/spec/geo_ip_spec.rb +192 -0
- data/spec/spec_helper.rb +1 -0
- metadata +38 -6
data/CHANGES.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
## 0.5.0
|
2
|
+
|
3
|
+
* Wrap Ruby's Timeout module around the RestClient call to enforce timeout if caused by bad internet connection or slow or invalid DNS lookup. Added WebMock to tests to have reliable tests. By [harleyttd](https://github.com/harleyttd)
|
4
|
+
|
5
|
+
## 0.4.0
|
6
|
+
|
7
|
+
* Uses API v3
|
8
|
+
|
9
|
+
## 0.3.2
|
10
|
+
|
11
|
+
* Switches to [rest-client](https://github.com/adamwiggins/rest-client) for requests
|
12
|
+
* Sets default timeout to 1 second and adds option to override it
|
13
|
+
* More relaxed json dependency scoping
|
14
|
+
* Some internal code refactoring
|
15
|
+
|
16
|
+
## 0.3.1
|
17
|
+
|
18
|
+
* Switches to bundler for gem deployment
|
19
|
+
* Uses Rspec 2.x from now on
|
20
|
+
|
21
|
+
## 0.3.0
|
22
|
+
|
23
|
+
* Added support for API key requirement (Thanks to seanconaty and luigi)
|
24
|
+
* Explicit gem dependency for json and removed rubygems requirement (idris) (http://tomayko.com/writings/require-rubygems-antipattern)
|
25
|
+
* Removed deprecated GeoIp#remote_geolocation method
|
26
|
+
|
27
|
+
## 0.2.0
|
28
|
+
|
29
|
+
* Added support for timezone information. Use the optional {:timezone => true|false} option
|
30
|
+
* Added support for country lookup. This will result in a faster reply since less queries need
|
31
|
+
to be done at ipinfodb's side. Use the optional {:precision => :city|:country} option
|
32
|
+
* API change: GeoIp.remote_geolocation(ip) is deprecated in favor of GeoIp.geolocation(ip)
|
33
|
+
|
34
|
+
## 0.1.1
|
35
|
+
|
36
|
+
* Removed time zone information since this has been deprecated with the service
|
37
|
+
|
38
|
+
## 0.1.0
|
39
|
+
|
40
|
+
* Initial commit
|
data/README.md
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# GeoIp
|
2
|
+
|
3
|
+
Retreive the geolocation of an IP address based on the [ipinfodb.com](http://ipinfodb.com/) webservice.
|
4
|
+
|
5
|
+
As of 8th November 2010, the service is asking that all users [register](http://ipinfodb.com/register.php) for an API key.
|
6
|
+
|
7
|
+
Consider making a donation to [ipinfodb.com](http://ipinfodb.com/) at [http://ipinfodb.com/donate.php](http://ipinfodb.com/donate.php).
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
### Set API key
|
12
|
+
GeoIp.api_key = 'YOUR_API_KEY'
|
13
|
+
|
14
|
+
This must be done before making the geolocation call.
|
15
|
+
|
16
|
+
### Retrieve geolocation
|
17
|
+
GeoIp.geolocation(ip_address)
|
18
|
+
|
19
|
+
### Example
|
20
|
+
|
21
|
+
# 209.85.227.104 = google.be (US)
|
22
|
+
GeoIp.geolocation('209.85.227.104')
|
23
|
+
|
24
|
+
returns:
|
25
|
+
|
26
|
+
{
|
27
|
+
:status_code => "OK",
|
28
|
+
:status_message => "",
|
29
|
+
:ip => "209.85.227.104"
|
30
|
+
:country_code => "US",
|
31
|
+
:country_name => "UNITED STATES",
|
32
|
+
:region_name => "CALIFORNIA",
|
33
|
+
:city => "MONTEREY PARK",
|
34
|
+
:zip_code => "91754",
|
35
|
+
:latitude => "34.0505",
|
36
|
+
:longitude => "-118.13"
|
37
|
+
}
|
38
|
+
|
39
|
+
### Country only
|
40
|
+
|
41
|
+
There is an option to only retreive the country information and thus excluding the city details. This results in a faster response from the service since less queries need to be done.
|
42
|
+
|
43
|
+
GeoIp.geolocation('209.85.227.104', :precision => :country)
|
44
|
+
|
45
|
+
returns:
|
46
|
+
|
47
|
+
{
|
48
|
+
:status_code => "OK",
|
49
|
+
:status_message => "",
|
50
|
+
:ip => "209.85.227.104"
|
51
|
+
:country_code => "US",
|
52
|
+
:country_name => "UNITED STATES"
|
53
|
+
}
|
54
|
+
|
55
|
+
### Timezone information
|
56
|
+
|
57
|
+
There is an option now to retrieve optional timezone information too:
|
58
|
+
|
59
|
+
GeoIp.geolocation('209.85.227.104', :timezone => true)
|
60
|
+
|
61
|
+
returns:
|
62
|
+
|
63
|
+
{
|
64
|
+
:status_code => "OK",
|
65
|
+
:status_message => "",
|
66
|
+
:ip => "209.85.227.104"
|
67
|
+
:country_code => "US",
|
68
|
+
:country_name => "UNITED STATES",
|
69
|
+
:region_name => "CALIFORNIA",
|
70
|
+
:city => "MONTEREY PARK",
|
71
|
+
:zip_code => "91754",
|
72
|
+
:latitude => "34.0505",
|
73
|
+
:longitude => "-118.13"
|
74
|
+
:timezone => "-08:00"
|
75
|
+
}
|
76
|
+
|
77
|
+
Obviously it is not possible to have the country precision enabled while retrieving the timezone information.
|
78
|
+
|
79
|
+
### Reserved / Private / Local IPs
|
80
|
+
|
81
|
+
Passing reserved, private or local IPs, such as `127.0.0.1` will return `-` for all location data, for example:
|
82
|
+
|
83
|
+
GeoIpCurb.geolocation('127.0.0.1')
|
84
|
+
|
85
|
+
returns:
|
86
|
+
|
87
|
+
{
|
88
|
+
:status_code => "OK",
|
89
|
+
:status_message => "",
|
90
|
+
:ip => "127.0.0.1",
|
91
|
+
:country_code => "-",
|
92
|
+
:country_name => "-",
|
93
|
+
:region_name => "-",
|
94
|
+
:city => "-",
|
95
|
+
:zip_code => "-",
|
96
|
+
:latitude => "0",
|
97
|
+
:longitude => "0"
|
98
|
+
}
|
99
|
+
|
100
|
+
### Timeout
|
101
|
+
|
102
|
+
It is possible to set a timeout for all requests. By default it is one second, but you can easily set a different value. Just like you would set the api_key you can set the timeout:
|
103
|
+
|
104
|
+
GeoIp.timeout = 5 # In order to set it to five seconds
|
105
|
+
|
106
|
+
## Getting it
|
107
|
+
|
108
|
+
GeoIp can be installed as a Ruby Gem:
|
109
|
+
|
110
|
+
gem install geo_ip
|
111
|
+
|
112
|
+
### Rails
|
113
|
+
|
114
|
+
#### Bundler enabled (Rails 3.0.x and 2.3.x)
|
115
|
+
|
116
|
+
In your Gemfile:
|
117
|
+
|
118
|
+
gem 'geo_ip', '~> 0.3.0'
|
119
|
+
|
120
|
+
Then create an initializer `config/initializers/geo_ip` (or name it whatever you want):
|
121
|
+
|
122
|
+
GeoIp.api_key = 'YOUR_API_KEY'
|
123
|
+
|
124
|
+
#### Pre-bundler (Rails 2.3.x or older)
|
125
|
+
|
126
|
+
In your `config/environment.rb`:
|
127
|
+
|
128
|
+
config.gem 'geo_ip', :version => '~> 0.3.0'
|
129
|
+
|
130
|
+
Then create an initializer `config/initializers/geo_ip` (or name it whatever you want):
|
131
|
+
|
132
|
+
GeoIp.api_key = 'YOUR_API_KEY'
|
133
|
+
|
134
|
+
## Testing
|
135
|
+
|
136
|
+
Set up your API key first for the test suite by creating a spec/api.yml file. Follow the example in spec/api.yml.example. Then run the tests with:
|
137
|
+
|
138
|
+
ruby spec/geo_ip_spec.rb
|
139
|
+
|
140
|
+
If you get a LoadError, you should run the tests with:
|
141
|
+
|
142
|
+
ruby -rubygems spec/geo_ip_spec.rb
|
143
|
+
|
144
|
+
## Contributors
|
145
|
+
|
146
|
+
* [seanconaty](https://github.com/seanconaty)
|
147
|
+
* [luigi](https://github.com/luigi)
|
148
|
+
* [idris](https://github.com/idris)
|
149
|
+
* [Rylon](https://github.com/Rylon)
|
150
|
+
* [harleyttd](https://github.com/harleyttd)
|
151
|
+
|
152
|
+
## Bugs
|
153
|
+
|
154
|
+
Please report them on the [Github issue tracker](https://github.com/jeroenj/geo_ip/issues)
|
155
|
+
for this project.
|
156
|
+
|
157
|
+
If you have a bug to report, please include the following information:
|
158
|
+
|
159
|
+
* **Version information for bierdopje, Rails and Ruby.**
|
160
|
+
* Stack trace and error message.
|
161
|
+
|
162
|
+
You may also fork this project on Github and create a pull request.
|
163
|
+
Do not forget to include tests.
|
164
|
+
|
165
|
+
## Copyright
|
166
|
+
|
167
|
+
Copyright (c) 2010-2011 Jeroen Jacobs. See LICENSE for details.
|
data/lib/geo_ip.rb
CHANGED
@@ -9,6 +9,7 @@ class GeoIp
|
|
9
9
|
|
10
10
|
@@api_key = nil
|
11
11
|
@@timeout = 1
|
12
|
+
@@fallback_timeout = 3
|
12
13
|
|
13
14
|
class << self
|
14
15
|
def api_key
|
@@ -27,6 +28,29 @@ class GeoIp
|
|
27
28
|
@@timeout = timeout
|
28
29
|
end
|
29
30
|
|
31
|
+
def fallback_timeout
|
32
|
+
@@fallback_timeout
|
33
|
+
end
|
34
|
+
|
35
|
+
def fallback_timeout= fallback_timeout
|
36
|
+
@@fallback_timeout = fallback_timeout
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_defaults_if_necessary options
|
40
|
+
options[:precision] ||= :city
|
41
|
+
options[:timezone] ||= false
|
42
|
+
raise 'Invalid precision' unless [:country, :city].include?(options[:precision])
|
43
|
+
raise 'Invalid timezone' unless [true, false].include?(options[:timezone])
|
44
|
+
end
|
45
|
+
|
46
|
+
def lookup_url ip, options = {}
|
47
|
+
set_defaults_if_necessary options
|
48
|
+
raise 'API key must be set first: GeoIp.api_key = \'YOURKEY\'' if self.api_key.nil?
|
49
|
+
raise 'Invalid IP address' unless ip.to_s =~ IPV4_REGEXP
|
50
|
+
|
51
|
+
"#{SERVICE_URL}#{options[:precision] == :city || options[:timezone] ? CITY_API : COUNTRY_API}?key=#{api_key}&ip=#{ip}&format=json&timezone=#{options[:timezone]}"
|
52
|
+
end
|
53
|
+
|
30
54
|
# Retreive the remote location of a given ip address.
|
31
55
|
#
|
32
56
|
# It takes two optional arguments:
|
@@ -36,32 +60,31 @@ class GeoIp
|
|
36
60
|
# ==== Example:
|
37
61
|
# GeoIp.geolocation('209.85.227.104', {:precision => :city, :timezone => true})
|
38
62
|
def geolocation ip, options={}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
parsed_response = JSON.parse RestClient::Request.execute(:method => :get, :url => url, :timeout => self.timeout)
|
47
|
-
convert_keys parsed_response
|
63
|
+
location = nil
|
64
|
+
Timeout.timeout(self.fallback_timeout) do
|
65
|
+
parsed_response = JSON.parse RestClient::Request.execute(:method => :get, :url => lookup_url(ip, options), :timeout => self.timeout)
|
66
|
+
location = convert_keys(parsed_response, options)
|
67
|
+
end
|
68
|
+
|
69
|
+
location
|
48
70
|
end
|
49
71
|
|
50
72
|
private
|
51
|
-
def convert_keys hash
|
73
|
+
def convert_keys hash, options
|
74
|
+
set_defaults_if_necessary options
|
52
75
|
location = {}
|
53
76
|
location[:ip] = hash['ipAddress']
|
54
77
|
location[:status_code] = hash['statusCode']
|
55
78
|
location[:status_message] = hash['statusMessage']
|
56
79
|
location[:country_code] = hash['countryCode']
|
57
80
|
location[:country_name] = hash['countryName']
|
58
|
-
if
|
81
|
+
if options[:precision] == :city
|
59
82
|
location[:region_name] = hash['regionName']
|
60
83
|
location[:city] = hash['cityName']
|
61
84
|
location[:zip_code] = hash['zipCode']
|
62
85
|
location[:latitude] = hash['latitude']
|
63
86
|
location[:longitude] = hash['longitude']
|
64
|
-
if
|
87
|
+
if options[:timezone]
|
65
88
|
location[:timezone] = hash['timeZone']
|
66
89
|
end
|
67
90
|
end
|
data/spec/geo_ip_spec.rb
CHANGED
@@ -2,8 +2,27 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
IP_GOOGLE_US = '209.85.227.104'
|
3
3
|
IP_PRIVATE = '10.0.0.1'
|
4
4
|
IP_LOCAL = '127.0.0.1'
|
5
|
+
# Use WebMock as default to speed up tests and for local development without a connection
|
6
|
+
# Change this to false to have tests make real http requests if you want. Perhaps to check whether IpInfoDb's API has changed
|
7
|
+
# However, you may need to increase the GeoIp.fallback_timeout variable if Timeout exceptions occur when tests are run
|
8
|
+
USE_WEBMOCK = true
|
5
9
|
|
6
10
|
describe 'GeoIp' do
|
11
|
+
before :all do
|
12
|
+
unless USE_WEBMOCK
|
13
|
+
puts "Running tests WITHOUT WebMock. You will need an internet connection. You may need to increase the GeoIp.fallback_timeout amount."
|
14
|
+
WebMock.disable!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def stub_geolocation(ip, options = {}, &block)
|
19
|
+
if USE_WEBMOCK
|
20
|
+
stub_request(:get, GeoIp.lookup_url(ip, options)).
|
21
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
22
|
+
to_return(:status => 200, :body => yield, :headers => {})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
before :each do
|
8
27
|
api_config = YAML.load_file(File.dirname(__FILE__) + '/api.yml')
|
9
28
|
GeoIp.api_key = api_config['key']
|
@@ -23,6 +42,22 @@ describe 'GeoIp' do
|
|
23
42
|
|
24
43
|
context 'city' do
|
25
44
|
it 'should return the correct city for a public ip address' do
|
45
|
+
stub_geolocation(IP_GOOGLE_US) do
|
46
|
+
%[{
|
47
|
+
"statusCode" : "OK",
|
48
|
+
"statusMessage" : "",
|
49
|
+
"ipAddress" : "209.85.227.104",
|
50
|
+
"countryCode" : "US",
|
51
|
+
"countryName" : "UNITED STATES",
|
52
|
+
"regionName" : "CALIFORNIA",
|
53
|
+
"cityName" : "MONTEREY PARK",
|
54
|
+
"zipCode" : "91754",
|
55
|
+
"latitude" : "34.0505",
|
56
|
+
"longitude" : "-118.13",
|
57
|
+
"timeZone" : "-08:00"
|
58
|
+
}]
|
59
|
+
end
|
60
|
+
|
26
61
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
27
62
|
geolocation[:country_code].should == 'US'
|
28
63
|
geolocation[:country_name].should == 'UNITED STATES'
|
@@ -30,6 +65,22 @@ describe 'GeoIp' do
|
|
30
65
|
end
|
31
66
|
|
32
67
|
it 'should return nothing city for a private ip address' do
|
68
|
+
stub_geolocation(IP_PRIVATE) do
|
69
|
+
%[{
|
70
|
+
"statusCode" : "OK",
|
71
|
+
"statusMessage" : "",
|
72
|
+
"ipAddress" : "10.0.0.1",
|
73
|
+
"countryCode" : "-",
|
74
|
+
"countryName" : "-",
|
75
|
+
"regionName" : "-",
|
76
|
+
"cityName" : "-",
|
77
|
+
"zipCode" : "-",
|
78
|
+
"latitude" : "0",
|
79
|
+
"longitude" : "0",
|
80
|
+
"timeZone" : "-"
|
81
|
+
}]
|
82
|
+
end
|
83
|
+
|
33
84
|
geolocation = GeoIp.geolocation(IP_PRIVATE)
|
34
85
|
geolocation[:country_code].should == '-'
|
35
86
|
geolocation[:country_name].should == '-'
|
@@ -37,6 +88,22 @@ describe 'GeoIp' do
|
|
37
88
|
end
|
38
89
|
|
39
90
|
it 'should return nothing for localhost ip address' do
|
91
|
+
stub_geolocation(IP_LOCAL) do
|
92
|
+
%[{
|
93
|
+
"statusCode" : "OK",
|
94
|
+
"statusMessage" : "",
|
95
|
+
"ipAddress" : "127.0.0.1",
|
96
|
+
"countryCode" : "-",
|
97
|
+
"countryName" : "-",
|
98
|
+
"regionName" : "-",
|
99
|
+
"cityName" : "-",
|
100
|
+
"zipCode" : "-",
|
101
|
+
"latitude" : "0",
|
102
|
+
"longitude" : "0",
|
103
|
+
"timeZone" : "-"
|
104
|
+
}]
|
105
|
+
end
|
106
|
+
|
40
107
|
geolocation = GeoIp.geolocation(IP_LOCAL)
|
41
108
|
geolocation[:country_code].should == '-'
|
42
109
|
geolocation[:country_name].should == '-'
|
@@ -44,6 +111,22 @@ describe 'GeoIp' do
|
|
44
111
|
end
|
45
112
|
|
46
113
|
it 'should return the correct city for a public ip address when explicitly requiring it' do
|
114
|
+
stub_geolocation(IP_GOOGLE_US) do
|
115
|
+
%[{
|
116
|
+
"statusCode" : "OK",
|
117
|
+
"statusMessage" : "",
|
118
|
+
"ipAddress" : "209.85.227.104",
|
119
|
+
"countryCode" : "US",
|
120
|
+
"countryName" : "UNITED STATES",
|
121
|
+
"regionName" : "CALIFORNIA",
|
122
|
+
"cityName" : "MONTEREY PARK",
|
123
|
+
"zipCode" : "91754",
|
124
|
+
"latitude" : "34.0505",
|
125
|
+
"longitude" : "-118.13",
|
126
|
+
"timeZone" : "-08:00"
|
127
|
+
}]
|
128
|
+
end
|
129
|
+
|
47
130
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :precision => :city)
|
48
131
|
geolocation[:country_code].should == 'US'
|
49
132
|
geolocation[:country_name].should == 'UNITED STATES'
|
@@ -53,24 +136,60 @@ describe 'GeoIp' do
|
|
53
136
|
|
54
137
|
context 'country' do
|
55
138
|
it 'should return the correct country for a public ip address' do
|
139
|
+
stub_geolocation(IP_GOOGLE_US, :precision => :country) do
|
140
|
+
%[{
|
141
|
+
"statusCode" : "OK",
|
142
|
+
"statusMessage" : "",
|
143
|
+
"ipAddress" : "209.85.227.104",
|
144
|
+
"countryCode" : "US",
|
145
|
+
"countryName" : "UNITED STATES"
|
146
|
+
}]
|
147
|
+
end
|
56
148
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :precision => :country)
|
57
149
|
geolocation[:country_code].should == 'US'
|
58
150
|
geolocation[:country_name].should == 'UNITED STATES'
|
59
151
|
end
|
60
152
|
|
61
153
|
it 'should return nothing country for a private ip address' do
|
154
|
+
stub_geolocation(IP_PRIVATE, :precision => :country) do
|
155
|
+
%[{
|
156
|
+
"statusCode" : "OK",
|
157
|
+
"statusMessage" : "",
|
158
|
+
"ipAddress" : "10.0.0.1",
|
159
|
+
"countryCode" : "-",
|
160
|
+
"countryName" : "-"
|
161
|
+
}]
|
162
|
+
end
|
62
163
|
geolocation = GeoIp.geolocation(IP_PRIVATE, :precision => :country)
|
63
164
|
geolocation[:country_code].should == '-'
|
64
165
|
geolocation[:country_name].should == '-'
|
65
166
|
end
|
66
167
|
|
67
168
|
it 'should return nothing country for localhost ip address' do
|
169
|
+
stub_geolocation(IP_LOCAL, :precision => :country) do
|
170
|
+
%[{
|
171
|
+
"statusCode" : "OK",
|
172
|
+
"statusMessage" : "",
|
173
|
+
"ipAddress" : "127.0.0.1",
|
174
|
+
"countryCode" : "-",
|
175
|
+
"countryName" : "-"
|
176
|
+
}]
|
177
|
+
end
|
68
178
|
geolocation = GeoIp.geolocation(IP_LOCAL, :precision => :country)
|
69
179
|
geolocation[:country_code].should == '-'
|
70
180
|
geolocation[:country_name].should == '-'
|
71
181
|
end
|
72
182
|
|
73
183
|
it 'should not return the city for a public ip address' do
|
184
|
+
stub_geolocation(IP_GOOGLE_US, :precision => :country) do
|
185
|
+
%[{
|
186
|
+
"statusCode" : "OK",
|
187
|
+
"statusMessage" : "",
|
188
|
+
"ipAddress" : "209.85.227.104",
|
189
|
+
"countryCode" : "US",
|
190
|
+
"countryName" : "UNITED STATES"
|
191
|
+
}]
|
192
|
+
end
|
74
193
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :precision => :country)
|
75
194
|
geolocation[:country_code].should == 'US'
|
76
195
|
geolocation[:country_name].should == 'UNITED STATES'
|
@@ -80,23 +199,96 @@ describe 'GeoIp' do
|
|
80
199
|
|
81
200
|
context 'timezone' do
|
82
201
|
it 'should return the correct timezone information for a public ip address' do
|
202
|
+
stub_geolocation(IP_GOOGLE_US, :timezone => true) do
|
203
|
+
%[{
|
204
|
+
"statusCode" : "OK",
|
205
|
+
"statusMessage" : "",
|
206
|
+
"ipAddress" : "209.85.227.104",
|
207
|
+
"countryCode" : "US",
|
208
|
+
"countryName" : "UNITED STATES",
|
209
|
+
"regionName" : "CALIFORNIA",
|
210
|
+
"cityName" : "MONTEREY PARK",
|
211
|
+
"zipCode" : "91754",
|
212
|
+
"latitude" : "34.0505",
|
213
|
+
"longitude" : "-118.13",
|
214
|
+
"timeZone" : "-08:00"
|
215
|
+
}]
|
216
|
+
end
|
83
217
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :timezone => true)
|
84
218
|
geolocation[:timezone].should == '-08:00' # This one is likely to break when dst changes.
|
85
219
|
end
|
86
220
|
|
87
221
|
it 'should not return the timezone information when explicitly not requesting it' do
|
222
|
+
stub_geolocation(IP_GOOGLE_US, :timezone => false) do
|
223
|
+
%[{
|
224
|
+
"statusCode" : "OK",
|
225
|
+
"statusMessage" : "",
|
226
|
+
"ipAddress" : "209.85.227.104",
|
227
|
+
"countryCode" : "US",
|
228
|
+
"countryName" : "UNITED STATES",
|
229
|
+
"regionName" : "CALIFORNIA",
|
230
|
+
"cityName" : "MONTEREY PARK",
|
231
|
+
"zipCode" : "91754",
|
232
|
+
"latitude" : "34.0505",
|
233
|
+
"longitude" : "-118.13",
|
234
|
+
"timeZone" : "-08:00"
|
235
|
+
}]
|
236
|
+
end
|
88
237
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :timezone => false)
|
89
238
|
geolocation[:timezone].should be_nil
|
90
239
|
end
|
91
240
|
|
92
241
|
it 'should not return the timezone information when not requesting it' do
|
242
|
+
stub_geolocation(IP_GOOGLE_US) do
|
243
|
+
%[{
|
244
|
+
"statusCode" : "OK",
|
245
|
+
"statusMessage" : "",
|
246
|
+
"ipAddress" : "209.85.227.104",
|
247
|
+
"countryCode" : "US",
|
248
|
+
"countryName" : "UNITED STATES",
|
249
|
+
"regionName" : "CALIFORNIA",
|
250
|
+
"cityName" : "MONTEREY PARK",
|
251
|
+
"zipCode" : "91754",
|
252
|
+
"latitude" : "34.0505",
|
253
|
+
"longitude" : "-118.13",
|
254
|
+
"timeZone" : "-08:00"
|
255
|
+
}]
|
256
|
+
end
|
93
257
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
94
258
|
geolocation[:timezone].should be_nil
|
95
259
|
end
|
96
260
|
|
97
261
|
it 'should not return the timezone information when country precision is selected' do
|
262
|
+
stub_geolocation(IP_GOOGLE_US, :precision => :country, :timezone => true) do
|
263
|
+
%[{
|
264
|
+
"statusCode" : "OK",
|
265
|
+
"statusMessage" : "",
|
266
|
+
"ipAddress" : "209.85.227.104",
|
267
|
+
"countryCode" : "US",
|
268
|
+
"countryName" : "UNITED STATES",
|
269
|
+
"regionName" : "CALIFORNIA",
|
270
|
+
"cityName" : "MONTEREY PARK",
|
271
|
+
"zipCode" : "91754",
|
272
|
+
"latitude" : "34.0505",
|
273
|
+
"longitude" : "-118.13",
|
274
|
+
"timeZone" : "-08:00"
|
275
|
+
}]
|
276
|
+
end
|
98
277
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :precision => :country, :timezone => true)
|
99
278
|
geolocation[:timezone].should be_nil
|
100
279
|
end
|
101
280
|
end
|
281
|
+
|
282
|
+
context "timeout" do
|
283
|
+
it 'should trigger timeout when the request is taking too long' do
|
284
|
+
stub_request(:get, GeoIp.lookup_url(IP_GOOGLE_US)).to_timeout
|
285
|
+
lambda { GeoIp.geolocation(IP_GOOGLE_US) }.should raise_exception("Request Timeout")
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'should trigger fallback timeout when RestClient is taking too long to send the request', :focus => true do
|
289
|
+
GeoIp.fallback_timeout = 1
|
290
|
+
RestClient::Request.stub(:execute) { sleep 1 }
|
291
|
+
lambda { GeoIp.geolocation(IP_GOOGLE_US) }.should raise_exception(Timeout::Error)
|
292
|
+
end
|
293
|
+
end
|
102
294
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo_ip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jeroen Jacobs
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-03-03 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,9 +50,23 @@ dependencies:
|
|
50
50
|
type: :runtime
|
51
51
|
version_requirements: *id002
|
52
52
|
- !ruby/object:Gem::Dependency
|
53
|
-
name:
|
53
|
+
name: rake
|
54
54
|
prerelease: false
|
55
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: rspec
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
56
70
|
none: false
|
57
71
|
requirements:
|
58
72
|
- - ~>
|
@@ -63,7 +77,23 @@ dependencies:
|
|
63
77
|
- 5
|
64
78
|
version: "2.5"
|
65
79
|
type: :development
|
66
|
-
version_requirements: *
|
80
|
+
version_requirements: *id004
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: webmock
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 31
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 7
|
93
|
+
- 10
|
94
|
+
version: 1.7.10
|
95
|
+
type: :development
|
96
|
+
version_requirements: *id005
|
67
97
|
description: A call to the ipinfodb.com will be done to retreive the geolocation based on the IP address. No need to include a database file in the application.
|
68
98
|
email: gems@jeroenj.be
|
69
99
|
executables: []
|
@@ -73,6 +103,8 @@ extensions: []
|
|
73
103
|
extra_rdoc_files: []
|
74
104
|
|
75
105
|
files:
|
106
|
+
- README.md
|
107
|
+
- CHANGES.md
|
76
108
|
- LICENSE
|
77
109
|
- lib/geo_ip.rb
|
78
110
|
- spec/api.yml
|