geo_ip 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/CHANGES +9 -3
  2. data/VERSION +1 -1
  3. data/geo_ip.gemspec +3 -3
  4. data/lib/geo_ip.rb +40 -14
  5. data/spec/geo_ip_spec.rb +92 -10
  6. metadata +20 -9
data/CHANGES CHANGED
@@ -1,7 +1,13 @@
1
+ == 0.2.0
2
+
3
+ * Added support for timezone information. Use the optional {:timezone => true|false} option
4
+ * Added support for country lookup. This will result in a faster reply since less queries need
5
+ to be done at ipinfodb's side. Use the optional {:precision => :city|:country} option
6
+
1
7
  == 0.1.1
2
-
8
+
3
9
  * Removed time zone information since this has been deprecated with the service
4
-
10
+
5
11
  == 0.1.0
6
-
12
+
7
13
  * Initial commit
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/geo_ip.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{geo_ip}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeroen Jacobs"]
12
- s.date = %q{2010-02-15}
12
+ s.date = %q{2010-03-25}
13
13
  s.description = %q{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.}
14
14
  s.email = %q{jj@redstorm.com}
15
15
  s.extra_rdoc_files = [
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.homepage = %q{http://github.com/jeroenj/geo_ip}
35
35
  s.rdoc_options = ["--charset=UTF-8"]
36
36
  s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.3.5}
37
+ s.rubygems_version = %q{1.3.6}
38
38
  s.summary = %q{Retreive the geolocation of an IP address based on the ipinfodb.com webservice}
39
39
  s.test_files = [
40
40
  "spec/geo_ip_spec.rb",
data/lib/geo_ip.rb CHANGED
@@ -1,4 +1,6 @@
1
- SERVICE_URL = "http://ipinfodb.com/ip_query.php"
1
+ SERVICE_URL = "http://ipinfodb.com/"
2
+ CITY_API = "ip_query.php"
3
+ COUNTRY_API = "ip_query_country.php"
2
4
  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/
3
5
 
4
6
  require 'rubygems'
@@ -7,10 +9,27 @@ require 'uri'
7
9
  require 'net/http'
8
10
 
9
11
  class GeoIp
10
- def self.remote_geolocation(ip)
12
+ # <b>DEPRECATED:</b> Please use <tt>geolocation</tt> instead.
13
+ def self.remote_geolocation(ip, timezone=false)
14
+ warn "DEPRECATION WARNING: `remote_geolocation` is deprecated and will be removed from 0.3. Use `geolocation` instead."
15
+ geolocation(ip, {:timezone => timezone})
16
+ end
17
+
18
+ # Retreive the remote location of a given ip address.
19
+ #
20
+ # It takes two optional arguments: precision and timezone
21
+ # preceision can either be :city (default) or :country
22
+ # timezone can either be false (default) or true
23
+ #
24
+ # Example:
25
+ # GeoIp.geolocation('209.85.227.104', {:precision => :city, :timezone => true})
26
+ def self.geolocation(ip, options={})
27
+ @precision = options[:precision] || :city
28
+ @timezone = options[:timezone] || false
11
29
  raise "Invalid IP address" unless ip.to_s =~ IPV4_REGEXP
12
-
13
- uri = SERVICE_URL + "?ip=#{ip}&output=json&timezone=false"
30
+ raise "Invalid precision" unless [:country, :city].include?(@precision)
31
+ raise "Invalid timezone" unless [true, false].include?(@timezone)
32
+ uri = "#{SERVICE_URL}#{@country ? COUNTRY_API : CITY_API}?ip=#{ip}&output=json&timezone=#{@timezone}"
14
33
  url = URI.parse(uri)
15
34
  reply = JSON.parse(Net::HTTP.get(url))
16
35
  location = convert_keys reply
@@ -19,16 +38,23 @@ class GeoIp
19
38
  private
20
39
  def self.convert_keys(hash)
21
40
  location = {}
22
- location[:ip] = hash["Ip"]
23
- location[:status] = hash["Status"]
24
- location[:country_code] = hash["CountryCode"]
25
- location[:country_name] = hash["CountryName"]
26
- location[:region_code] = hash["RegionCode"]
27
- location[:region_name] = hash["RegionName"]
28
- location[:city] = hash["City"]
29
- location[:zip_postal_code] = hash["ZipPostalCode"]
30
- location[:latitude] = hash["Latitude"]
31
- location[:longitude] = hash["Longitude"]
41
+ location[:ip] = hash["Ip"]
42
+ location[:status] = hash["Status"]
43
+ location[:country_code] = hash["CountryCode"]
44
+ location[:country_name] = hash["CountryName"]
45
+ if @precision == :city
46
+ location[:region_code] = hash["RegionCode"]
47
+ location[:region_name] = hash["RegionName"]
48
+ location[:city] = hash["City"]
49
+ location[:zip_postal_code] = hash["ZipPostalCode"]
50
+ location[:latitude] = hash["Latitude"]
51
+ location[:longitude] = hash["Longitude"]
52
+ if @timezone
53
+ location[:timezone_name] = hash["TimezoneName"]
54
+ location[:utc_offset] = hash["Gmtoffset"].to_i
55
+ location[:dst?] = hash["Isdst"] ? true : false
56
+ end
57
+ end
32
58
  location
33
59
  end
34
60
  end
data/spec/geo_ip_spec.rb CHANGED
@@ -1,19 +1,101 @@
1
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'
2
5
 
3
6
  describe "GeoIp" do
4
- it "should return the correct country for a public ip address" do
5
- # 209.85.227.104 = google.be (US)
6
- GeoIp.remote_geolocation('209.85.227.104')[:country_code].should == 'US'
7
- GeoIp.remote_geolocation('209.85.227.104')[:country_name].should == 'United States'
7
+ context "city" do
8
+ it "should return the correct city for a public ip address" do
9
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US)
10
+ geolocation[:country_code].should == 'US'
11
+ geolocation[:country_name].should == 'United States'
12
+ geolocation[:city].should == 'Mountain View'
13
+ end
14
+
15
+ it "should return the correct city for a private ip address" do
16
+ geolocation = GeoIp.geolocation(IP_PRIVATE)
17
+ geolocation[:country_code].should == 'RD'
18
+ geolocation[:country_name].should == 'Reserved'
19
+ geolocation[:city].should be_empty
20
+ end
21
+
22
+ it "should return the correct city for localhost ip address" do
23
+ geolocation = GeoIp.geolocation(IP_LOCAL)
24
+ geolocation[:country_code].should == 'RD'
25
+ geolocation[:country_name].should == 'Reserved'
26
+ geolocation[:city].should be_empty
27
+ end
28
+
29
+ it "should return the correct city for a public ip address when explicitly requiring it" do
30
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :city})
31
+ geolocation[:country_code].should == 'US'
32
+ geolocation[:country_name].should == 'United States'
33
+ geolocation[:city].should == 'Mountain View'
34
+ end
8
35
  end
9
36
 
10
- it "should return the correct country for a private ip address" do
11
- GeoIp.remote_geolocation('10.0.0.1')[:country_code].should == 'RD'
12
- GeoIp.remote_geolocation('10.0.0.1')[:country_name].should == 'Reserved'
37
+ context "country" do
38
+ it "should return the correct country for a public ip address" do
39
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country})
40
+ geolocation[:country_code].should == 'US'
41
+ geolocation[:country_name].should == 'United States'
42
+ end
43
+
44
+ it "should return the correct country for a private ip address" do
45
+ geolocation = GeoIp.geolocation(IP_PRIVATE, {:precision => :country})
46
+ geolocation[:country_code].should == 'RD'
47
+ geolocation[:country_name].should == 'Reserved'
48
+ end
49
+
50
+ it "should return the correct country for localhost ip address" do
51
+ geolocation = GeoIp.geolocation(IP_LOCAL, {:precision => :country})
52
+ geolocation[:country_code].should == 'RD'
53
+ geolocation[:country_name].should == 'Reserved'
54
+ end
55
+
56
+ it "should not return the city for a public ip address" do
57
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country})
58
+ geolocation[:country_code].should == 'US'
59
+ geolocation[:country_name].should == 'United States'
60
+ geolocation[:city].should be_nil
61
+ end
62
+ end
63
+
64
+ context "timezone" do
65
+ it "should return the correct timezone information for a public ip address" do
66
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:timezone => true})
67
+ geolocation[:timezone_name].should == 'America/Los_Angeles'
68
+ geolocation[:utc_offset].should == -25200
69
+ geolocation[:dst?].should_not be_nil # true if dst?, false if not dst?
70
+ end
71
+
72
+ it "should not return the timezone information when explicitly not requesting it" do
73
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:timezone => false})
74
+ geolocation[:timezone_name].should be_nil
75
+ geolocation[:utc_offset].should be_nil
76
+ geolocation[:dst?].should be_nil
77
+ end
78
+
79
+ it "should not return the timezone information when not requesting it" do
80
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US)
81
+ geolocation[:timezone_name].should be_nil
82
+ geolocation[:utc_offset].should be_nil
83
+ geolocation[:dst?].should be_nil
84
+ end
85
+
86
+ it "should not return the timezone information when country precision is selected" do
87
+ geolocation = GeoIp.geolocation(IP_GOOGLE_US, {:precision => :country, :timezone => true})
88
+ geolocation[:timezone_name].should be_nil
89
+ geolocation[:utc_offset].should be_nil
90
+ geolocation[:dst?].should be_nil
91
+ end
13
92
  end
14
93
 
15
- it "should return the correct country for localhost ip address" do
16
- GeoIp.remote_geolocation('127.0.0.1')[:country_code].should == 'RD'
17
- GeoIp.remote_geolocation('127.0.0.1')[:country_name].should == 'Reserved'
94
+ context "deprecated" do
95
+ it "should return the correct country for a public ip address" do
96
+ geolocation = GeoIp.remote_geolocation(IP_GOOGLE_US)
97
+ geolocation[:country_code].should == 'US'
98
+ geolocation[:country_name].should == 'United States'
99
+ end
18
100
  end
19
101
  end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geo_ip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Jeroen Jacobs
@@ -9,19 +14,23 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-15 00:00:00 +01:00
17
+ date: 2010-03-25 00:00:00 +01:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: rspec
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
23
31
  version: 1.2.9
24
- version:
32
+ type: :development
33
+ version_requirements: *id001
25
34
  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.
26
35
  email: jj@redstorm.com
27
36
  executables: []
@@ -58,18 +67,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
67
  requirements:
59
68
  - - ">="
60
69
  - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
61
72
  version: "0"
62
- version:
63
73
  required_rubygems_version: !ruby/object:Gem::Requirement
64
74
  requirements:
65
75
  - - ">="
66
76
  - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
67
79
  version: "0"
68
- version:
69
80
  requirements: []
70
81
 
71
82
  rubyforge_project:
72
- rubygems_version: 1.3.5
83
+ rubygems_version: 1.3.6
73
84
  signing_key:
74
85
  specification_version: 3
75
86
  summary: Retreive the geolocation of an IP address based on the ipinfodb.com webservice