geo_ip 0.1.1 → 0.2.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.
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