phony 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +111 -0
- data/lib/ndc/austria.rb +69 -0
- data/lib/ndc/fixed_size.rb +113 -0
- data/lib/ndc/germany.rb +157 -0
- data/lib/ndc/prefix.rb +67 -0
- data/lib/ndc/splitter.rb +81 -0
- data/lib/phony.rb +496 -0
- data/spec/lib/ndc/austria_spec.rb +40 -0
- data/spec/lib/ndc/fixed_size_spec.rb +65 -0
- data/spec/lib/ndc/germany_spec.rb +40 -0
- data/spec/lib/ndc/prefix_spec.rb +25 -0
- data/spec/lib/ndc/splitter_spec.rb +59 -0
- data/spec/lib/phony_spec.rb +380 -0
- metadata +82 -0
data/lib/ndc/prefix.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Splits a national number using a prefix code.
|
2
|
+
#
|
3
|
+
# DSL:
|
4
|
+
# length: the length range of the dcs. For austria it is 1..4.
|
5
|
+
# format: the format of the dcs and rest. For austria it is '%s %s', default is '%s %s %s %s'.
|
6
|
+
# ndcs: an array of the prefix codes. For germany it starts with ['10', '11', '12', '13', '30'…
|
7
|
+
#
|
8
|
+
module Phony
|
9
|
+
module NDC
|
10
|
+
class Prefix < Splitter
|
11
|
+
|
12
|
+
# Splits the number into ndc and rest.
|
13
|
+
#
|
14
|
+
def self.split_ndc(number)
|
15
|
+
number = number.dup
|
16
|
+
presumed_code = ''
|
17
|
+
presumed_code << number.slice!(0..@min_ndc_length-2) if @min_ndc_length && @min_ndc_length > 1
|
18
|
+
(@min_ndc_length || 1).upto(@max_ndc_length) do |i|
|
19
|
+
presumed_code << number.slice!(0..0)
|
20
|
+
sized_ndcs = @ndcs[i]
|
21
|
+
break unless sized_ndcs && !sized_ndcs.include?(presumed_code)
|
22
|
+
end
|
23
|
+
return [presumed_code, number]
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
# Define the length range for the country's ndcs.
|
29
|
+
#
|
30
|
+
def self.length(range)
|
31
|
+
@min_ndc_length, @max_ndc_length = range.min, range.max
|
32
|
+
end
|
33
|
+
|
34
|
+
# Define the list of NDCs.
|
35
|
+
#
|
36
|
+
# Note: For optimization, if the country has a max ndc length of 4,
|
37
|
+
# only enter ndcs up to the length of 3 letters.
|
38
|
+
# If the algorithm fails to match an ndc, it will assume it is a 4 digit ndc.
|
39
|
+
#
|
40
|
+
# e.g. We have NDCs '1', '22', '333', and '4444'.
|
41
|
+
# Only set
|
42
|
+
# ndcs '1', '22', '333'
|
43
|
+
# and
|
44
|
+
# length 1..4
|
45
|
+
# '4444' will be "recognized" because the algorithm does not find a shorter ndc (assuming it
|
46
|
+
# is a correct prefix code) and stop at the max ndc length of 4, given by the length method.
|
47
|
+
#
|
48
|
+
def self.ndcs(*ndcs_ary)
|
49
|
+
@ndcs = optimize(ndcs_ary)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Optimizes and restructures the given ndcs array.
|
55
|
+
#
|
56
|
+
def self.optimize(ndcs_ary)
|
57
|
+
ndcs = {}
|
58
|
+
ndcs_ary.each do |ndc|
|
59
|
+
ndcs[ndc.length] ||= []
|
60
|
+
ndcs[ndc.length] << ndc
|
61
|
+
end
|
62
|
+
ndcs
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/ndc/splitter.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Splits a national number into a fixed size NDC and rest.
|
2
|
+
#
|
3
|
+
module Phony
|
4
|
+
module NDC
|
5
|
+
class Splitter
|
6
|
+
|
7
|
+
# Sets the local grouping format.
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
# * local 3, 2, 2 # Switzerland, 364 35 33, thus: 3-2-2.
|
11
|
+
# * local 2, 2, 2, 2 # France, 12 34 56 78, thus: 2-2-2-2.
|
12
|
+
#
|
13
|
+
def self.local *split_sizes
|
14
|
+
@split_sizes = split_sizes.flatten
|
15
|
+
format((['%s']*@split_sizes.size).join('%s'))
|
16
|
+
end
|
17
|
+
|
18
|
+
# Define a format for the country's local format.
|
19
|
+
#
|
20
|
+
# Examples
|
21
|
+
# * format '%s%s%s%s%s' # Switzerland, spaces between the groups, e.g. 364˽35˽32
|
22
|
+
#
|
23
|
+
def self.format format
|
24
|
+
@format = format
|
25
|
+
@format_with_ndc = ndc_format + @format
|
26
|
+
end
|
27
|
+
|
28
|
+
# Define a format for the country's national format.
|
29
|
+
#
|
30
|
+
# Default is NN followed by a space character.
|
31
|
+
#
|
32
|
+
def self.ndc_format
|
33
|
+
'%s%s'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Split an E164 number without country code into its NDC-Local parts.
|
37
|
+
#
|
38
|
+
# Examples
|
39
|
+
# * split '443643533' # => ['44', '364', '35', '33'] # (Switzerland)
|
40
|
+
#
|
41
|
+
def self.split number
|
42
|
+
ndc_part = split_ndc(number)
|
43
|
+
[ndc_part, split_local(ndc_part.pop)].flatten
|
44
|
+
end
|
45
|
+
|
46
|
+
# Split a local number according to an assumed country specific format.
|
47
|
+
#
|
48
|
+
# Examples
|
49
|
+
# * split '3643533' # => ['364', '35', '33'] # (Switzerland)
|
50
|
+
#
|
51
|
+
def self.split_local number
|
52
|
+
local = []
|
53
|
+
@split_sizes.each do |size|
|
54
|
+
local << number.slice!(0..size-1)
|
55
|
+
break if number.empty?
|
56
|
+
end
|
57
|
+
local
|
58
|
+
end
|
59
|
+
|
60
|
+
# Formats the given E164 Number (NDC-Local without CC) according to the country specific format / ndcs splitting.
|
61
|
+
#
|
62
|
+
def self.formatted number, space = ' '
|
63
|
+
formatted_with_spaces @format_with_ndc, split(number), space
|
64
|
+
end
|
65
|
+
|
66
|
+
# Formats the given local number according to the country specific format.
|
67
|
+
#
|
68
|
+
def self.locally_formatted number, space = ' '
|
69
|
+
formatted_with_spaces @format, split_local(number), space
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.formatted_with_spaces format, split_number, space
|
73
|
+
space ||= ' '
|
74
|
+
number_and_spaces = (split_number).zip([space]*split_number.size).flatten
|
75
|
+
format % number_and_spaces
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/lib/phony.rb
ADDED
@@ -0,0 +1,496 @@
|
|
1
|
+
begin
|
2
|
+
gem 'activesupport', '~> 3.0'
|
3
|
+
rescue LoadError
|
4
|
+
puts "phony requires activesupport ~> 3.0"
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'active_support/core_ext/object/blank'
|
8
|
+
|
9
|
+
# Framework.
|
10
|
+
#
|
11
|
+
require File.expand_path '../ndc/splitter', __FILE__
|
12
|
+
require File.expand_path '../ndc/fixed_size', __FILE__
|
13
|
+
require File.expand_path '../ndc/prefix', __FILE__
|
14
|
+
|
15
|
+
# Prefix code countries
|
16
|
+
#
|
17
|
+
require File.expand_path '../ndc/austria', __FILE__
|
18
|
+
require File.expand_path '../ndc/germany', __FILE__
|
19
|
+
|
20
|
+
# require 'Phony'
|
21
|
+
|
22
|
+
module Phony
|
23
|
+
|
24
|
+
include NDC
|
25
|
+
|
26
|
+
# Returns a fixed ndc splitter.
|
27
|
+
#
|
28
|
+
def self.fixed national_code_length = 2, options = {}
|
29
|
+
NDC.fixed national_code_length, options
|
30
|
+
end
|
31
|
+
|
32
|
+
# prefix length =>
|
33
|
+
# country code => national prefix length
|
34
|
+
@@country_codes = {
|
35
|
+
1 => {
|
36
|
+
'0' => fixed(0), # reserved
|
37
|
+
'1' => fixed(3, :local => [3, 10]), # USA, Canada, etc.
|
38
|
+
'7' => fixed(3), # Kazakhstan (Republic of) & Russian Federation
|
39
|
+
},
|
40
|
+
2 => {
|
41
|
+
'20' => fixed(2), # Egypt
|
42
|
+
'27' => fixed(2), # South Africa
|
43
|
+
|
44
|
+
'30' => fixed(2), # Greece
|
45
|
+
'31' => fixed(2), # Netherlands
|
46
|
+
'32' => fixed(2), # Belgium
|
47
|
+
'33' => fixed(1, :local => [2, 2, 2, 2]), # France
|
48
|
+
'34' => fixed(2), # Spain
|
49
|
+
'36' => fixed(2), # Hungary
|
50
|
+
'39' => fixed(3), # Italy
|
51
|
+
|
52
|
+
'40' => fixed(2), # Romania
|
53
|
+
'41' => fixed(2, :local => [3, 2, 2], :special_ndcs => ['800', '840', '842', '844', '848']), # Switzerland (Confederation of)
|
54
|
+
'43' => Austria,
|
55
|
+
'44' => fixed(2), # United Kingdom of Great Britain and Northern Ireland
|
56
|
+
'45' => fixed(2), # Denmark
|
57
|
+
'46' => fixed(2), # Sweden
|
58
|
+
'47' => fixed(2), # Norway
|
59
|
+
'48' => fixed(2), # Poland (Republic of)
|
60
|
+
'49' => Germany,
|
61
|
+
|
62
|
+
'51' => fixed(2), # Peru
|
63
|
+
'52' => fixed(2), # Mexico
|
64
|
+
'53' => fixed(2), # Cuba
|
65
|
+
'54' => fixed(2), # Argentine Republic
|
66
|
+
'55' => fixed(2), # Brazil (Federative Republic of)
|
67
|
+
'56' => fixed(2), # Chile
|
68
|
+
'57' => fixed(2), # Colombia (Republic of)
|
69
|
+
'58' => fixed(2), # Venezuela (Bolivarian Republic of)
|
70
|
+
|
71
|
+
'60' => fixed(2), # Malaysia
|
72
|
+
'61' => fixed(2), # Australia
|
73
|
+
'62' => fixed(2), # Indonesia (Republic of)
|
74
|
+
'63' => fixed(2), # Philippines (Republic of the)
|
75
|
+
'64' => fixed(1, :local => [3, 4]), # New Zealand
|
76
|
+
'65' => fixed(2), # Singapore (Republic of)
|
77
|
+
'66' => fixed(2), # Thailand
|
78
|
+
|
79
|
+
'81' => fixed(2), # Japan
|
80
|
+
'82' => fixed(2), # Korea (Republic of)
|
81
|
+
'84' => fixed(2), # Viet Nam (Socialist Republic of)
|
82
|
+
'86' => fixed(2), # China (People's Republic of)
|
83
|
+
|
84
|
+
'90' => fixed(2), # Turkey
|
85
|
+
'91' => fixed(2), # India (Republic of)
|
86
|
+
'92' => fixed(2), # Pakistan (Islamic Republic of)
|
87
|
+
'93' => fixed(2), # Afghanistan
|
88
|
+
'94' => fixed(2), # Sri Lanka (Democratic Socialist Republic of)
|
89
|
+
'95' => fixed(2), # Myanmar (Union of)
|
90
|
+
'98' => fixed(2), #Iran (Islamic Republic of)
|
91
|
+
},
|
92
|
+
3 => {
|
93
|
+
'210' => fixed(2), # -
|
94
|
+
'211' => fixed(2), # -
|
95
|
+
'212' => fixed(2), # Morocco
|
96
|
+
'213' => fixed(2), # Algeria
|
97
|
+
'214' => fixed(2), # -
|
98
|
+
'215' => fixed(2), # -
|
99
|
+
'216' => fixed(2), # Tunisia
|
100
|
+
'217' => fixed(2), # -
|
101
|
+
'218' => fixed(2), # Lybia
|
102
|
+
'219' => fixed(2), # -
|
103
|
+
|
104
|
+
'220' => fixed(2), # Gambia
|
105
|
+
'221' => fixed(2), # Senegal
|
106
|
+
'222' => fixed(2), # Mauritania
|
107
|
+
'223' => fixed(2), # Mali
|
108
|
+
'224' => fixed(2), # Guinea
|
109
|
+
'225' => fixed(2), # Côte d'Ivoire
|
110
|
+
'226' => fixed(2), # Burkina Faso
|
111
|
+
'227' => fixed(2), # Niger
|
112
|
+
'228' => fixed(2), # Togolese Republic
|
113
|
+
'229' => fixed(2), # Benin
|
114
|
+
|
115
|
+
'230' => fixed(2), # Mauritius
|
116
|
+
'231' => fixed(2), # Liberia
|
117
|
+
'232' => fixed(2), # Sierra Leone
|
118
|
+
'233' => fixed(2), # Ghana
|
119
|
+
'234' => fixed(2), # Nigeria
|
120
|
+
'235' => fixed(2), # Chad
|
121
|
+
'236' => fixed(2), # Central African Republic
|
122
|
+
'237' => fixed(2), # Cameroon
|
123
|
+
'238' => fixed(2), # Cape Verde
|
124
|
+
'239' => fixed(2), # Sao Tome and Principe
|
125
|
+
|
126
|
+
'240' => fixed(2), # Equatorial Guinea
|
127
|
+
'241' => fixed(2), # Gabonese Republic
|
128
|
+
'242' => fixed(2), # Congo
|
129
|
+
'243' => fixed(2), # Democratic Republic of the Congo
|
130
|
+
'244' => fixed(2), # Angola
|
131
|
+
'245' => fixed(2), # Guinea-Bissau
|
132
|
+
'246' => fixed(2), # Diego Garcia
|
133
|
+
'247' => fixed(2), # Ascension
|
134
|
+
'248' => fixed(2), # Seychelles
|
135
|
+
'249' => fixed(2), # Sudan
|
136
|
+
|
137
|
+
'250' => fixed(2), # Rwanda
|
138
|
+
'251' => fixed(2), # Ethiopia
|
139
|
+
'252' => fixed(2), # Somali Democratic Republic
|
140
|
+
'253' => fixed(2), # Djibouti
|
141
|
+
'254' => fixed(2), # Kenya
|
142
|
+
'255' => fixed(2), # Tanzania
|
143
|
+
'256' => fixed(2), # Uganda
|
144
|
+
'257' => fixed(2), # Burundi
|
145
|
+
'258' => fixed(2), # Mozambique
|
146
|
+
'259' => fixed(2), # -
|
147
|
+
|
148
|
+
'260' => fixed(2), # Zambia
|
149
|
+
'261' => fixed(2), # Madagascar
|
150
|
+
'262' => fixed(3), # Reunion / Mayotte (new)
|
151
|
+
'263' => fixed(2), # Zimbabwe
|
152
|
+
'264' => fixed(2), # Namibia
|
153
|
+
'265' => fixed(2), # Malawi
|
154
|
+
'266' => fixed(2), # Lesotho
|
155
|
+
'267' => fixed(2), # Botswana
|
156
|
+
'268' => fixed(2), # Swaziland
|
157
|
+
'269' => fixed(2), # Comoros
|
158
|
+
|
159
|
+
'280' => fixed(2), # -
|
160
|
+
'281' => fixed(2), # -
|
161
|
+
'282' => fixed(2), # -
|
162
|
+
'283' => fixed(2), # -
|
163
|
+
'284' => fixed(2), # -
|
164
|
+
'285' => fixed(2), # -
|
165
|
+
'286' => fixed(2), # -
|
166
|
+
'287' => fixed(2), # -
|
167
|
+
'288' => fixed(2), # -
|
168
|
+
'289' => fixed(2), # -
|
169
|
+
'290' => fixed(2), # Saint Helena
|
170
|
+
|
171
|
+
'291' => fixed(2), # Eritrea
|
172
|
+
'292' => fixed(2), # -
|
173
|
+
'293' => fixed(2), # -
|
174
|
+
'294' => fixed(2), # -
|
175
|
+
'295' => fixed(2), # -
|
176
|
+
'296' => fixed(2), # -
|
177
|
+
'297' => fixed(2), # Aruba
|
178
|
+
'298' => fixed(2), # Faroe Islands
|
179
|
+
'299' => fixed(2), # Greenland
|
180
|
+
|
181
|
+
'350' => fixed(2), # Gibraltar
|
182
|
+
'351' => fixed(2), # Portugal
|
183
|
+
'352' => fixed(2), # Luxembourg
|
184
|
+
'353' => fixed(2), # Ireland
|
185
|
+
'354' => fixed(2), # Iceland
|
186
|
+
'355' => fixed(2), # Albania
|
187
|
+
'356' => fixed(2), # Malta
|
188
|
+
'357' => fixed(2), # Cyprus
|
189
|
+
'358' => fixed(2), # Finland
|
190
|
+
'359' => fixed(2), # Bulgaria
|
191
|
+
|
192
|
+
'370' => fixed(2), # Lithuania
|
193
|
+
'371' => fixed(2), # Latvia
|
194
|
+
'372' => fixed(2), # Estonia
|
195
|
+
'373' => fixed(2), # Moldova
|
196
|
+
'374' => fixed(2), # Armenia
|
197
|
+
'375' => fixed(2), # Belarus
|
198
|
+
'376' => fixed(2), # Andorra
|
199
|
+
'377' => fixed(2), # Monaco
|
200
|
+
'378' => fixed(2), # San Marino
|
201
|
+
'379' => fixed(2), # Vatican City State
|
202
|
+
|
203
|
+
'380' => fixed(2), # Ukraine
|
204
|
+
'381' => fixed(2), # Serbia and Montenegro
|
205
|
+
'382' => fixed(2), # -
|
206
|
+
'383' => fixed(2), # -
|
207
|
+
'384' => fixed(2), # -
|
208
|
+
'385' => fixed(2), # Croatia
|
209
|
+
'386' => fixed(2), # Slovenia
|
210
|
+
'387' => fixed(2), # Bosnia and Herzegovina
|
211
|
+
'388' => fixed(2), # Group of countries, shared code
|
212
|
+
'389' => fixed(2), # The Former Yugoslav Republic of Macedonia
|
213
|
+
|
214
|
+
'420' => fixed(2), # Czech Republic
|
215
|
+
'421' => fixed(2), # Slovak Republic
|
216
|
+
'422' => fixed(2), # Spare code
|
217
|
+
'423' => fixed(0, :local => [3, 2, 2]), # Liechtenstein (Principality of)
|
218
|
+
'424' => fixed(2), # -
|
219
|
+
'425' => fixed(2), # -
|
220
|
+
'426' => fixed(2), # -
|
221
|
+
'427' => fixed(2), # -
|
222
|
+
'428' => fixed(2), # -
|
223
|
+
'429' => fixed(2), # -
|
224
|
+
|
225
|
+
'500' => fixed(2), # Falkland Islands (Malvinas)
|
226
|
+
'501' => fixed(2), # Belize
|
227
|
+
'502' => fixed(2), # Guatemala (Republic of)
|
228
|
+
'503' => fixed(2), # El Salvador (Republic of)
|
229
|
+
'504' => fixed(2), # Honduras (Republic of)
|
230
|
+
'505' => fixed(2), # Nicaragua
|
231
|
+
'506' => fixed(2), # Costa Rica
|
232
|
+
'507' => fixed(2), # Panama (Republic of)
|
233
|
+
'508' => fixed(2), # Saint Pierre and Miquelon (Collectivité territoriale de la République française)
|
234
|
+
'509' => fixed(2), # Haiti (Republic of)
|
235
|
+
|
236
|
+
'590' => fixed(3), # Guadeloupe (French Department of)
|
237
|
+
'591' => fixed(2), # Bolivia (Republic of)
|
238
|
+
'592' => fixed(2), # Guyana
|
239
|
+
'593' => fixed(2), # Ecuador
|
240
|
+
'594' => fixed(3), # French Guiana (French Department of)
|
241
|
+
'595' => fixed(2), # Paraguay (Republic of)
|
242
|
+
'596' => fixed(3), # Martinique (French Department of)
|
243
|
+
'597' => fixed(2), # Suriname (Republic of)
|
244
|
+
'598' => fixed(2), # Uruguay (Eastern Republic of)
|
245
|
+
'599' => fixed(2), # Netherlands Antilles
|
246
|
+
|
247
|
+
'670' => fixed(2), # Democratic Republic of Timor-Leste
|
248
|
+
'671' => fixed(2), # Spare code
|
249
|
+
'672' => fixed(2), # Australian External Territories
|
250
|
+
'673' => fixed(2), # Brunei Darussalam
|
251
|
+
'674' => fixed(2), # Nauru (Republic of)
|
252
|
+
'675' => fixed(2), # Papua New Guinea
|
253
|
+
'676' => fixed(2), # Tonga (Kingdom of)
|
254
|
+
'677' => fixed(2), # Solomon Islands
|
255
|
+
'678' => fixed(2), # Vanuatu (Republic of)
|
256
|
+
'679' => fixed(2), # Fiji (Republic of)
|
257
|
+
|
258
|
+
'680' => fixed(2), # Palau (Republic of)
|
259
|
+
'681' => fixed(2), # Wallis and Futuna (Territoire français d'outre-mer)
|
260
|
+
'682' => fixed(2), # Cook Islands
|
261
|
+
'683' => fixed(2), # Niue
|
262
|
+
'684' => fixed(2), # -
|
263
|
+
'685' => fixed(2), # Samoa (Independent State of)
|
264
|
+
'686' => fixed(2), # Kiribati (Republic of)
|
265
|
+
'687' => fixed(2), # New Caledonia (Territoire français d'outre-mer)
|
266
|
+
'688' => fixed(2), # Tuvalu
|
267
|
+
'689' => fixed(2), # French Polynesia (Territoire français d'outre-mer)
|
268
|
+
|
269
|
+
'690' => fixed(2), # Tokelau
|
270
|
+
'691' => fixed(2), # Micronesia (Federated States of)
|
271
|
+
'692' => fixed(2), # Marshall Islands (Republic of the)
|
272
|
+
'693' => fixed(2), # -
|
273
|
+
'694' => fixed(2), # -
|
274
|
+
'695' => fixed(2), # -
|
275
|
+
'696' => fixed(2), # -
|
276
|
+
'697' => fixed(2), # -
|
277
|
+
'698' => fixed(2), # -
|
278
|
+
'699' => fixed(2), # -
|
279
|
+
|
280
|
+
'800' => fixed(2), # International Freephone Service
|
281
|
+
'801' => fixed(2), # -
|
282
|
+
'802' => fixed(2), # -
|
283
|
+
'803' => fixed(2), # -
|
284
|
+
'804' => fixed(2), # -
|
285
|
+
'805' => fixed(2), # -
|
286
|
+
'806' => fixed(2), # -
|
287
|
+
'807' => fixed(2), # -
|
288
|
+
'808' => fixed(2), # International Shared Cost Service (ISCS)
|
289
|
+
'809' => fixed(2), # -
|
290
|
+
|
291
|
+
'830' => fixed(2), # -
|
292
|
+
'831' => fixed(2), # -
|
293
|
+
'832' => fixed(2), # -
|
294
|
+
'833' => fixed(2), # -
|
295
|
+
'834' => fixed(2), # -
|
296
|
+
'835' => fixed(2), # -
|
297
|
+
'836' => fixed(2), # -
|
298
|
+
'837' => fixed(2), # -
|
299
|
+
'838' => fixed(2), # -
|
300
|
+
'839' => fixed(2), # -
|
301
|
+
|
302
|
+
'850' => fixed(2), # Democratic People's Republic of Korea
|
303
|
+
'851' => fixed(2), # Spare code
|
304
|
+
'852' => fixed(2), # Hong Kong, China
|
305
|
+
'853' => fixed(2), # Macao, China
|
306
|
+
'854' => fixed(2), # Spare code
|
307
|
+
'855' => fixed(2), # Cambodia (Kingdom of)
|
308
|
+
'856' => fixed(2), # Lao People's Democratic Republic
|
309
|
+
'857' => fixed(2), # Spare code
|
310
|
+
'858' => fixed(2), # Spare code
|
311
|
+
'859' => fixed(2), # Spare code
|
312
|
+
|
313
|
+
'870' => fixed(2), # Inmarsat SNAC
|
314
|
+
'871' => fixed(2), # Inmarsat (Atlantic Ocean-East)
|
315
|
+
'872' => fixed(2), # Inmarsat (Pacific Ocean)
|
316
|
+
'873' => fixed(2), # Inmarsat (Indian Ocean)
|
317
|
+
'874' => fixed(2), # Inmarsat (Atlantic Ocean-West)
|
318
|
+
'875' => fixed(2), # Reserved - Maritime Mobile Service Applications
|
319
|
+
'876' => fixed(2), # Reserved - Maritime Mobile Service Applications
|
320
|
+
'877' => fixed(2), # Reserved - Maritime Mobile Service Applications
|
321
|
+
'878' => fixed(2), # Universal Personal Telecommunication Service (UPT)
|
322
|
+
'879' => fixed(2), # Reserved for national non-commercial purposes
|
323
|
+
|
324
|
+
'880' => fixed(2), # Bangladesh (People's Republic of)
|
325
|
+
'881' => fixed(2), # International Mobile, shared code
|
326
|
+
'882' => fixed(2), # International Networks, shared code
|
327
|
+
'883' => fixed(2), # -
|
328
|
+
'884' => fixed(2), # -
|
329
|
+
'885' => fixed(2), # -
|
330
|
+
'886' => fixed(2), # Reserved
|
331
|
+
'887' => fixed(2), # -
|
332
|
+
'888' => fixed(2), # Reserved for future global service
|
333
|
+
'889' => fixed(2), # -
|
334
|
+
|
335
|
+
'890' => fixed(2), # -
|
336
|
+
'891' => fixed(2), # -
|
337
|
+
'892' => fixed(2), # -
|
338
|
+
'893' => fixed(2), # -
|
339
|
+
'894' => fixed(2), # -
|
340
|
+
'895' => fixed(2), # -
|
341
|
+
'896' => fixed(2), # -
|
342
|
+
'897' => fixed(2), # -
|
343
|
+
'898' => fixed(2), # -
|
344
|
+
'899' => fixed(2), # -
|
345
|
+
|
346
|
+
'960' => fixed(2), # Maldives (Republic of)
|
347
|
+
'961' => fixed(2), # Lebanon
|
348
|
+
'962' => fixed(2), # Jordan (Hashemite Kingdom of)
|
349
|
+
'963' => fixed(2), # Syrian Arab Republic
|
350
|
+
'964' => fixed(2), # Iraq (Republic of)
|
351
|
+
'965' => fixed(2), # Kuwait (State of)
|
352
|
+
'966' => fixed(2), # Saudi Arabia (Kingdom of)
|
353
|
+
'967' => fixed(2), # Yemen (Republic of)
|
354
|
+
'968' => fixed(2), # Oman (Sultanate of)
|
355
|
+
'969' => fixed(2), # Reserved - reservation currently under investigation
|
356
|
+
|
357
|
+
'970' => fixed(2), # Reserved
|
358
|
+
'971' => fixed(2), # United Arab Emirates
|
359
|
+
'972' => fixed(2), # Israel (State of)
|
360
|
+
'973' => fixed(2), # Bahrain (Kingdom of)
|
361
|
+
'974' => fixed(2), # Qatar (State of)
|
362
|
+
'975' => fixed(2), # Bhutan (Kingdom of)
|
363
|
+
'976' => fixed(2), # Mongolia
|
364
|
+
'977' => fixed(2), # Nepal
|
365
|
+
'978' => fixed(2), # -
|
366
|
+
'979' => fixed(2), # International Premium Rate Service (IPRS)
|
367
|
+
|
368
|
+
'990' => fixed(2), # Spare code
|
369
|
+
'991' => fixed(2), # Trial of a proposed new international telecommunication public correspondence service, shared code
|
370
|
+
'992' => fixed(2), # Tajikistan (Republic of)
|
371
|
+
'993' => fixed(2), # Turkmenistan
|
372
|
+
'994' => fixed(2), # Azerbaijani Republic
|
373
|
+
'995' => fixed(2), # Georgia
|
374
|
+
'996' => fixed(2), # Kyrgyz Republic
|
375
|
+
'997' => fixed(2), # Spare code
|
376
|
+
'998' => fixed(2), # Uzbekistan (Republic of)
|
377
|
+
'999' => fixed(2), # Reserved for possible future use within the Telecommunications for Disaster Relief (TDR) concept
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
# Splits the phone number into pieces according to the country codes above.
|
382
|
+
#
|
383
|
+
def self.split(phone_number)
|
384
|
+
splitter_or_number, country_code, ndc, local = split_internal(phone_number) do |splitter, cc, ndc_local|
|
385
|
+
[splitter, cc, splitter.split_ndc(ndc_local)].flatten
|
386
|
+
end
|
387
|
+
return splitter_or_number if local.nil?
|
388
|
+
|
389
|
+
[country_code, ndc, splitter_or_number.split_local(local)].flatten
|
390
|
+
end
|
391
|
+
|
392
|
+
# Formats a E164 number according to local customs.
|
393
|
+
#
|
394
|
+
def self.formatted(phone_number, options = {})
|
395
|
+
splitter_or_number, cc, ndc, local = split_internal(phone_number) do |splitter, cc, ndc_local|
|
396
|
+
[splitter, cc, splitter.split_ndc(ndc_local)].flatten
|
397
|
+
end
|
398
|
+
return splitter_or_number if local.nil?
|
399
|
+
|
400
|
+
space = options[:spaces] || ' '
|
401
|
+
formatted_cc_ndc(cc, ndc, options[:format], space) + splitter_or_number.locally_formatted(local, space)
|
402
|
+
end
|
403
|
+
|
404
|
+
# Normalizes
|
405
|
+
#
|
406
|
+
def self.normalize(phone_number)
|
407
|
+
phone_number = phone_number.dup
|
408
|
+
phone_number.gsub!(/\D*/, '').gsub!(/^0+/, '') # Remove zeros at the beginning and non-digit chars
|
409
|
+
remove_relative_zeros! phone_number
|
410
|
+
end
|
411
|
+
|
412
|
+
# Returns true if the number starts with 4 digits and ends with 6-12 characters.
|
413
|
+
#
|
414
|
+
def self.vanity_number?(number)
|
415
|
+
(number.gsub(' ', '') =~ /^\d{4}\w{6,12}$/) ? true : false
|
416
|
+
end
|
417
|
+
|
418
|
+
# Converts any character in the vanity_number to it's numeric representation.
|
419
|
+
# Does not check if the passed number is a valid vanity_number, simply does replacement.
|
420
|
+
#
|
421
|
+
def self.vanity_to_number(vanity_number)
|
422
|
+
Vanity.replace(vanity_number)
|
423
|
+
end
|
424
|
+
|
425
|
+
module Vanity
|
426
|
+
|
427
|
+
@@mapping = [
|
428
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
|
429
|
+
'2223334445556667777888999922233344455566677778889999'
|
430
|
+
]
|
431
|
+
def self.mapping
|
432
|
+
@@mapping
|
433
|
+
end
|
434
|
+
|
435
|
+
# Replaces vanity characters of passed number with correct digits.
|
436
|
+
# Does not check for validity of vanity_number. Simply replaces all characters in the number
|
437
|
+
#
|
438
|
+
def self.replace number
|
439
|
+
number.tr *mapping
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
|
445
|
+
private
|
446
|
+
|
447
|
+
# Removes 0s from partially normalized numbers such as:
|
448
|
+
# 410443643533
|
449
|
+
#
|
450
|
+
# Example:
|
451
|
+
# 410443643533 -> 41443643533
|
452
|
+
def self.remove_relative_zeros!(phone_number, format = nil)
|
453
|
+
'%s%s' % split_cc(phone_number).collect! { |code| code.gsub(/^0+/, '') }
|
454
|
+
end
|
455
|
+
|
456
|
+
# Formats country code and national destination code.
|
457
|
+
#
|
458
|
+
def self.formatted_cc_ndc(cc, ndc, format, space = nil)
|
459
|
+
space ||= ' '
|
460
|
+
format, split_phone_number = case format
|
461
|
+
when nil, :international_absolute, :international, :+
|
462
|
+
[ndc.blank? ? '+%s%s' : '+%s%s%s%s', [cc, space, ndc, space]]
|
463
|
+
when :international_relative
|
464
|
+
[ndc.blank? ? '00%s%s' : '00%s%s%s%s', [cc, space, ndc, space]]
|
465
|
+
when :national
|
466
|
+
[ndc.blank? ? '' : '0%s%s', [ndc, space]]
|
467
|
+
when :local
|
468
|
+
['', []]
|
469
|
+
end
|
470
|
+
format % split_phone_number
|
471
|
+
end
|
472
|
+
|
473
|
+
def self.split_cc(phone_number)
|
474
|
+
split_internal(phone_number) do |splitter, cc, ndc_local|
|
475
|
+
[cc, ndc_local]
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def self.split_cc_ndc(phone_number)
|
480
|
+
split_internal(phone_number) do |splitter, cc, ndc_local|
|
481
|
+
splitter ? [cc, splitter.split_ndc(ndc_local)].flatten : [cc, ndc_local, '']
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
def self.split_internal(phone_number)
|
486
|
+
number = phone_number.dup
|
487
|
+
presumed_code = ''
|
488
|
+
1.upto(3) do |i|
|
489
|
+
presumed_code << number.slice!(0..0)
|
490
|
+
splitter = @@country_codes[i][presumed_code]
|
491
|
+
return yield(splitter, presumed_code, number) if splitter
|
492
|
+
end
|
493
|
+
return yield(nil, '', '')
|
494
|
+
end
|
495
|
+
|
496
|
+
end
|