Skip to content

Commit ce8d3b2

Browse files
committed
Added Country and Region class
Added Country class to query country information and Region class to lookup for ISO 3166-2 subdivision code form country code and region name.
1 parent 9e06599 commit ce8d3b2

9 files changed

+4061
-5
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,22 @@ Below is the description of the functions available in the **IpTools** class.
8383
| compress_ipv6 | Compress a IPv6 to shorten the length. |
8484
| expand_ipv6 | Expand a shorten IPv6 to full length. |
8585

86+
## Country
87+
Below is the description of the functions available in the **Country** class.
88+
89+
| Function Name | Description |
90+
|---|---|
91+
| Constructor | Expect a IP2Location Country Information CSV file. This database is free for download at https://www.ip2location.com/free/country-information |
92+
| get_country_info | Provide a ISO 3166 country code to get the country information in array. Will return a full list of countries information if country code not provided. Below is the information returned: <ul><li>country_code</li><li>country_alpha3_code</li><li>country_numeric_code</li><li>capital</li><li>country_demonym</li><li>total_area</li><li>population</li><li>idd_code</li><li>currency_code</li><li>currency_name</li><li>currency_symbol</li><li>lang_code</li><li>lang_name</li><li>cctld</li></ul> |
93+
94+
## Region
95+
Below is the description of the functions available in the **Region** class.
96+
97+
| Function Name | Description |
98+
|---|---|
99+
| Constructor | Expect a IP2Location ISO 3166-2 Subdivision Code CSV file. This database is free for download at https://www.ip2location.com/free/iso3166-2 |
100+
| get_region_code | Provide a ISO 3166 country code and the region name to get ISO 3166-2 subdivision code for the region. |
101+
86102
# Dependencies
87103
This library requires IP2Location BIN data file to function. You may download the BIN data file at
88104
* IP2Location LITE BIN Data (Free): https://lite.ip2location.com

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.5.0
1+
8.6.0

example.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
puts 'Usage Type: ' + record['usagetype']
3030
puts 'Address Type: ' + record['addresstype']
3131
puts 'Category: ' + record['category']
32-
3332
i2l.close()
3433

3534
# Web Service
@@ -52,3 +51,11 @@
5251
puts iptool.cidr_to_ipv6('2002::1234:abcd:ffff:c0a8:101/64')
5352
puts iptool.compress_ipv6('2002:0000:0000:1234:ffff:ffff:ffff:ffff')
5453
puts iptool.expand_ipv6('2002::1234:ffff:ffff:ffff:ffff')
54+
55+
# Country Class
56+
country = Ip2locationCountry.new('./data/IP2LOCATION-COUNTRY-INFORMATION-BASIC.CSV')
57+
puts country.get_country_info('US')
58+
59+
# Region Class
60+
region = Ip2locationRegion.new('./data/IP2LOCATION-ISO3166-2.CSV')
61+
puts region.get_region_code('US', 'California')

ip2location_ruby.gemspec

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |s|
22
s.name = "ip2location_ruby"
3-
s.version = "8.5.0"
3+
s.version = "8.6.0"
44

55
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
66
s.require_paths = ["lib"]
@@ -30,11 +30,15 @@ Gem::Specification.new do |s|
3030
"lib/ip2location_ruby/ip2location_config.rb",
3131
"lib/ip2location_ruby/ip2location_record.rb",
3232
"spec/assets/IP2LOCATION-LITE-DB1.IPV6.BIN",
33+
"spec/ip2location_ruby_country_spec.rb",
3334
"spec/ip2location_ruby_database_spec.rb",
3435
"spec/ip2location_ruby_iptools_spec.rb",
36+
"spec/ip2location_ruby_region_spec.rb",
3537
"spec/ip2location_ruby_webservice_spec.rb",
3638
"spec/spec_helper.rb",
37-
"rb/data/IP2LOCATION-LITE-DB1.IPV6.BIN"
39+
"rb/data/IP2LOCATION-LITE-DB1.IPV6.BIN",
40+
"rb/data/IP2LOCATION-COUNTRY-INFORMATION-BASIC.CSV",
41+
"rb/data/IP2LOCATION-ISO3166-2.CSV"
3842
]
3943
s.homepage = "https://github.com/ip2location/ip2location-ruby"
4044
s.licenses = ["MIT"]

lib/ip2location_ruby.rb

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'ipaddr'
44
require 'net/http'
55
require 'json'
6+
require 'csv'
67
require 'ip2location_ruby/ip2location_config'
78
require 'ip2location_ruby/database_config'
89
require 'ip2location_ruby/i2l_float_data'
@@ -13,7 +14,7 @@
1314
class Ip2location
1415
attr_accessor :record_class4, :record_class6, :v4, :file, :db_index, :count, :base_addr, :ipno, :count, :record, :database, :columns, :ip_version, :ipv4databasecount, :ipv4databaseaddr, :ipv4indexbaseaddr, :ipv6databasecount, :ipv6databaseaddr, :ipv6indexbaseaddr, :databaseyear, :databasemonth, :databaseday, :last_err_msg
1516

16-
VERSION = '8.5.0'
17+
VERSION = '8.6.0'
1718
FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
1819
INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
1920
INVALID_BIN_DATABASE = 'Incorrect IP2Location BIN file format. Please make sure that you are using the latest IP2Location BIN file.'
@@ -964,4 +965,127 @@ def expand_ipv6(ip)
964965
return
965966
end
966967
end
968+
end
969+
970+
class Ip2locationCountry
971+
attr_accessor :fields, :records
972+
973+
def initialize(csv)
974+
if csv == ''
975+
abort('The CSV file "' + csv + '" is not found.')
976+
end
977+
978+
begin
979+
csvfile = File.open(File.expand_path csv, 'rb')
980+
rescue
981+
abort('Error in opening ' + csv + '. No such CSV file in the /your_ip2location_ruby_library_path/rb/ folder.')
982+
else
983+
end
984+
985+
begin
986+
CSV.parse(csvfile)
987+
rescue
988+
abort('Unable to read "' + csv + '".')
989+
else
990+
line = 1
991+
self.records = Hash.new
992+
CSV.foreach((csvfile)) do |data|
993+
if line == 1
994+
if data[0] != 'country_code'
995+
abort('Invalid country information CSV file.')
996+
end
997+
self.fields = data
998+
else
999+
self.records[data[0]] = data
1000+
end
1001+
line = line + 1
1002+
end
1003+
end
1004+
end
1005+
1006+
def get_country_info(country_code = nil)
1007+
if self.records.empty?
1008+
abort('No record available.')
1009+
end
1010+
1011+
if country_code
1012+
if (self.records[country_code]).nil?
1013+
return []
1014+
end
1015+
results = Hash.new
1016+
for i in 0..(self.fields.length()-1)
1017+
results[self.fields[i]] = self.records[country_code][i]
1018+
end
1019+
return results
1020+
end
1021+
1022+
results = []
1023+
self.records.each do |key, value|
1024+
data = Hash.new
1025+
for i in 0..(self.fields.length()-1)
1026+
data[self.fields[i]] = self.records[key][i]
1027+
end
1028+
results = results.append(data)
1029+
end
1030+
return results
1031+
end
1032+
end
1033+
1034+
class Ip2locationRegion
1035+
attr_accessor :records
1036+
1037+
def initialize(csv)
1038+
if csv == ''
1039+
abort('The CSV file "' + csv + '" is not found.')
1040+
end
1041+
1042+
begin
1043+
csvfile = File.open(File.expand_path csv, 'rb')
1044+
rescue
1045+
abort('Error in opening ' + csv + '. No such CSV file in the /your_ip2location_ruby_library_path/rb/ folder.')
1046+
else
1047+
end
1048+
1049+
begin
1050+
CSV.parse(csvfile)
1051+
rescue
1052+
abort('Unable to read "' + csv + '".')
1053+
else
1054+
line = 1
1055+
self.records = Hash.new
1056+
CSV.foreach((csvfile)) do |data|
1057+
if line == 1
1058+
if data[1] != 'subdivision_name'
1059+
abort('Invalid region information CSV file.')
1060+
end
1061+
else
1062+
temp_data = Hash.new
1063+
temp_data['code'] = data[2]
1064+
temp_data['name'] = data[1]
1065+
if self.records[data[0]]
1066+
self.records[data[0]].push temp_data
1067+
else
1068+
self.records[data[0]] = [temp_data]
1069+
end
1070+
end
1071+
line = line + 1
1072+
end
1073+
end
1074+
end
1075+
1076+
def get_region_code(country_code, region_name)
1077+
if self.records.empty?
1078+
abort('No record available.')
1079+
end
1080+
1081+
if (self.records[country_code]).nil?
1082+
return
1083+
end
1084+
1085+
for i in 0..(self.records[country_code].length()-1)
1086+
if region_name.upcase == self.records[country_code][i]["name"].upcase
1087+
return self.records[country_code][i]["code"]
1088+
end
1089+
end
1090+
end
9671091
end

0 commit comments

Comments
 (0)