geo_ip_curb 0.3.2 → 0.4.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/LICENSE +1 -1
- data/lib/geo_ip_curb.rb +21 -27
- metadata +14 -35
- data/spec/api.yml.example +0 -1
- data/spec/geo_ip_spec.rb +0 -120
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -6
data/LICENSE
CHANGED
data/lib/geo_ip_curb.rb
CHANGED
@@ -2,12 +2,12 @@ require 'json'
|
|
2
2
|
require 'curb'
|
3
3
|
|
4
4
|
class GeoIpCurb
|
5
|
-
SERVICE_URL = "http://api.ipinfodb.com/
|
6
|
-
CITY_API = "
|
7
|
-
COUNTRY_API = "
|
5
|
+
SERVICE_URL = "http://api.ipinfodb.com/v3"
|
6
|
+
CITY_API = "ip-city"
|
7
|
+
COUNTRY_API = "ip-country"
|
8
8
|
IPV4_REGEXP = /\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/
|
9
|
-
TIMEOUT =
|
10
|
-
ERROR_PREFIX = "
|
9
|
+
TIMEOUT = 10
|
10
|
+
ERROR_PREFIX = "api.ipinfodb.com service error"
|
11
11
|
|
12
12
|
@@api_key = nil
|
13
13
|
|
@@ -28,17 +28,14 @@ class GeoIpCurb
|
|
28
28
|
# ==== Example:
|
29
29
|
# GeoIpCurb.geolocation('209.85.227.104', {:precision => :city, :timezone => true})
|
30
30
|
def self.geolocation(ip, options={})
|
31
|
-
@precision = options[:precision] || :
|
32
|
-
@timezone = options[:timezone] || false
|
31
|
+
@precision = options[:precision] || :country
|
33
32
|
@timeout = options[:timeout] || TIMEOUT
|
34
33
|
|
35
34
|
raise "API key must be set first: GeoIpCurb.api_key = 'YOURKEY'" if self.api_key.nil?
|
36
35
|
raise "Invalid IP address" unless ip.to_s =~ IPV4_REGEXP
|
37
36
|
raise "Invalid precision" unless [:country, :city].include?(@precision)
|
38
|
-
raise "Invalid timezone" unless [true, false].include?(@timezone)
|
39
37
|
|
40
|
-
uri = "#{SERVICE_URL}/#{@country ? COUNTRY_API : CITY_API}
|
41
|
-
|
38
|
+
uri = "#{SERVICE_URL}/#{@precision==:country ? COUNTRY_API : CITY_API}/?key=#{self.api_key}&ip=#{ip}&format=json"
|
42
39
|
convert_keys send_request(uri)
|
43
40
|
end
|
44
41
|
|
@@ -57,24 +54,21 @@ class GeoIpCurb
|
|
57
54
|
|
58
55
|
def self.convert_keys(hash)
|
59
56
|
location = {}
|
60
|
-
location[:ip] = hash["
|
61
|
-
location[:status] = hash["
|
62
|
-
location[:
|
63
|
-
location[:
|
57
|
+
location[:ip] = hash["ipAddress"]
|
58
|
+
location[:status] = hash["statusCode"]
|
59
|
+
location[:status_message] = hash["statusMessage"]
|
60
|
+
location[:country_code] = hash["countryCode"]
|
61
|
+
location[:country_name] = hash["countryName"]
|
64
62
|
if @precision == :city
|
65
|
-
location[:
|
66
|
-
location[:
|
67
|
-
location[:
|
68
|
-
location[:
|
69
|
-
location[:
|
70
|
-
location[:
|
71
|
-
if @timezone
|
72
|
-
location[:timezone_name] = hash["TimezoneName"]
|
73
|
-
location[:utc_offset] = hash["Gmtoffset"].to_i
|
74
|
-
location[:dst?] = hash["Isdst"] ? true : false
|
75
|
-
end
|
63
|
+
location[:region_name] = hash["regionName"]
|
64
|
+
location[:city] = hash["cityName"]
|
65
|
+
location[:zip_postal_code] = hash["zipCode"]
|
66
|
+
location[:latitude] = hash["latitude"]
|
67
|
+
location[:longitude] = hash["longitude"]
|
68
|
+
location[:utc_offset] = hash["timeZone"]
|
76
69
|
end
|
77
|
-
location[:
|
70
|
+
location[:status] = "ERROR" if hash[:error_msg]
|
71
|
+
location[:status_message] = hash[:error_msg] if hash[:error_msg]
|
78
72
|
location
|
79
73
|
end
|
80
|
-
end
|
74
|
+
end
|
metadata
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo_ip_curb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Conway
|
14
|
-
- Jeroen Jacobs
|
15
14
|
autorequire:
|
16
15
|
bindir: bin
|
17
16
|
cert_chain: []
|
18
17
|
|
19
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-25 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: json
|
@@ -50,25 +50,10 @@ dependencies:
|
|
50
50
|
version: 0.7.15
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: rspec
|
55
|
-
prerelease: false
|
56
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 9
|
62
|
-
segments:
|
63
|
-
- 2
|
64
|
-
- 5
|
65
|
-
version: "2.5"
|
66
|
-
type: :development
|
67
|
-
version_requirements: *id003
|
68
53
|
- !ruby/object:Gem::Dependency
|
69
54
|
name: mocha
|
70
55
|
prerelease: false
|
71
|
-
requirement: &
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
72
57
|
none: false
|
73
58
|
requirements:
|
74
59
|
- - ~>
|
@@ -80,8 +65,8 @@ dependencies:
|
|
80
65
|
- 12
|
81
66
|
version: 0.9.12
|
82
67
|
type: :development
|
83
|
-
version_requirements: *
|
84
|
-
description: A call to the ipinfodb.com will be done to
|
68
|
+
version_requirements: *id003
|
69
|
+
description: A call to the v3 API over at ipinfodb.com will be done to retrieve the geolocation based on the IP address. No need to include a database file in the application.
|
85
70
|
email:
|
86
71
|
executables: []
|
87
72
|
|
@@ -92,10 +77,7 @@ extra_rdoc_files: []
|
|
92
77
|
files:
|
93
78
|
- LICENSE
|
94
79
|
- lib/geo_ip_curb.rb
|
95
|
-
|
96
|
-
- spec/geo_ip_spec.rb
|
97
|
-
- spec/spec.opts
|
98
|
-
- spec/spec_helper.rb
|
80
|
+
has_rdoc: true
|
99
81
|
homepage:
|
100
82
|
licenses: []
|
101
83
|
|
@@ -125,12 +107,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
107
|
requirements: []
|
126
108
|
|
127
109
|
rubyforge_project:
|
128
|
-
rubygems_version: 1.
|
110
|
+
rubygems_version: 1.5.0
|
129
111
|
signing_key:
|
130
112
|
specification_version: 3
|
131
|
-
summary:
|
132
|
-
test_files:
|
133
|
-
|
134
|
-
- spec/geo_ip_spec.rb
|
135
|
-
- spec/spec.opts
|
136
|
-
- spec/spec_helper.rb
|
113
|
+
summary: Retrieve the geolocation of an IP address using the the ipinfodb.com v3 API service using Curb.
|
114
|
+
test_files: []
|
115
|
+
|
data/spec/api.yml.example
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
key: YOUR_KEY_HERE
|
data/spec/geo_ip_spec.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
IP_GOOGLE_US = '209.85.227.104'
|
3
|
-
IP_PRIVATE = '10.0.0.1'
|
4
|
-
IP_LOCAL = '127.0.0.1'
|
5
|
-
|
6
|
-
describe "GeoIp" do
|
7
|
-
|
8
|
-
before :each do
|
9
|
-
api_config = YAML.load_file(File.dirname(__FILE__) + '/api.yml')
|
10
|
-
GeoIp.api_key = api_config['key']
|
11
|
-
end
|
12
|
-
|
13
|
-
context "api_key" do
|
14
|
-
it "should return the API key when set" do
|
15
|
-
GeoIp.api_key = "my_api_key"
|
16
|
-
GeoIp.api_key.should == "my_api_key"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should throw an error when API key is not set" do
|
20
|
-
GeoIp.api_key = nil
|
21
|
-
lambda {GeoIp.geolocation(IP_GOOGLE_US)}.should raise_error
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context "service failure" do
|
26
|
-
it "should return an error hash if the GeoIP service is down" do
|
27
|
-
GeoIp.expects(:send_request).returns({:error_msg => "#{GeoIp::ERROR_PREFIX}: Im on fire!"}).once
|
28
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
29
|
-
geolocation[:error].should =~ Regexp.new("^#{GeoIp::ERROR_PREFIX}")
|
30
|
-
Mocha::Mockery.instance.stubba.unstub_all
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "city" do
|
35
|
-
it "should return the correct city for a public ip address" do
|
36
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
37
|
-
geolocation[:country_code].should == 'US'
|
38
|
-
geolocation[:country_name].should == 'United States'
|
39
|
-
geolocation[:city].should == 'Mountain View'
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should return the correct city for a private ip address" do
|
43
|
-
geolocation = GeoIp.geolocation(IP_PRIVATE)
|
44
|
-
geolocation[:country_code].should == 'RD'
|
45
|
-
geolocation[:country_name].should == 'Reserved'
|
46
|
-
geolocation[:city].should be_empty
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should return the correct city for localhost ip address" do
|
50
|
-
geolocation = GeoIp.geolocation(IP_LOCAL)
|
51
|
-
geolocation[:country_code].should == 'RD'
|
52
|
-
geolocation[:country_name].should == 'Reserved'
|
53
|
-
geolocation[:city].should be_empty
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should return the correct city for a public ip address when explicitly requiring it" do
|
57
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :city})
|
58
|
-
geolocation[:country_code].should == 'US'
|
59
|
-
geolocation[:country_name].should == 'United States'
|
60
|
-
geolocation[:city].should == 'Mountain View'
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context "country" do
|
65
|
-
it "should return the correct country for a public ip address" do
|
66
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country})
|
67
|
-
geolocation[:country_code].should == 'US'
|
68
|
-
geolocation[:country_name].should == 'United States'
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should return the correct country for a private ip address" do
|
72
|
-
geolocation = GeoIp.geolocation(IP_PRIVATE, {:precision => :country})
|
73
|
-
geolocation[:country_code].should == 'RD'
|
74
|
-
geolocation[:country_name].should == 'Reserved'
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should return the correct country for localhost ip address" do
|
78
|
-
geolocation = GeoIp.geolocation(IP_LOCAL, {:precision => :country})
|
79
|
-
geolocation[:country_code].should == 'RD'
|
80
|
-
geolocation[:country_name].should == 'Reserved'
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should not return the city for a public ip address" do
|
84
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country})
|
85
|
-
geolocation[:country_code].should == 'US'
|
86
|
-
geolocation[:country_name].should == 'United States'
|
87
|
-
geolocation[:city].should be_nil
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "timezone" do
|
92
|
-
it "should return the correct timezone information for a public ip address" do
|
93
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:timezone => true})
|
94
|
-
geolocation[:timezone_name].should == 'America/Los_Angeles'
|
95
|
-
geolocation[:utc_offset].should == -28800
|
96
|
-
geolocation[:dst?].should_not be_nil # true if dst?, false if not dst?
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should not return the timezone information when explicitly not requesting it" do
|
100
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:timezone => false})
|
101
|
-
geolocation[:timezone_name].should be_nil
|
102
|
-
geolocation[:utc_offset].should be_nil
|
103
|
-
geolocation[:dst?].should be_nil
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should not return the timezone information when not requesting it" do
|
107
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
108
|
-
geolocation[:timezone_name].should be_nil
|
109
|
-
geolocation[:utc_offset].should be_nil
|
110
|
-
geolocation[:dst?].should be_nil
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should not return the timezone information when country precision is selected" do
|
114
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country, :timezone => true})
|
115
|
-
geolocation[:timezone_name].should be_nil
|
116
|
-
geolocation[:utc_offset].should be_nil
|
117
|
-
geolocation[:dst?].should be_nil
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
data/spec/spec.opts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|