geoip 1.2.2 → 1.3.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/data/geoip/region.yml +4249 -0
- data/geoip.gemspec +3 -2
- data/lib/geoip.rb +111 -7
- metadata +3 -2
data/geoip.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "geoip"
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Clifford Heath", "Roland Moriz"]
|
12
|
-
s.date = "2013-08-
|
12
|
+
s.date = "2013-08-13"
|
13
13
|
s.description = "GeoIP searches a GeoIP database for a given host or IP address, and\nreturns information about the country where the IP address is allocated,\nand the city, ISP and other information, if you have that database version."
|
14
14
|
s.email = ["clifford.heath@gmail.com", "rmoriz@gmail.com"]
|
15
15
|
s.executables = ["geoip"]
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"data/geoip/country_code3.yml",
|
27
27
|
"data/geoip/country_continent.yml",
|
28
28
|
"data/geoip/country_name.yml",
|
29
|
+
"data/geoip/region.yml",
|
29
30
|
"data/geoip/time_zone.yml",
|
30
31
|
"geoip.gemspec",
|
31
32
|
"lib/geoip.rb",
|
data/lib/geoip.rb
CHANGED
@@ -58,7 +58,7 @@ require 'yaml'
|
|
58
58
|
class GeoIP
|
59
59
|
|
60
60
|
# The GeoIP GEM version number
|
61
|
-
VERSION = "1.
|
61
|
+
VERSION = "1.3.0"
|
62
62
|
|
63
63
|
# The +data/+ directory for geoip
|
64
64
|
DATA_DIR = File.expand_path(File.join(File.dirname(__FILE__),'..','data','geoip'))
|
@@ -78,6 +78,9 @@ class GeoIP
|
|
78
78
|
# ordered by GeoIP ID
|
79
79
|
CountryContinent = YAML.load_file(File.join(DATA_DIR,'country_continent.yml'))
|
80
80
|
|
81
|
+
# Load a hash of region names by region code
|
82
|
+
RegionName = YAML.load_file(File.join(DATA_DIR,'region.yml'))
|
83
|
+
|
81
84
|
# Hash of the timezone codes mapped to timezone name, per zoneinfo
|
82
85
|
TimeZone = YAML.load_file(File.join(DATA_DIR,'time_zone.yml'))
|
83
86
|
|
@@ -118,13 +121,27 @@ class GeoIP
|
|
118
121
|
|
119
122
|
end
|
120
123
|
|
124
|
+
class Region < Struct.new(:request, :ip, :country_code2, :country_code3, :country_name, :continent_code,
|
125
|
+
:region_code, :region_name, :timezone)
|
126
|
+
|
127
|
+
def to_hash
|
128
|
+
Hash[each_pair.to_a]
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
# Warning: for historical reasons the region code is mis-named region_name here
|
121
134
|
class City < Struct.new(:request, :ip, :country_code2, :country_code3, :country_name, :continent_code,
|
122
|
-
:region_name, :city_name, :postal_code, :latitude, :longitude, :dma_code, :area_code, :timezone)
|
135
|
+
:region_name, :city_name, :postal_code, :latitude, :longitude, :dma_code, :area_code, :timezone, :real_region_name)
|
123
136
|
|
124
137
|
def to_hash
|
125
138
|
Hash[each_pair.to_a]
|
126
139
|
end
|
127
140
|
|
141
|
+
def region_code
|
142
|
+
self.region_name
|
143
|
+
end
|
144
|
+
|
128
145
|
end
|
129
146
|
|
130
147
|
class ASN < Struct.new(:number, :asn)
|
@@ -185,6 +202,11 @@ class GeoIP
|
|
185
202
|
return city(hostname)
|
186
203
|
end
|
187
204
|
|
205
|
+
if (@database_type == GEOIP_REGION_EDITION_REV0 ||
|
206
|
+
@database_type == GEOIP_REGION_EDITION_REV1)
|
207
|
+
return region(hostname)
|
208
|
+
end
|
209
|
+
|
188
210
|
ip = lookup_ip(hostname)
|
189
211
|
if (@database_type == GEOIP_COUNTRY_EDITION ||
|
190
212
|
@database_type == GEOIP_PROXY_EDITION ||
|
@@ -210,6 +232,42 @@ class GeoIP
|
|
210
232
|
)
|
211
233
|
end
|
212
234
|
|
235
|
+
# Search the GeoIP database for the specified host, retuning region info.
|
236
|
+
#
|
237
|
+
# +hostname+ is a String holding the hosts's DNS name or numeric IP
|
238
|
+
# address.
|
239
|
+
#
|
240
|
+
# Returns a Region object with the nine elements:
|
241
|
+
# * The host or IP address string as requested
|
242
|
+
# * The IP address string after looking up the host
|
243
|
+
# * The two-character country code (ISO 3166-1 alpha-2)
|
244
|
+
# * The three-character country code (ISO 3166-2 alpha-3)
|
245
|
+
# * The ISO 3166 English-language name of the country
|
246
|
+
# * The two-character continent code
|
247
|
+
# * The region name (state or territory)
|
248
|
+
# * The timezone name, if known
|
249
|
+
#
|
250
|
+
def region(hostname)
|
251
|
+
if (@database_type == GEOIP_CITY_EDITION_REV0 ||
|
252
|
+
@database_type == GEOIP_CITY_EDITION_REV1 ||
|
253
|
+
@database_type == GEOIP_CITY_EDITION_REV1_V6)
|
254
|
+
return city(hostname)
|
255
|
+
end
|
256
|
+
|
257
|
+
if (@database_type == GEOIP_REGION_EDITION_REV0 ||
|
258
|
+
@database_type == GEOIP_REGION_EDITION_REV1)
|
259
|
+
ip = lookup_ip(hostname)
|
260
|
+
ipnum = iptonum(ip)
|
261
|
+
pos = seek_record(ipnum)
|
262
|
+
else
|
263
|
+
throw "Invalid GeoIP database type, can't look up Region by IP"
|
264
|
+
end
|
265
|
+
|
266
|
+
unless pos == @database_segments[0]
|
267
|
+
read_region(pos, hostname, ip)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
213
271
|
# Search the GeoIP database for the specified host, returning city info.
|
214
272
|
#
|
215
273
|
# +hostname+ is a String holding the host's DNS name or numeric IP
|
@@ -404,6 +462,51 @@ class GeoIP
|
|
404
462
|
end
|
405
463
|
end
|
406
464
|
|
465
|
+
def read_region(pos, hostname = '', ip = '') #:nodoc:
|
466
|
+
if (@database_type == GEOIP_REGION_EDITION_REV0)
|
467
|
+
pos -= STATE_BEGIN_REV0
|
468
|
+
if (pos >= 1000)
|
469
|
+
code = 225
|
470
|
+
region_code = ((pos - 1000) / 26 + 65).chr + ((pos - 1000) % 26 + 65).chr
|
471
|
+
else
|
472
|
+
code = pos
|
473
|
+
region_code = ''
|
474
|
+
end
|
475
|
+
elsif (@database_type == GEOIP_REGION_EDITION_REV1)
|
476
|
+
pos -= STATE_BEGIN_REV1
|
477
|
+
if (pos < US_OFFSET)
|
478
|
+
code = 0
|
479
|
+
region_code = ''
|
480
|
+
elsif (pos < CANADA_OFFSET)
|
481
|
+
code = 225
|
482
|
+
region_code = ((pos - US_OFFSET) / 26 + 65).chr + ((pos - US_OFFSET) % 26 + 65).chr
|
483
|
+
elsif (pos < WORLD_OFFSET)
|
484
|
+
code = 38
|
485
|
+
region_code = ((pos - CANADA_OFFSET) / 26 + 65).chr + ((pos - CANADA_OFFSET) % 26 + 65).chr
|
486
|
+
else
|
487
|
+
code = (pos - WORLD_OFFSET) / FIPS_RANGE
|
488
|
+
region_code = ''
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
Region.new(
|
493
|
+
hostname,
|
494
|
+
ip,
|
495
|
+
CountryCode[code], # ISO3166-1 alpha-2 code
|
496
|
+
CountryCode3[code], # ISO3166-2 alpha-3 code
|
497
|
+
CountryName[code], # Country name, per ISO 3166
|
498
|
+
CountryContinent[code], # Continent code.
|
499
|
+
region_code, # Unfortunately this is called region_name in the City structure
|
500
|
+
lookup_region_name(CountryCode[code], region_code),
|
501
|
+
(TimeZone["#{CountryCode[code]}#{region_code}"] || TimeZone["#{CountryCode[code]}"])
|
502
|
+
)
|
503
|
+
end
|
504
|
+
|
505
|
+
def lookup_region_name(country_iso2, region_code)
|
506
|
+
country_regions = RegionName[country_iso2]
|
507
|
+
country_regions && country_regions[region_code]
|
508
|
+
end
|
509
|
+
|
407
510
|
# Search the GeoIP database for the specified host, returning city info.
|
408
511
|
#
|
409
512
|
# +hostname+ is a String holding the host's DNS name or numeric
|
@@ -433,9 +536,9 @@ class GeoIP
|
|
433
536
|
@iter_pos += 1 unless @iter_pos.nil?
|
434
537
|
|
435
538
|
spl = record.split("\x00", 4)
|
436
|
-
# Get the region:
|
437
|
-
|
438
|
-
@iter_pos += (
|
539
|
+
# Get the region code:
|
540
|
+
region_code = spl[0]
|
541
|
+
@iter_pos += (region_code.size + 1) unless @iter_pos.nil?
|
439
542
|
|
440
543
|
# Get the city:
|
441
544
|
city = spl[1]
|
@@ -490,14 +593,15 @@ class GeoIP
|
|
490
593
|
CountryCode3[code], # ISO3166-2 code
|
491
594
|
CountryName[code], # Country name, per IS03166
|
492
595
|
CountryContinent[code], # Continent code.
|
493
|
-
|
596
|
+
region_code, # Region code (called region_name, unfortunately)
|
494
597
|
city, # City name
|
495
598
|
postal_code, # Postal code
|
496
599
|
latitude,
|
497
600
|
longitude,
|
498
601
|
dma_code,
|
499
602
|
area_code,
|
500
|
-
(TimeZone["#{CountryCode[code]}#{
|
603
|
+
(TimeZone["#{CountryCode[code]}#{region_code}"] || TimeZone["#{CountryCode[code]}"]),
|
604
|
+
lookup_region_name(CountryCode[code], region_code) # Real region name
|
501
605
|
)
|
502
606
|
end
|
503
607
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-08-
|
13
|
+
date: 2013-08-13 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: ! 'GeoIP searches a GeoIP database for a given host or IP address, and
|
16
16
|
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- data/geoip/country_code3.yml
|
36
36
|
- data/geoip/country_continent.yml
|
37
37
|
- data/geoip/country_name.yml
|
38
|
+
- data/geoip/region.yml
|
38
39
|
- data/geoip/time_zone.yml
|
39
40
|
- geoip.gemspec
|
40
41
|
- lib/geoip.rb
|