itu_codes 0.4.3 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +88 -48
- data/lib/data/north_american_area_codes.yml +86 -64
- data/lib/itu_codes.rb +87 -40
- data/lib/itu_codes/constants.rb +3 -2
- data/lib/itu_codes/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -9,74 +9,114 @@ Country code lookup based on official ISO-3166-1 specifications:
|
|
9
9
|
* [Country Codes - ISO 3166][3]
|
10
10
|
* [list of alpha-2 country codes in XML format][4]
|
11
11
|
|
12
|
+
The main goal of this library is to closely match the latest official specifications from the ITU and the ISO relating to callign codes. If you find any discrepancies in the data, please let me know!
|
13
|
+
|
14
|
+
Some complicating factors when dealing with calling codes:
|
15
|
+
* In North America, 25 countries and territories follow the [North American Numbering Plan][5] and share the ITU code '1'.
|
16
|
+
* Russia and Kazakhstan share the ITU code '7'.
|
17
|
+
* The ITU does not use ISO 3166 alpha-2 codes to specify countries or regions in its documents.
|
18
|
+
* In general, each ITU code corresponds to exactly one ISO 3166 code. However, there are exceptions. For examples, the Australian External Territories have a single ITU code of '672', but have 4 distinct ISO 3166 codes (CC, CX, HM, NF).
|
19
|
+
|
20
|
+
|
12
21
|
## Usage:
|
13
22
|
|
14
|
-
|
15
|
-
|
23
|
+
```ruby
|
24
|
+
|
25
|
+
# The following methods are provided:
|
26
|
+
|
27
|
+
# ItuCodes.country_for(full_or_partial_number)
|
28
|
+
# ItuCodes.find_by_itu_code(code)
|
29
|
+
# ItuCodes.find_by_name(country_name)
|
30
|
+
# ItuCodes.valid_code?(exact_itu_code)
|
31
|
+
# ItuCodes.parse_code(full_or_partial_number)
|
32
|
+
# ItuCodes.parse_number(full_or_partial_number)
|
33
|
+
# ItuCodes.iso2itu(iso_2_letter_country_code)
|
34
|
+
# ItuCodes.itu2iso(exact_itu_code)
|
35
|
+
# ItuCodes.compatriots?(full_or_partial_number1, full_or_partial_number2)
|
36
|
+
|
37
|
+
|
38
|
+
# Examples
|
39
|
+
|
40
|
+
# Any full or partial number will work
|
41
|
+
ItuCodes.country_for('33')
|
42
|
+
# => "France"
|
43
|
+
|
44
|
+
# Country names are returned EXACTLY as specified in ITU E.164 document
|
45
|
+
ItuCodes.country_for('18184442222')
|
46
|
+
# => "United States of America"
|
47
|
+
|
48
|
+
ItuCodes.country_for('7')
|
49
|
+
# => [ "Kazakhstan (Republic of)", "Russian Federation" ]
|
50
|
+
|
51
|
+
ItuCodes.find_by_itu_code '995'
|
52
|
+
# => "Georgia"
|
16
53
|
|
17
|
-
|
18
|
-
|
54
|
+
ItuCodes.find_by_itu_code '123123995'
|
55
|
+
# => nil
|
19
56
|
|
20
|
-
|
21
|
-
|
57
|
+
# Name should match EXACTLY as specified in ITU E.164 document
|
58
|
+
# ItuCodes.iso2itu accepts 2 letter ISO 3166 codes
|
59
|
+
ItuCodes.find_by_name 'France'
|
60
|
+
# => "33"
|
22
61
|
|
23
|
-
|
24
|
-
|
62
|
+
ItuCodes.find_by_name 'Erewhon'
|
63
|
+
# => nil
|
25
64
|
|
26
|
-
|
27
|
-
|
65
|
+
ItuCodes.valid_code? '8392813'
|
66
|
+
# => false
|
28
67
|
|
29
|
-
|
30
|
-
|
68
|
+
ItuCodes.valid_code? '7'
|
69
|
+
# => true
|
31
70
|
|
32
|
-
|
33
|
-
|
71
|
+
ItuCodes.parse_code '18185558888'
|
72
|
+
# => 1
|
34
73
|
|
35
|
-
|
36
|
-
|
74
|
+
ItuCodes.parse_code '822'
|
75
|
+
# => "82"
|
37
76
|
|
38
|
-
|
39
|
-
|
77
|
+
ItuCodes.parse_code '4'
|
78
|
+
# => nil
|
40
79
|
|
41
|
-
|
42
|
-
|
43
|
-
# countries ...
|
44
|
-
ItuCodes.compatriots? '822', '811'
|
45
|
-
# => false
|
80
|
+
ItuCodes.parse_number '18185558888'
|
81
|
+
# => "8185558888"
|
46
82
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# => true
|
83
|
+
# Convert from and to ISO 2-letter country codes:
|
84
|
+
ItuCodes.iso2itu('US')
|
85
|
+
# => "1"
|
51
86
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# => false
|
87
|
+
# Convert from and to ISO 2-letter country codes:
|
88
|
+
ItuCodes.itu2iso('1')
|
89
|
+
# => ["AS", "AI", "AG", "BS", "BB", "BM", "VG", "CA", "KY", "DM", "DO", "GD", "GU", "JM", "MS", "MP", "PR", "KN", "LC", "VC", "SX", "TT", "TC", "US", "VI"]
|
56
90
|
|
57
|
-
|
58
|
-
|
59
|
-
|
91
|
+
# Mexico
|
92
|
+
# ISO 3361 code : MX
|
93
|
+
# ITU code : 52
|
94
|
+
ItuCodes.iso2itu('MX')
|
95
|
+
# => "52"
|
60
96
|
|
61
|
-
|
62
|
-
|
63
|
-
# => "1"
|
97
|
+
ItuCodes.itu2iso('52')
|
98
|
+
# => "MX"
|
64
99
|
|
65
|
-
|
66
|
-
|
67
|
-
|
100
|
+
# Despite the same 1st digit,
|
101
|
+
# these are for different
|
102
|
+
# countries ...
|
103
|
+
ItuCodes.compatriots? '822', '811'
|
104
|
+
# => false
|
68
105
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# => "52"
|
106
|
+
# ... but these are for
|
107
|
+
# the same country ...
|
108
|
+
ItuCodes.compatriots? '1984', '1985'
|
109
|
+
# => true
|
74
110
|
|
75
|
-
|
76
|
-
|
111
|
+
# ... and then there's the
|
112
|
+
# North American 'situation' ...
|
113
|
+
ItuCodes.compatriots? '1264', '1818'
|
114
|
+
# => false
|
77
115
|
|
116
|
+
```
|
78
117
|
|
79
118
|
[1]: http://www.itu.int/pub/T-SP-E.164D-11-2011
|
80
119
|
[2]: http://www.itu.int/dms_pub/itu-t/opb/sp/T-SP-E.164D-11-2011-PDF-E.pdf
|
81
120
|
[3]: http://www.iso.org/iso/home/standards/country_codes
|
82
|
-
[4]: http://www.iso.org/iso/home/standards/country_codes/country_names_and_code_elements_xml
|
121
|
+
[4]: http://www.iso.org/iso/home/standards/country_codes/country_names_and_code_elements_xml
|
122
|
+
[5]: http://www.nanpa.com
|
@@ -4,6 +4,90 @@
|
|
4
4
|
# * http://www.itu.int/pub/T-SP-E.164D-11-2011
|
5
5
|
# * vendor/itu/T-SP-E.164D-11-2011-PDF-E.pdf
|
6
6
|
|
7
|
+
American Samoa:
|
8
|
+
- '1684'
|
9
|
+
Anguilla:
|
10
|
+
- '1264'
|
11
|
+
Antigua and Barbuda:
|
12
|
+
- '1268'
|
13
|
+
Bahamas (Commonwealth of the):
|
14
|
+
- '1242'
|
15
|
+
Barbados:
|
16
|
+
- '1246'
|
17
|
+
Bermuda:
|
18
|
+
- '1441'
|
19
|
+
British Virgin Islands:
|
20
|
+
- '1284'
|
21
|
+
Canada:
|
22
|
+
- '1204'
|
23
|
+
- '1226'
|
24
|
+
- '1236'
|
25
|
+
- '1249'
|
26
|
+
- '1250'
|
27
|
+
- '1289'
|
28
|
+
- '1306'
|
29
|
+
- '1343'
|
30
|
+
- '1365'
|
31
|
+
- '1403'
|
32
|
+
- '1416'
|
33
|
+
- '1418'
|
34
|
+
- '1431'
|
35
|
+
- '1437'
|
36
|
+
- '1438'
|
37
|
+
- '1450'
|
38
|
+
- '1506'
|
39
|
+
- '1514'
|
40
|
+
- '1519'
|
41
|
+
- '1579'
|
42
|
+
- '1581'
|
43
|
+
- '1587'
|
44
|
+
- '1604'
|
45
|
+
- '1613'
|
46
|
+
- '1639'
|
47
|
+
- '1647'
|
48
|
+
- '1705'
|
49
|
+
- '1709'
|
50
|
+
- '1778'
|
51
|
+
- '1780'
|
52
|
+
- '1807'
|
53
|
+
- '1819'
|
54
|
+
- '1867'
|
55
|
+
- '1873'
|
56
|
+
- '1902'
|
57
|
+
- '1905'
|
58
|
+
Cayman Islands:
|
59
|
+
- '1345'
|
60
|
+
Dominica (Commonwealth of):
|
61
|
+
- '1767'
|
62
|
+
Dominican Republic:
|
63
|
+
- '1809'
|
64
|
+
- '1829'
|
65
|
+
- '1849'
|
66
|
+
Grenada:
|
67
|
+
- '1473'
|
68
|
+
Guam:
|
69
|
+
- '1671'
|
70
|
+
Jamaica:
|
71
|
+
- '1876'
|
72
|
+
Montserrat:
|
73
|
+
- '1664'
|
74
|
+
Northern Mariana Islands (Commonwealth of the):
|
75
|
+
- '1670'
|
76
|
+
Puerto Rico:
|
77
|
+
- '1787'
|
78
|
+
- '1939'
|
79
|
+
Saint Kitts and Nevis:
|
80
|
+
- '1869'
|
81
|
+
Saint Lucia:
|
82
|
+
- '1758'
|
83
|
+
Saint Vincent and the Grenadines:
|
84
|
+
- '1784'
|
85
|
+
Sint Maarten (Dutch part):
|
86
|
+
- '1721'
|
87
|
+
Trinidad and Tobago:
|
88
|
+
- '1868'
|
89
|
+
Turks and Caicos Islands:
|
90
|
+
- '1649'
|
7
91
|
United States of America:
|
8
92
|
- '1201'
|
9
93
|
- '1202'
|
@@ -328,67 +412,5 @@ United States of America:
|
|
328
412
|
- '1984'
|
329
413
|
- '1985'
|
330
414
|
- '1989'
|
331
|
-
|
332
|
-
- '
|
333
|
-
- '1226'
|
334
|
-
- '1236'
|
335
|
-
- '1249'
|
336
|
-
- '1250'
|
337
|
-
- '1289'
|
338
|
-
- '1306'
|
339
|
-
- '1343'
|
340
|
-
- '1365'
|
341
|
-
- '1403'
|
342
|
-
- '1416'
|
343
|
-
- '1418'
|
344
|
-
- '1431'
|
345
|
-
- '1437'
|
346
|
-
- '1438'
|
347
|
-
- '1450'
|
348
|
-
- '1506'
|
349
|
-
- '1514'
|
350
|
-
- '1519'
|
351
|
-
- '1579'
|
352
|
-
- '1581'
|
353
|
-
- '1587'
|
354
|
-
- '1604'
|
355
|
-
- '1613'
|
356
|
-
- '1639'
|
357
|
-
- '1647'
|
358
|
-
- '1705'
|
359
|
-
- '1709'
|
360
|
-
- '1778'
|
361
|
-
- '1780'
|
362
|
-
- '1807'
|
363
|
-
- '1819'
|
364
|
-
- '1867'
|
365
|
-
- '1873'
|
366
|
-
- '1902'
|
367
|
-
- '1905'
|
368
|
-
American Samoa: '1684'
|
369
|
-
Anguilla: '1264'
|
370
|
-
Antigua and Barbuda: '1268'
|
371
|
-
Bahamas: '1242'
|
372
|
-
Barbados: '1246'
|
373
|
-
Bermuda: '1441'
|
374
|
-
British Virgin Islands: '1284'
|
375
|
-
Cayman Islands: '1345'
|
376
|
-
Dominica: '1767'
|
377
|
-
Dominican Republic:
|
378
|
-
- '1809'
|
379
|
-
- '1829'
|
380
|
-
- '1849'
|
381
|
-
Grenada: '1473'
|
382
|
-
Guam: '1671'
|
383
|
-
Jamaica: '1876'
|
384
|
-
Montserrat: '1664'
|
385
|
-
Northern Mariana Islands: '1670'
|
386
|
-
Puerto Rico:
|
387
|
-
- '1787'
|
388
|
-
- '1939'
|
389
|
-
Saint Kitts and Nevis: '1869'
|
390
|
-
Saint Lucia: '1758'
|
391
|
-
Saint Vincent and the Grenadines: '1784'
|
392
|
-
Trinidad and Tobago: '1868'
|
393
|
-
Turks and Caicos Islands: '1649'
|
394
|
-
United States Virgin Islands: '1340'
|
415
|
+
United States Virgin Islands:
|
416
|
+
- '1340'
|
data/lib/itu_codes.rb
CHANGED
@@ -1,24 +1,52 @@
|
|
1
|
-
# to-do: deal with headache codes:
|
2
|
-
# 1 --> Non-US need to be separated by area code
|
3
|
-
# 7 --> Kazakhstan!
|
4
|
-
|
5
1
|
require 'itu_codes/constants'
|
6
2
|
require 'itu_codes/helpers'
|
7
3
|
|
8
|
-
# TODO: add ability to search for common names (i.e. 'USA' or 'United States of America' for 'United States')
|
9
|
-
|
10
4
|
module ItuCodes
|
11
5
|
class << self
|
12
|
-
def find_by_itu_code(code)
|
13
|
-
returner = lookup(code)
|
14
6
|
|
15
|
-
|
16
|
-
|
7
|
+
# number is a full or partial number
|
8
|
+
def country_for(number)
|
9
|
+
parsed = parse_code(number)
|
10
|
+
|
11
|
+
return if parsed.nil?
|
12
|
+
|
13
|
+
matching_countries = if north_american?(parsed)
|
14
|
+
north_american_codes.select do |k, v|
|
15
|
+
v.any? do |na_area_code|
|
16
|
+
na_area_code =~ /^#{number[0,4]}/
|
17
|
+
end
|
18
|
+
end.keys
|
19
|
+
elsif eurasian?(parsed)
|
20
|
+
temp = []
|
21
|
+
temp << "Kazakhstan (Republic of)" if kazakh?(number[0,2])
|
22
|
+
temp << "Russian Federation" if russian?(number[0,2])
|
23
|
+
temp
|
17
24
|
else
|
18
|
-
|
25
|
+
country_codes[parsed]
|
26
|
+
end
|
27
|
+
|
28
|
+
if matching_countries.is_a?(Array) && matching_countries.length === 1
|
29
|
+
matching_countries.first
|
30
|
+
else
|
31
|
+
matching_countries
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Must pass a valid ITU code
|
36
|
+
def find_by_itu_code(code)
|
37
|
+
if valid_code?(code)
|
38
|
+
returner = country_for(code)
|
39
|
+
|
40
|
+
if returner.size <= 1
|
41
|
+
returner.first
|
42
|
+
else
|
43
|
+
returner
|
44
|
+
end
|
19
45
|
end
|
20
46
|
end
|
21
47
|
|
48
|
+
# Passed name must match exact name specified in ITU spec
|
49
|
+
# see: lib/data/assigned_country_codes.yml
|
22
50
|
def find_by_name(name)
|
23
51
|
matching = country_codes.select do |k, v|
|
24
52
|
[*v].include? name
|
@@ -33,16 +61,17 @@ module ItuCodes
|
|
33
61
|
end
|
34
62
|
end
|
35
63
|
|
36
|
-
# lookup by ISO 3166 country code
|
37
|
-
# e.g.
|
64
|
+
# lookup by ISO 3166 alpha-2 country code
|
65
|
+
# e.g. find_by_iso_code('US')
|
38
66
|
# see : http://www.iso.org/iso/country_codes.htm
|
39
67
|
def iso2itu(iso_code)
|
40
68
|
country_name = Helpers.country_name_lookup(iso_code)
|
41
69
|
find_by_name(country_name)
|
42
70
|
end
|
43
71
|
|
44
|
-
|
45
|
-
|
72
|
+
# number is a full or partial number
|
73
|
+
def itu2iso(number)
|
74
|
+
name = country_for(number)
|
46
75
|
|
47
76
|
if name.is_a?(String)
|
48
77
|
Helpers.country_code_lookup(name)
|
@@ -60,10 +89,6 @@ module ItuCodes
|
|
60
89
|
country_codes.has_key?(some_code)
|
61
90
|
end
|
62
91
|
|
63
|
-
def north_american?(some_code)
|
64
|
-
some_code[0,1] == '1'
|
65
|
-
end
|
66
|
-
|
67
92
|
# parse a destination code (probably with area code) to find the ITU code
|
68
93
|
# ex: parse_code(1818) => 1
|
69
94
|
def parse_code(some_number)
|
@@ -78,33 +103,62 @@ module ItuCodes
|
|
78
103
|
# ex: parse_number(18184443322) => 8184443322
|
79
104
|
def parse_number(some_number)
|
80
105
|
country_code = parse_code(some_number)
|
81
|
-
some_number.
|
106
|
+
some_number[country_code.length,some_number.length] unless country_code.nil?
|
82
107
|
end
|
83
108
|
|
84
109
|
def compatriots?(some, other)
|
85
|
-
both_valid = ! ( parse_code(some).nil?
|
110
|
+
both_valid = ! ( parse_code(some).nil? || parse_code(other).nil? )
|
86
111
|
|
87
112
|
if north_american?(some) && north_american?(other)
|
88
|
-
both_valid && !(
|
113
|
+
both_valid && !([*country_for(some)] & [*country_for(other)]).empty?
|
114
|
+
elsif eurasian?(some) && eurasian?(other)
|
115
|
+
both_valid && !([*country_for(some)] & [*country_for(other)]).empty?
|
89
116
|
else
|
90
117
|
some = parse_code(some)
|
91
118
|
other = parse_code(other)
|
92
|
-
both_valid &&
|
119
|
+
both_valid && some === other
|
93
120
|
end
|
94
121
|
end
|
95
122
|
|
123
|
+
def north_american?(some_code)
|
124
|
+
some_code[0,1] == '1'
|
125
|
+
end
|
126
|
+
|
127
|
+
def eurasian?(some_code)
|
128
|
+
some_code[0,1] == '7'
|
129
|
+
end
|
130
|
+
|
96
131
|
def american?(some_code)
|
97
|
-
|
98
|
-
# for US, '1' will be returned
|
99
|
-
countries = lookup(some_code[0,4]) || []
|
100
|
-
countries.include?('United States of America')
|
132
|
+
[* country_for(some_code) ].include?('United States of America')
|
101
133
|
end
|
102
134
|
|
103
135
|
def canadian?(some_code)
|
104
|
-
|
105
|
-
north_american?(some_code) && (countries.include?('Canada'))
|
136
|
+
[* country_for(some_code) ].include?('Canada')
|
106
137
|
end
|
107
138
|
|
139
|
+
# Russian codes start with 7
|
140
|
+
# and are not codes defined for Kazakhstan
|
141
|
+
def russian?(some_code)
|
142
|
+
if some_code.length < 2
|
143
|
+
eurasian?(some_code)
|
144
|
+
else
|
145
|
+
eurasian?(some_code) && !kazakh?(some_code)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Kazakhstan country code will start with either 76 or 77
|
150
|
+
# see: http://www.itu.int/oth/T020200006F/en
|
151
|
+
# http://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006F0001PDFE.pdf
|
152
|
+
# NOTE: apparently, some numbers are still jointly used by Kazakhstan and Russia
|
153
|
+
# 7000-0009, 7100-7199, 7200-7299, 7800-7809, 7881-7899
|
154
|
+
# ItuCodes reports these as Russian codes for the time being
|
155
|
+
def kazakh?(some_code)
|
156
|
+
if some_code.length < 2
|
157
|
+
eurasian?(some_code)
|
158
|
+
else
|
159
|
+
%(77 76).include?(some_code[0,2])
|
160
|
+
end
|
161
|
+
end
|
108
162
|
|
109
163
|
private
|
110
164
|
|
@@ -112,19 +166,12 @@ module ItuCodes
|
|
112
166
|
Constants::NORTH_AMERICAN_AREA_CODES
|
113
167
|
end
|
114
168
|
|
115
|
-
def
|
116
|
-
Constants::
|
169
|
+
def eurasian_codes
|
170
|
+
Constants::NORTH_AMERICAN_AREA_CODES
|
117
171
|
end
|
118
172
|
|
119
|
-
def
|
120
|
-
|
121
|
-
matching_countries = country_codes[cleaned] || []
|
122
|
-
|
123
|
-
matching_north_americans = north_american_codes.select do |k, v|
|
124
|
-
[*v].include?(code)
|
125
|
-
end || {}
|
126
|
-
|
127
|
-
[*matching_countries] + matching_north_americans.keys.compact
|
173
|
+
def country_codes
|
174
|
+
Constants::ASSIGNED_COUNTRY_CODES
|
128
175
|
end
|
129
176
|
|
130
177
|
# converts input to string, then strips any non-numeric characters
|
data/lib/itu_codes/constants.rb
CHANGED
@@ -2,7 +2,8 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
module ItuCodes
|
4
4
|
module Constants
|
5
|
-
|
6
|
-
|
5
|
+
base_path = File.expand_path(File.dirname(__FILE__))
|
6
|
+
ASSIGNED_COUNTRY_CODES = YAML.load_file base_path + '/../data/assigned_country_codes.yml'
|
7
|
+
NORTH_AMERICAN_AREA_CODES = YAML.load_file base_path + '/../data/north_american_area_codes.yml'
|
7
8
|
end
|
8
9
|
end
|
data/lib/itu_codes/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: itu_codes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|