phony 1.0.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/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
|