nt54 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/README.md +121 -0
- data/Rakefile +25 -0
- data/lib/nt54.rb +16 -0
- data/lib/nt54/area.rb +15 -0
- data/lib/nt54/areas.csv +307 -0
- data/lib/nt54/parser.rb +91 -0
- data/lib/nt54/parser/machinery.rb +52 -0
- data/lib/nt54/parser/visitor.rb +35 -0
- data/lib/nt54/parser/visitors/dialtone.rb +26 -0
- data/lib/nt54/parser/visitors/wait_for_area_code.rb +17 -0
- data/lib/nt54/parser/visitors/wait_for_area_code_completion.rb +32 -0
- data/lib/nt54/parser/visitors/wait_for_area_code_or_mobile_prefix_completion.rb +23 -0
- data/lib/nt54/parser/visitors/wait_for_country_code_end.rb +14 -0
- data/lib/nt54/parser/visitors/wait_for_country_code_start.rb +14 -0
- data/lib/nt54/parser/visitors/wait_for_local_number.rb +12 -0
- data/lib/nt54/parser/visitors/wait_for_local_prefix.rb +19 -0
- data/lib/nt54/parser/visitors/wait_for_mobile_prefix_completion.rb +13 -0
- data/lib/nt54/parser/visitors/wait_for_mobile_prefix_or_area_code.rb +21 -0
- data/lib/nt54/parser/visitors/wait_for_prefix.rb +18 -0
- data/lib/nt54/parser/visitors/wait_for_special_number_completion.rb +12 -0
- data/lib/nt54/phone_number.rb +83 -0
- data/lib/nt54/province.rb +14 -0
- data/lib/nt54/provinces.csv +25 -0
- data/lib/nt54/special_number.rb +10 -0
- data/lib/nt54/special_numbers.csv +14 -0
- data/lib/nt54/version.rb +3 -0
- data/nt54.gemspec +18 -0
- data/test/helper.rb +5 -0
- data/test/parser_test.rb +57 -0
- metadata +108 -0
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# NT54
|
2
|
+
|
3
|
+
Parsing, validation, meta-information and formatting for Argentine phone
|
4
|
+
numbers.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
require "nt54"
|
9
|
+
|
10
|
+
# Parsing
|
11
|
+
number = NT54::Parser.parse("0291-15-555-4444")
|
12
|
+
number.area_code # => "291"
|
13
|
+
number.local_prefix # => "555"
|
14
|
+
number.local_number # => "4444"
|
15
|
+
number.country_code # => "54"
|
16
|
+
number.mobile? # => true
|
17
|
+
|
18
|
+
# Validation
|
19
|
+
number = NT54::Parser.parse("0291-15-555-4444")
|
20
|
+
number.valid? # => true
|
21
|
+
NT54::Parser.valid?("0291-15-555-4444") # => true
|
22
|
+
NT54::Parser.valid?("03864-22-4444") # => false (there's no 3864 area code)
|
23
|
+
|
24
|
+
# Meta-information
|
25
|
+
number.area.city # => "Bahía Blanca"
|
26
|
+
number.area.province.code # => "B"
|
27
|
+
number.area.province.name # => "Buenos Aires"
|
28
|
+
number.area.lat # => "-38.71167760000001"
|
29
|
+
number.area.lng # => "-62.26807789999999"
|
30
|
+
|
31
|
+
# Formatting
|
32
|
+
number.format_international # => "+54 9 (291) 555-4444"
|
33
|
+
number.format_international_sms # => "+54 (291) 555-4444"
|
34
|
+
number.format_national # => "(0291) 15 555-4444"
|
35
|
+
number.format_local # => "15 555-4444"
|
36
|
+
|
37
|
+
# Special number handling
|
38
|
+
number = NT54::Parser.parse("100")
|
39
|
+
number.special? # => true
|
40
|
+
number.special.comment # => "Bomberos"
|
41
|
+
number.special.comment_en # => "Fire department"
|
42
|
+
|
43
|
+
## More info
|
44
|
+
|
45
|
+
Simple phone number formats like the one used for North America can be somewhat
|
46
|
+
easily described with regular expressions, but Argentina's phone numbers are
|
47
|
+
quite complex. For example, area codes can be 2-4 numbers long and can overlap.
|
48
|
+
A prefix is used to denote mobile verse non-mobile numbers, and this prefix
|
49
|
+
changes number and position when dialing internationally. The prefix must be
|
50
|
+
used when calling internationally, but not when sending SMS internationally.
|
51
|
+
|
52
|
+
This means that Argentine phone numbers are best captured with a grammar, rather
|
53
|
+
than regular expressions, so NT54 uses a finite state machine to process the
|
54
|
+
number like a real hardware or software dialer.
|
55
|
+
|
56
|
+
If you're curious, you can debug the phone number processing like this:
|
57
|
+
|
58
|
+
D, [2012-01-24T15:29:00.993893 #10077] DEBUG -- : new state: Dialtone
|
59
|
+
D, [2012-01-24T15:29:00.994076 #10077] DEBUG -- : got 0
|
60
|
+
D, [2012-01-24T15:29:00.994209 #10077] DEBUG -- : triggering area_code_indicated
|
61
|
+
D, [2012-01-24T15:29:00.994272 #10077] DEBUG -- : new state: WaitForAreaCode
|
62
|
+
D, [2012-01-24T15:29:00.994320 #10077] DEBUG -- : got 2
|
63
|
+
D, [2012-01-24T15:29:00.994352 #10077] DEBUG -- : got 9
|
64
|
+
D, [2012-01-24T15:29:00.994660 #10077] DEBUG -- : got 1
|
65
|
+
D, [2012-01-24T15:29:00.994738 #10077] DEBUG -- : triggering area_code_potentially_completed
|
66
|
+
D, [2012-01-24T15:29:00.994804 #10077] DEBUG -- : new state: WaitForAreaCodeCompletion
|
67
|
+
D, [2012-01-24T15:29:00.994871 #10077] DEBUG -- : got 1
|
68
|
+
D, [2012-01-24T15:29:00.994910 #10077] DEBUG -- : 291 is a valid area code
|
69
|
+
D, [2012-01-24T15:29:00.994951 #10077] DEBUG -- : triggering mobile_prefix_started
|
70
|
+
D, [2012-01-24T15:29:00.994999 #10077] DEBUG -- : new state: WaitForMobilePrefixCompletion
|
71
|
+
D, [2012-01-24T15:29:00.995040 #10077] DEBUG -- : got 5
|
72
|
+
D, [2012-01-24T15:29:00.995071 #10077] DEBUG -- : triggering mobile_prefix_completed
|
73
|
+
D, [2012-01-24T15:29:00.995120 #10077] DEBUG -- : new state: WaitForLocalPrefix
|
74
|
+
D, [2012-01-24T15:29:00.995150 #10077] DEBUG -- : got 4
|
75
|
+
D, [2012-01-24T15:29:00.995213 #10077] DEBUG -- : got 4
|
76
|
+
D, [2012-01-24T15:29:00.995247 #10077] DEBUG -- : got 4
|
77
|
+
D, [2012-01-24T15:29:00.995281 #10077] DEBUG -- : got 5
|
78
|
+
D, [2012-01-24T15:29:00.995329 #10077] DEBUG -- : triggering local_prefix_completed
|
79
|
+
D, [2012-01-24T15:29:00.995371 #10077] DEBUG -- : new state: WaitForLocalNumber
|
80
|
+
D, [2012-01-24T15:29:00.995413 #10077] DEBUG -- : got 5
|
81
|
+
D, [2012-01-24T15:29:00.995441 #10077] DEBUG -- : got 5
|
82
|
+
D, [2012-01-24T15:29:00.997847 #10077] DEBUG -- : got 5
|
83
|
+
#<NT54::PhoneNumber:0x007f8e91058120
|
84
|
+
@area_code="291",
|
85
|
+
@country_code="54",
|
86
|
+
@local_number="5555",
|
87
|
+
@local_prefix="444",
|
88
|
+
@mobile=true>
|
89
|
+
|
90
|
+
## Installation
|
91
|
+
|
92
|
+
gem install nt54
|
93
|
+
|
94
|
+
## Author
|
95
|
+
|
96
|
+
[Norman Clarke](mailto:norman@njclarke.com)
|
97
|
+
|
98
|
+
## Changelog
|
99
|
+
|
100
|
+
* 2012-01-24 - Initial release
|
101
|
+
|
102
|
+
## License
|
103
|
+
|
104
|
+
Copyright (c) 2012 Norman Clarke
|
105
|
+
|
106
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
107
|
+
this software and associated documentation files (the "Software"), to deal in
|
108
|
+
the Software without restriction, including without limitation the rights to
|
109
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
110
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
111
|
+
subject to the following conditions:
|
112
|
+
|
113
|
+
The above copyright notice and this permission notice shall be included in all
|
114
|
+
copies or substantial portions of the Software.
|
115
|
+
|
116
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
117
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
118
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
119
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
120
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
121
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
task :default => :test
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs = ["lib"]
|
8
|
+
t.verbose = false
|
9
|
+
t.test_files = FileList['test/*_test.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
task :clean do
|
13
|
+
%x{rm -rf *.gem doc pkg coverage}
|
14
|
+
%x{rm -f `find . -name '*.rbc'`}
|
15
|
+
end
|
16
|
+
|
17
|
+
task :gem do
|
18
|
+
%x{gem build nt54.gemspec}
|
19
|
+
end
|
20
|
+
|
21
|
+
task :yard => :guide do
|
22
|
+
puts %x{bundle exec yard}
|
23
|
+
end
|
24
|
+
|
25
|
+
task :doc => :yard
|
data/lib/nt54.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "csv"
|
3
|
+
require "pathname"
|
4
|
+
require "pp"
|
5
|
+
require "ambry"
|
6
|
+
require "micromachine"
|
7
|
+
require "nt54/phone_number"
|
8
|
+
require "nt54/parser"
|
9
|
+
require "nt54/province"
|
10
|
+
require "nt54/area"
|
11
|
+
require "nt54/special_number"
|
12
|
+
|
13
|
+
module NT54
|
14
|
+
extend self
|
15
|
+
attr_accessor :log
|
16
|
+
end
|
data/lib/nt54/area.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module NT54
|
2
|
+
class Area
|
3
|
+
extend Ambry::Model
|
4
|
+
field :code, :city, :province_code, :comment, :lat, :lng
|
5
|
+
|
6
|
+
def province
|
7
|
+
Province.get(province_code)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
CSV.foreach(Pathname(__FILE__).dirname.join("areas.csv")) do |row|
|
12
|
+
Area.create Hash[[:code, :city, :province_code, :comment].zip(row)]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/lib/nt54/areas.csv
ADDED
@@ -0,0 +1,307 @@
|
|
1
|
+
11,Buenos Aires,C,,-34.6084175,-58.37316130000001
|
2
|
+
220,Pontevedra,B,,-34.74426400000001,-58.7001579
|
3
|
+
2202,González Catán,B,,-34.7627204,-58.6300804
|
4
|
+
221,La Plata,B,,-34.9173012,-57.9501305
|
5
|
+
2221,Atalaya,B,,-35.0268593,-57.53101729999999
|
6
|
+
2223,Altamirano,B,,-35.36700800000001,-58.1614
|
7
|
+
2224,Glew,B,,-34.8854021,-58.3812772
|
8
|
+
2225,Alejandro Korn,B,,-34.9710848,-58.38823009999999
|
9
|
+
2226,Alejandro Petión,B,,-34.6084175,-58.37316130000001
|
10
|
+
2227,Antonio Carboni,B,,-35.2000008,-59.3333282
|
11
|
+
2229,Juan María Gutiérrez,B,,-34.5871849,-58.3991699
|
12
|
+
223,Mar del Plata,B,,-37.9798584,-57.5897942
|
13
|
+
2241,Chascomús,B,,-35.5654907,-58.0160484
|
14
|
+
2242,Pila,B,,-36.0017624,-58.1404037
|
15
|
+
2243,General Belgrano,B,,-35.7671432,-58.4959946
|
16
|
+
2244,Las Flores,B,,-33.75,-59.9333305
|
17
|
+
2245,Dolores,B,,-36.3145485,-57.68008039999999
|
18
|
+
2246,Santa Teresita,B,,-36.5437544,-56.702013
|
19
|
+
2252,San Clemente del Tuyú,B,,-36.3695702,-56.7175713
|
20
|
+
2254,Cariló,B,,-37.1615028,-56.8993073
|
21
|
+
2255,Villa Gesell,B,,-37.2633972,-56.9732704
|
22
|
+
2257,Mar de Ajó,B,,-36.7311783,-56.6819267
|
23
|
+
2261,Lobería,B,,-38.1640892,-58.7817154
|
24
|
+
2262,Necochea,B,,-38.5544968,-58.73960879999999
|
25
|
+
2264,Claraz,B,,-37.8900948,-59.2902184
|
26
|
+
2265,Coronel Vidal,B,,-37.4456291,-57.726944
|
27
|
+
2266,Mechongué,B,,-38.15000149999999,-58.216671
|
28
|
+
2267,General Madariaga,B,,-37.03333,-57.13333
|
29
|
+
2268,General Guido,B,,-36.7210945,-57.9162555
|
30
|
+
2271,Abbott,B,,-35.282589,-58.8043213
|
31
|
+
2272,Las Marianas,B,,-35.06560899999999,-59.5156784
|
32
|
+
2273,Carmen de Areco,B,,-34.3806686,-59.8223267
|
33
|
+
2274,Carlos Spegazzini,B,,-34.6193051,-58.4263416
|
34
|
+
2281,Azul,B,,-36.7749672,-59.8540382
|
35
|
+
2283,Tapalqué,B,,-36.355545,-60.0236549
|
36
|
+
2284,Olavarría,B,,-36.8920898,-60.3149414
|
37
|
+
2285,Laprida,B,,-37.5454292,-60.7987099
|
38
|
+
2286,La Colina,B,,-37.3615913,-61.5340996
|
39
|
+
2291,Mar del Sur,B,,-38.34144209999999,-57.99058909999999
|
40
|
+
2292,Benito Juárez,B,,-37.6734123,-59.8051033
|
41
|
+
2293,Tandil,B,,-37.3178101,-59.1503906
|
42
|
+
2296,Ayacucho,B,,-37.1502686,-58.4829712
|
43
|
+
2297,Rauch,B,,-36.7749176,-59.0897865
|
44
|
+
2302,General Pico,L,,-35.6569519,-63.75454709999999
|
45
|
+
2314,Espigas,B,,-36.4169312,-60.6774902
|
46
|
+
2316,Arboledas,B,,-36.8838501,-61.4822388
|
47
|
+
2317,Carlos María Naón,B,,-35.246891,-60.8367882
|
48
|
+
2320,Del Viso,B,,-34.4792247,-58.79967199999999
|
49
|
+
2322,Fátima,B,,-34.4259919,-58.9965377
|
50
|
+
2323,Luján,B,,-34.565731,-59.1174316
|
51
|
+
2324,Mercedes,B,,-34.6546021,-59.4284134
|
52
|
+
2325,Azcuénaga,B,,-34.3833313,-59.34999850000001
|
53
|
+
2326,Duggan,B,,-34.2072449,-59.6355782
|
54
|
+
2331,Realicó,L,,-35.0380173,-64.2465744
|
55
|
+
2333,Quemú Quemú,L,,-36.0488892,-63.5504112
|
56
|
+
2334,Eduardo Castex,L,,-35.9136543,-64.2888718
|
57
|
+
2335,Ingeniero Luiggi,L,,-35.3858719,-64.4675903
|
58
|
+
2336,Huinca Renancó,X,,-34.8402596,-64.37178039999999
|
59
|
+
2337,Fortín Olavarría,B,,-35.7110596,-63.02032089999999
|
60
|
+
2338,Victorica,L,,-36.2161713,-65.4323502
|
61
|
+
2342,Bragado,B,,-35.1199112,-60.48142619999999
|
62
|
+
2343,Elvira,B,,-35.2331505,-59.4827309
|
63
|
+
2344,Álvarez de Toledo,B,,-35.6375122,-59.62751009999999
|
64
|
+
2345,Mosconi,B,,-35.7412682,-60.56213
|
65
|
+
2346,Chivilcoy,B,,-34.8972397,-60.018837
|
66
|
+
2352,Chacabuco,B,,-34.63593290000001,-60.4651222
|
67
|
+
2353,Arribeños,B,,-34.2097626,-61.3543663
|
68
|
+
2354,El Dorado,B,,-34.6508789,-61.5838585
|
69
|
+
2355,Lincoln,B,,-34.8678589,-61.53442
|
70
|
+
2356,Coronel Granada,B,,-34.7897377,-62.20030209999999
|
71
|
+
2357,Carlos Salas,B,,-35.3924484,-61.99036030000001
|
72
|
+
2358,Zavalía,B,,-34.8937607,-61.00455859999999
|
73
|
+
2362,Junín,B,,-34.5822105,-60.94940190000001
|
74
|
+
237,Francisco Álvarez,B,,-34.6056091,-58.85812389999999
|
75
|
+
2392,Berutti,B,,-35.8551674,-62.51066590000001
|
76
|
+
2393,Salazar,B,,-36.3066902,-62.20112990000001
|
77
|
+
2394,Quenumá,B,,-36.5679893,-63.08898929999999
|
78
|
+
2395,Bellocq,B,,-35.9170494,-61.5426598
|
79
|
+
2396,Chiclana,B,,-35.7327118,-61.7404366
|
80
|
+
2473,Wheelwright,S,,-33.782959,-61.2158203
|
81
|
+
2474,Gahan,B,,-34.3352432,-60.0972443
|
82
|
+
2475,Carabelas,B,,-34.0364685,-60.8659592
|
83
|
+
2477,Pergamino,B,,-33.8881416,-60.5693359
|
84
|
+
2478,Arrecifes,B,,-34.0638771,-60.10348889999999
|
85
|
+
261,Mendoza,M,,-32.890183,-68.8440498
|
86
|
+
2622,Colonia Las Rosas,M,,-33.5999985,-69.0999985
|
87
|
+
2623,San Martín,M,,-33.0799789,-68.4694595
|
88
|
+
2624,Cacheuta,M,,-33.0386314,-69.1012573
|
89
|
+
2625,Bowen,M,,-34.999691,-67.5164795
|
90
|
+
2626,Arroyito,M,,-32.8333282,-67.3000107
|
91
|
+
2627,San Rafael,M,,-34.6131516,-68.341011
|
92
|
+
264,San Juan,J,,-31.5272732,-68.5214081
|
93
|
+
2646,Astica,J,,-30.9320107,-67.3846512
|
94
|
+
2647,Colangüil,J,,-30.0343609,-69.2403793
|
95
|
+
2648,Calingasta,J,,-31.3184566,-69.42536160000002
|
96
|
+
2651,San Francisco del Monte de Oro,D,,-32.5991783,-66.1322021
|
97
|
+
2655,La Toma,D,,-33.0548161,-65.61749429999999
|
98
|
+
2656,Merlo,D,,-32.3492393,-65.0335693
|
99
|
+
2657,Justo Daract,D,,-33.8653603,-65.18463129999999
|
100
|
+
2658,Buena Esperanza,D,,-34.756794,-65.2529907
|
101
|
+
266,San Luis,D,,-33.2995605,-66.3491821
|
102
|
+
280,Trelew,U,,-43.2491302,-65.3074036
|
103
|
+
2901,Ushuaia,V,,-54.79167940000001,-68.229248
|
104
|
+
2902,El Calafate,Z,,-50.3402138,-72.27050779999999
|
105
|
+
2903,Pastos Blancos,U,,-45.3,-70.5
|
106
|
+
291,Bahía Blanca,B,,-38.71167760000001,-62.26807789999999
|
107
|
+
2920,Viedma,R,,-40.8119087,-62.9962044
|
108
|
+
2921,Coronel Dorrego,B,,-38.7194366,-61.28545759999999
|
109
|
+
2922,Coronel Pringles,B,,-37.9854202,-61.3540382
|
110
|
+
2923,Arroyo Corto,B,,-37.5128212,-62.3171997
|
111
|
+
2924,Santa Teresa,L,,-37.5666667,-63.41666670000001
|
112
|
+
2925,Felipe Solá,B,,-38.0075912,-62.81608199999999
|
113
|
+
2926,Coronel Suárez,B,,-37.4559517,-61.93072509999999
|
114
|
+
2927,Algarrobo,B,,-38.8949089,-63.1354523
|
115
|
+
2928,Hilario Ascasubi,B,,-39.3760529,-62.64558030000001
|
116
|
+
2929,Casbas,B,,-36.7571449,-62.5028076
|
117
|
+
2931,General Conesa,R,,-40.1037178,-64.45793909999999
|
118
|
+
2932,Punta Alta,B,,-38.8760605,-62.07408909999999
|
119
|
+
2933,Huanguelen Sur,B,,-34.6084175,-58.37316130000001
|
120
|
+
2934,San Antonio Oeste,R,,-40.7428017,-64.9676514
|
121
|
+
2935,Rivera,B,,-37.1594315,-63.24351119999999
|
122
|
+
2936,Carhué,B,,-37.1780663,-62.75482179999999
|
123
|
+
2940,Ingeniero Jacobacci,R,,-41.3285255,-69.5493011
|
124
|
+
2942,Zapala,Q,,-38.9023615,-70.06534049999999
|
125
|
+
2944,San Carlos de Bariloche,R,,-41.1492882,-71.3012695
|
126
|
+
2945,Esquel,U,,-42.9067192,-71.3081055
|
127
|
+
2946,Choele Choel,R,,-39.2879906,-65.66539759999999
|
128
|
+
2948,Chos Malal,Q,,-37.3793945,-70.2700043
|
129
|
+
2952,General Acha,L,,-37.3761444,-64.6000443
|
130
|
+
2953,Macachín,L,,-37.1502686,-63.64928819999999
|
131
|
+
2954,Santa Rosa,L,,-36.6226883,-64.2859268
|
132
|
+
2962,San Julián,Z,,-49.305111,-67.70797
|
133
|
+
2963,Los Antiguos,Z,,-46.5486283,-71.6319773
|
134
|
+
2964,Río Grande,V,,-53.79180909999999,-67.7197266
|
135
|
+
2966,Río Gallegos,Z,,-51.6329918,-69.2276001
|
136
|
+
297,Comodoro Rivadavia,U,,-45.8679199,-67.5
|
137
|
+
2972,San Martín de los Andes,Q,,-40.1550903,-71.3541946
|
138
|
+
298,General Roca,R,,-39.0267525,-67.5751724
|
139
|
+
2982,Orense,B,,-38.6870613,-59.773838
|
140
|
+
2983,Tres Arroyos,B,,-38.3763123,-60.2781296
|
141
|
+
299,Neuquén,Q,,-38.9492798,-68.0658112
|
142
|
+
3327,Benavídez,B,,-34.4151715,-58.6867547
|
143
|
+
3329,Alsina,B,,-33.9080009,-59.3892059
|
144
|
+
3382,Rufino,S,,-34.266468,-62.7097206
|
145
|
+
3385,Laboulaye,X,,-34.127224,-63.3895645
|
146
|
+
3387,Italó,X,,-34.783329,-63.7666702
|
147
|
+
3388,Banderaló,B,,-35.0161705,-63.37463
|
148
|
+
3400,Villa Constitución,S,,-33.2336388,-60.3341713
|
149
|
+
3401,El Trébol,S,,-32.1980158,-61.70194999999999
|
150
|
+
3402,Arroyo Seco,S,,-33.161659,-60.51317999999999
|
151
|
+
3404,Gálvez,S,,-32.03339,-61.2158203
|
152
|
+
3405,San Javier,S,,-30.5831909,-59.9496384
|
153
|
+
3406,San Jorge,S,,-31.8962113,-61.85977699999999
|
154
|
+
3407,El Paraíso,B,,-33.5769615,-59.98809809999999
|
155
|
+
3408,San Cristóbal,S,,-30.3069038,-61.2378159
|
156
|
+
3409,Colonia Bossi,S,,-30.6688976,-61.78675080000001
|
157
|
+
341,Rosario,S,,-32.9507408,-60.66650010000001
|
158
|
+
342,Coronda,S,,-31.9728813,-60.9193039
|
159
|
+
343,Paraná,E,,-31.7413197,-60.51154709999999
|
160
|
+
3435,Lucas González,E,,-32.3856506,-59.5289459
|
161
|
+
3436,Victoria,E,,-32.6220245,-60.1570702
|
162
|
+
3437,La Paz,E,,-30.7589703,-59.63927839999999
|
163
|
+
3438,Bovril,E,,-31.3434707,-59.4465431
|
164
|
+
3442,Concepción del Uruguay,E,,-32.4838219,-58.23302839999999
|
165
|
+
3444,Gualeguay,E,,-33.1512413,-59.3344116
|
166
|
+
3445,Rosario del Tala,E,,-32.3026733,-59.14167789999999
|
167
|
+
3446,Gualeguaychú,E,,-33.0150185,-58.5192451
|
168
|
+
3447,Villa Elisa,E,,-32.1641185,-58.40059899999999
|
169
|
+
345,Concordia,E,,-31.3918479,-58.0170605
|
170
|
+
3454,Federal,E,,-30.9512291,-58.7988281
|
171
|
+
3455,Villaguay,E,,-31.849369,-59.01580809999999
|
172
|
+
3456,Chajarí,E,,-30.7572746,-57.99161909999999
|
173
|
+
3458,San José de Feliciano,E,,-30.3826904,-58.7493896
|
174
|
+
3460,Sargento Cabral,S,,-33.4308929,-60.6272621
|
175
|
+
3461,Campos Salles,B,,-33.4036369,-60.23913570000001
|
176
|
+
3462,Venado Tuerto,S,,-33.75,-61.96564100000001
|
177
|
+
3463,Canals,X,,-33.5619736,-62.8815918
|
178
|
+
3464,Casilda,S,,-33.0496216,-61.1663818
|
179
|
+
3465,Firmat,S,,-33.4555244,-61.48825069999999
|
180
|
+
3466,Arocena,S,,-32.0777283,-60.9751549
|
181
|
+
3467,Cruz Alta,X,,-33.008709,-61.8109207
|
182
|
+
3468,Corral de Bustos,X,,-33.2835312,-62.1854591
|
183
|
+
3469,Acebal,S,,-33.2412796,-60.83404160000001
|
184
|
+
3471,Cañada de Gómez,S,,-32.8161583,-61.3998413
|
185
|
+
3472,Marcos Juárez,X,,-32.6936073,-62.10267640000001
|
186
|
+
3476,Totoras,S,,-32.5857964,-61.1678085
|
187
|
+
3482,Reconquista,S,,-29.1448193,-59.64352419999999
|
188
|
+
3483,Vera,S,,-29.4653301,-60.2160606
|
189
|
+
3487,Zárate,B,,-34.0988083,-59.0322914
|
190
|
+
3488,Dique Luján,B,,-34.3717288,-58.6880906
|
191
|
+
3489,Campana,B,,-34.1674805,-58.95264049999999
|
192
|
+
3491,Tostado,S,,-29.2327906,-61.77137080000001
|
193
|
+
3492,Rafaela,S,,-31.2525979,-61.49164219999999
|
194
|
+
3493,Sunchales,S,,-30.9429569,-61.5598907
|
195
|
+
3496,Esperanza,S,,-31.4489859,-60.93036629999999
|
196
|
+
3497,Cayastacito,S,,-31.1000004,-60.5666618
|
197
|
+
3498,San Justo,S,,-30.7894382,-60.59102249999999
|
198
|
+
351,Córdoba,X,,-31.3989296,-64.1821289
|
199
|
+
3521,Deán Funes,X,,-30.42249679999999,-64.3527756
|
200
|
+
3522,San Francisco del Chañar,X,,-29.7839394,-63.9321899
|
201
|
+
3524,Villa del Totoral,X,,-30.816667,-63.71666699999999
|
202
|
+
3525,Jesús María,X,,-30.97630969999999,-64.09581279999999
|
203
|
+
353,Villa María,X,,-32.4104614,-63.24364499999999
|
204
|
+
3532,Oliva,X,,-32.0412292,-63.5676689
|
205
|
+
3533,Las Varillas,X,,-31.87050079999999,-62.7197901
|
206
|
+
3534,Bell Ville,X,,-32.6201134,-62.68926239999999
|
207
|
+
3541,Villa Carlos Paz,X,,-31.4209385,-64.5001297
|
208
|
+
3542,Salsacate,X,,-31.3179455,-65.0883789
|
209
|
+
3543,La Calera,X,,-31.396629,-64.45997600000001
|
210
|
+
3544,Villa Dolores,X,,-31.944437,-65.19210819999999
|
211
|
+
3546,Santa Rosa de Calamuchita,X,,-32.0677338,-64.5497437
|
212
|
+
3547,Alta Gracia,X,,-31.65455249999999,-64.43060299999999
|
213
|
+
3548,La Falda,X,,-31.0875359,-64.4837265
|
214
|
+
3549,Cruz del Eje,X,,-30.7211227,-64.8098984
|
215
|
+
3562,Morteros,X,,-30.7099133,-62.00429149999999
|
216
|
+
3563,Balnearia,X,,-31.0128017,-62.66572489999999
|
217
|
+
3564,San Francisco,X,,-31.42499919999999,-62.0841599
|
218
|
+
3571,Río Tercero,X,,-32.1753998,-64.1122055
|
219
|
+
3572,Río Segundo,X,,-31.65180209999999,-63.9123955
|
220
|
+
3573,Calchín,X,,-31.668045,-63.19916920000001
|
221
|
+
3574,Santa Rosa de Río Primero,X,,-31.1512527,-63.4034538
|
222
|
+
3575,La Para,X,,-30.8919945,-62.99832149999999
|
223
|
+
3576,Arroyito,X,,-31.4154091,-63.0505409
|
224
|
+
358,Río Cuarto,X,,-33.132019,-64.3496704
|
225
|
+
3582,Coronel Moldes,X,,-33.6346397,-64.59960939999999
|
226
|
+
3583,Vicuña Mackenna,X,,-33.9179611,-64.3894806
|
227
|
+
3584,La Carlota,X,,-33.4203339,-63.2935677
|
228
|
+
3585,Adelia María,X,,-33.6373901,-64.0310669
|
229
|
+
3711,Ingeniero Guillermo N. Juárez,P,,-23.8945923,-61.85535050000001
|
230
|
+
3715,Las Lomitas,P,,-24.7045002,-60.6005783
|
231
|
+
3716,Ibarreta,P,,-25.2150536,-59.8573494
|
232
|
+
3717,Formosa,P,,-26.185201,-58.1753697
|
233
|
+
3718,Clorinda,P,,-25.2881832,-57.7228203
|
234
|
+
3721,Charadai,H,,-27.6559811,-59.8599968
|
235
|
+
3722,Resistencia,H,,-27.451656,-58.98625199999999
|
236
|
+
3725,General José de San Martín,H,,-26.53898,-59.34269
|
237
|
+
3731,Charata,H,,-27.2179902,-61.18736169999999
|
238
|
+
3732,Presidencia Roque Sáenz Peña,H,,-26.7906895,-60.4402504
|
239
|
+
3734,Machagai,H,,-26.9329796,-60.0512695
|
240
|
+
3735,Villa Ángela,H,,-27.5758266,-60.7136879
|
241
|
+
3741,Bernardo de Irigoyen,N,,-26.25,-53.65000149999999
|
242
|
+
3743,Jardín América,N,,-27.0431973,-55.2270686
|
243
|
+
3751,San Pedro,N,,-26.6308594,-54.1131592
|
244
|
+
3754,Dos Arroyos,N,,-27.700201,-55.24606319999999
|
245
|
+
3755,Oberá,N,,-27.4815311,-55.1234932
|
246
|
+
3756,Santo Tomé,W,,-28.5516205,-56.0456352
|
247
|
+
3757,Puerto Iguazú,N,,-25.5971635,-54.578599
|
248
|
+
3758,Concepción de la Sierra,N,,-27.9806169,-55.52174849999999
|
249
|
+
376,Posadas,N,,-27.3621374,-55.90087459999999
|
250
|
+
3772,Paso de los Libres,W,,-29.7137101,-57.0855601
|
251
|
+
3773,Mercedes,W,,-29.1826935,-58.0789719
|
252
|
+
3774,Curuzú Cuatiá,W,,-29.7915416,-58.0499307
|
253
|
+
3775,Monte Caseros,W,,-30.2494283,-57.62968739999999
|
254
|
+
3777,Goya,W,,-29.1442242,-59.2643242
|
255
|
+
3781,San Miguel,W,,-27.9932613,-57.588829
|
256
|
+
3782,San Lorenzo,W,,-28.1302185,-58.766201
|
257
|
+
3783,Corrientes,W,,-27.4712257,-58.83958440000001
|
258
|
+
3786,Ituzaingó,W,,-27.5899088,-56.68927009999999
|
259
|
+
381,San Miguel de Tucumán,T,,-26.8082848,-65.2175903
|
260
|
+
3821,Chepes,F,,-31.3363895,-66.5918427
|
261
|
+
3822,La Rioja,F,,-29.4128001,-66.8559803
|
262
|
+
3825,Chilecito,F,,-29.1659603,-67.5
|
263
|
+
3826,Chamical,F,,-30.36156459999999,-66.31504819999999
|
264
|
+
3827,Aimogasta,F,,-28.5549145,-66.81731409999999
|
265
|
+
3832,Recreo,K,,-29.2792282,-65.06365199999999
|
266
|
+
3833,Huillapima,K,,-28.7320004,-65.9838867
|
267
|
+
3835,Andalgalá,K,,-27.6004009,-66.3162308
|
268
|
+
3837,Tinogasta,K,,-28.0673199,-67.565918
|
269
|
+
3838,El Cajón,K,,-26.4333305,-66.2666702
|
270
|
+
3841,Pampa de los Guanacos,G,,-26.2302074,-61.8373413
|
271
|
+
3843,Quimilí,G,,-27.6441841,-62.41556549999999
|
272
|
+
3844,Añatuya,G,,-28.46558,-62.83356089999999
|
273
|
+
3845,Villa Atamisqui,G,,-28.4820595,-63.8003502
|
274
|
+
3846,Campo Gallo,G,,-26.5841694,-62.85004039999999
|
275
|
+
385,Santiago del Estero,G,,-27.78442,-64.26728059999999
|
276
|
+
3854,Ancaján,G,,-28.4333305,-64.933342
|
277
|
+
3855,Suncho Corral,G,,-27.9333344,-63.4300537
|
278
|
+
3856,Sumampa,G,,-29.3664608,-63.4680214
|
279
|
+
3857,Los Juríes,G,,-28.465704,-62.1094246
|
280
|
+
3858,Termas de Río Hondo,G,,-27.4942493,-64.8577881
|
281
|
+
3861,Bobadal,G,,-26.7166691,-64.3833313
|
282
|
+
3862,Trancas,T,,-26.2161293,-65.2835083
|
283
|
+
3863,Famaillá,T,,-27.0560551,-65.40216830000001
|
284
|
+
3865,Aguilares,T,,-27.4328594,-65.61586
|
285
|
+
3867,Tafí del Valle,T,,-26.8458195,-65.700119
|
286
|
+
3868,Cafayate,A,,-26.0703259,-65.9787521
|
287
|
+
3869,Palá Palá,T,,-27.0666695,-65.2166672
|
288
|
+
387,Salta,A,,-24.7829323,-65.4121552
|
289
|
+
3873,Tartagal,A,,-22.5203762,-63.79910659999999
|
290
|
+
3876,El Galpón,A,,-25.3839092,-64.6325684
|
291
|
+
3877,Joaquín V. González,A,,-25.1135731,-64.1268692
|
292
|
+
3878,Embarcación,A,,-23.2110825,-64.0974197
|
293
|
+
388,San Salvador de Jujuy,Y,,-24.1857864,-65.2994767
|
294
|
+
3885,La Quiaca,Y,,-22.1044031,-65.5967709
|
295
|
+
3886,Libertador General San Martín,Y,,-23.81945,-64.790077
|
296
|
+
3887,Humahuaca,Y,,-23.203963,-65.34860929999999
|
297
|
+
3888,San Pedro,Y,,-24.2316571,-64.8678707
|
298
|
+
3891,Graneros,T,,-27.6498394,-65.4400711
|
299
|
+
3892,Amaichá del Valle,T,,-26.5863342,-65.9180298
|
300
|
+
3894,Burruyacú,T,,-26.5937716,-64.811084
|
301
|
+
600,,,premium rate,,
|
302
|
+
605,,,premium rate for charity donation,,
|
303
|
+
609,,,fixed-rate gaming,,
|
304
|
+
610,,,dial-up internet access,,
|
305
|
+
800,,,toll free,,
|
306
|
+
810,,,local rate,,
|
307
|
+
822,,,toll free calling card,,
|
data/lib/nt54/parser.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require "nt54/parser/machinery"
|
2
|
+
require "nt54/parser/visitor"
|
3
|
+
|
4
|
+
module NT54
|
5
|
+
|
6
|
+
class Parser
|
7
|
+
include Machinery
|
8
|
+
|
9
|
+
attr_reader :number
|
10
|
+
|
11
|
+
trigger :country_code_indicated
|
12
|
+
transition :Dialtone, :WaitForCountryCodeStart
|
13
|
+
|
14
|
+
trigger :mobile_prefix_or_area_code_started
|
15
|
+
transition :Dialtone, :WaitForAreaCodeOrMobilePrefixCompletion
|
16
|
+
|
17
|
+
trigger :country_code_started
|
18
|
+
transition :WaitForCountryCodeStart, :WaitForCountryCodeEnd
|
19
|
+
|
20
|
+
trigger :area_code_indicated
|
21
|
+
transition :Dialtone, :WaitForAreaCode
|
22
|
+
|
23
|
+
trigger :country_code_completed
|
24
|
+
transition :WaitForCountryCodeEnd, :WaitForMobilePrefixOrAreaCode
|
25
|
+
|
26
|
+
trigger :mobile_prefix_or_area_code_indicated
|
27
|
+
transition :WaitForMobilePrefixOrAreaCode, :WaitForAreaCodeOrMobilePrefixCompletion
|
28
|
+
|
29
|
+
trigger :mobile_prefix_started
|
30
|
+
transition :WaitForPrefix, :WaitForMobilePrefixCompletion
|
31
|
+
transition :WaitForMobilePrefixOrAreaCode, :WaitForAreaCode
|
32
|
+
transition :WaitForAreaCodeCompletion, :WaitForMobilePrefixCompletion
|
33
|
+
transition :Dialtone, :WaitForMobilePrefixCompletion
|
34
|
+
|
35
|
+
trigger :area_code_completed
|
36
|
+
transition :WaitForAreaCodeOrMobilePrefixCompletion, :WaitForLocalPrefix
|
37
|
+
transition :WaitForAreaCodeCompletion, :WaitForPrefix
|
38
|
+
transition :WaitForAreaCode, :WaitForPrefix
|
39
|
+
|
40
|
+
trigger :area_code_potentially_completed
|
41
|
+
transition :WaitForAreaCode, :WaitForAreaCodeCompletion
|
42
|
+
|
43
|
+
trigger :mobile_prefix_completed
|
44
|
+
transition :WaitForAreaCodeOrMobilePrefixCompletion, :WaitForLocalPrefix
|
45
|
+
transition :WaitForMobilePrefixCompletion, :WaitForLocalPrefix
|
46
|
+
|
47
|
+
trigger :local_prefix_started
|
48
|
+
transition :Dialtone, :WaitForLocalPrefix
|
49
|
+
transition :WaitForPrefix, :WaitForLocalPrefix
|
50
|
+
|
51
|
+
trigger :area_code_started
|
52
|
+
transition :WaitForMobilePrefixOrAreaCode, :WaitForAreaCode
|
53
|
+
transition :WaitForPrefix, :WaitForAreaCode
|
54
|
+
|
55
|
+
trigger :local_prefix_completed
|
56
|
+
transition :WaitForLocalPrefix, :WaitForLocalNumber
|
57
|
+
|
58
|
+
trigger :special_number_started
|
59
|
+
transition :Dialtone, :WaitForSpecialNumberCompletion
|
60
|
+
transition :WaitForAreaCodeOrMobilePrefixCompletion, :WaitForSpecialNumberCompletion
|
61
|
+
|
62
|
+
def self.parse(sequence)
|
63
|
+
parser = new
|
64
|
+
sequence = sequence.to_s.gsub(/[^0-9+]/, '')
|
65
|
+
sequence.split("").map {|x| parser.dial(x)}
|
66
|
+
parser.number.fix!
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.debug(sequence)
|
70
|
+
NT54.log = Logger.new(STDOUT)
|
71
|
+
NT54.log.level = Logger::DEBUG
|
72
|
+
pp parse(sequence)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.valid?(sequence)
|
76
|
+
number = parse(sequence)
|
77
|
+
number.valid?
|
78
|
+
rescue RuntimeError
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize
|
83
|
+
@number = PhoneNumber.new
|
84
|
+
@visitor = Parser::Visitors::Dialtone.new(@number)
|
85
|
+
end
|
86
|
+
|
87
|
+
def dial(keypress)
|
88
|
+
respond_to @visitor.accept(keypress)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
|
4
|
+
module Machinery
|
5
|
+
private
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
def machine
|
12
|
+
@machine or begin
|
13
|
+
@machine = MicroMachine.new(:Dialtone).tap do |m|
|
14
|
+
m.instance_variable_set :@transitions_for, self.class.transitions
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to(event)
|
20
|
+
return if event.nil?
|
21
|
+
next_visitor = machine.transitions_for[event][machine.state]
|
22
|
+
send event
|
23
|
+
@visitor = Visitors.const_get(next_visitor).new(@number)
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def trigger(name, &block)
|
28
|
+
triggers << name
|
29
|
+
transitions[name] = {}
|
30
|
+
class_eval(<<-END, __FILE__, __LINE__ + 1)
|
31
|
+
def #{name}
|
32
|
+
NT54.log.debug "triggering #{name}" if NT54.log
|
33
|
+
machine.trigger :#{name}
|
34
|
+
end
|
35
|
+
END
|
36
|
+
end
|
37
|
+
|
38
|
+
def transition(from, to)
|
39
|
+
transitions[triggers.last][from] = to
|
40
|
+
end
|
41
|
+
|
42
|
+
def transitions
|
43
|
+
@transitions ||= {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def triggers
|
47
|
+
@triggers ||= []
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
class Visitor
|
4
|
+
|
5
|
+
attr :number
|
6
|
+
|
7
|
+
def initialize(number)
|
8
|
+
NT54.log.debug "new state: #{to_sym}" if NT54.log
|
9
|
+
@number = number
|
10
|
+
end
|
11
|
+
|
12
|
+
def accept(keypress)
|
13
|
+
NT54.log.debug "got #{keypress}" if NT54.log
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_sym
|
18
|
+
self.class.to_s.split("::").last.to_sym
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "nt54/parser/visitors/dialtone"
|
25
|
+
require "nt54/parser/visitors/wait_for_area_code"
|
26
|
+
require "nt54/parser/visitors/wait_for_area_code_completion"
|
27
|
+
require "nt54/parser/visitors/wait_for_area_code_or_mobile_prefix_completion"
|
28
|
+
require "nt54/parser/visitors/wait_for_country_code_end"
|
29
|
+
require "nt54/parser/visitors/wait_for_country_code_start"
|
30
|
+
require "nt54/parser/visitors/wait_for_local_number"
|
31
|
+
require "nt54/parser/visitors/wait_for_local_prefix"
|
32
|
+
require "nt54/parser/visitors/wait_for_mobile_prefix_completion"
|
33
|
+
require "nt54/parser/visitors/wait_for_mobile_prefix_or_area_code"
|
34
|
+
require "nt54/parser/visitors/wait_for_prefix"
|
35
|
+
require "nt54/parser/visitors/wait_for_special_number_completion"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class Dialtone < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
case keypress
|
8
|
+
when "+"
|
9
|
+
:country_code_indicated
|
10
|
+
when "1"
|
11
|
+
:mobile_prefix_or_area_code_started
|
12
|
+
when "0"
|
13
|
+
:area_code_indicated
|
14
|
+
when ("4".."8")
|
15
|
+
@number.local_prefix << keypress
|
16
|
+
:local_prefix_started
|
17
|
+
when("9")
|
18
|
+
@number.special_sequence << keypress
|
19
|
+
:special_number_started
|
20
|
+
else raise "Don't know how to handle #{keypress}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForAreaCode < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
@number.area_code << keypress
|
8
|
+
if @number.area_code.length == 2 && @number.area
|
9
|
+
:area_code_completed
|
10
|
+
elsif @number.area_code.length > 2
|
11
|
+
:area_code_potentially_completed
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForAreaCodeCompletion < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
# Some area codes overlap, (e.g., 387 and 3873), so we need to check
|
8
|
+
# for a 4-digit area code even if we already have a valid 3-digit one.
|
9
|
+
candidate = @number.area_code + keypress
|
10
|
+
if Area.key? candidate
|
11
|
+
NT54.log.debug "#{candidate} is a valid area code" if NT54.log
|
12
|
+
@number.area_code = candidate
|
13
|
+
:area_code_completed
|
14
|
+
elsif Area.key? @number.area_code
|
15
|
+
NT54.log.debug "#{@number.area_code} is a valid area code" if NT54.log
|
16
|
+
if keypress == "1"
|
17
|
+
@number.mobile = true
|
18
|
+
:mobile_prefix_started
|
19
|
+
else
|
20
|
+
@number.local_prefix << keypress
|
21
|
+
:area_code_completed
|
22
|
+
end
|
23
|
+
else
|
24
|
+
NT54.log.warn("Continuing with invalid or unknown area code") if NT54.log
|
25
|
+
@number.local_prefix << keypress
|
26
|
+
:area_code_completed
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForAreaCodeOrMobilePrefixCompletion < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
if keypress == "1"
|
8
|
+
@number.area_code = "11"
|
9
|
+
:area_code_completed
|
10
|
+
elsif keypress == "5"
|
11
|
+
@number.mobile = true
|
12
|
+
:mobile_prefix_completed
|
13
|
+
elsif keypress == "0" || keypress == "2"
|
14
|
+
@number.special_sequence = "1#{keypress}"
|
15
|
+
:special_number_started
|
16
|
+
else raise "Invalid number #{keypress}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForCountryCodeEnd < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
raise "Expected 4, got #{keypress}" unless keypress.to_s == "4"
|
8
|
+
@number.country_code << keypress
|
9
|
+
:country_code_completed
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForCountryCodeStart < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
raise "Expected 5, got #{keypress}" unless keypress.to_s == "5"
|
8
|
+
@number.country_code << keypress
|
9
|
+
:country_code_started
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForLocalPrefix < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
combo = [@number.area_code.length, @number.local_prefix.length]
|
8
|
+
if combo == [2,4] || combo == [3,3] || combo == [4,2] || combo == [0, 4]
|
9
|
+
@number.local_number << keypress
|
10
|
+
return :local_prefix_completed
|
11
|
+
else
|
12
|
+
@number.local_prefix << keypress
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForMobilePrefixOrAreaCode < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
case keypress.to_s
|
8
|
+
when "1"
|
9
|
+
:mobile_prefix_or_area_code_indicated
|
10
|
+
when "9"
|
11
|
+
@number.mobile = true
|
12
|
+
:mobile_prefix_started
|
13
|
+
else
|
14
|
+
@number.area_code << keypress
|
15
|
+
:area_code_started
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module NT54
|
2
|
+
class Parser
|
3
|
+
module Visitors
|
4
|
+
class WaitForPrefix < Visitor
|
5
|
+
def accept(keypress)
|
6
|
+
super
|
7
|
+
if keypress == "1"
|
8
|
+
@number.mobile = true
|
9
|
+
:mobile_prefix_started
|
10
|
+
else
|
11
|
+
@number.local_prefix << keypress
|
12
|
+
:local_prefix_started
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module NT54
|
2
|
+
class PhoneNumber
|
3
|
+
|
4
|
+
attr_accessor :country_code, :area_code, :local_prefix, :local_number,
|
5
|
+
:city, :province_code, :mobile, :special_sequence, :special
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
[:country_code, :area_code, :local_prefix, :local_number, :special_sequence].each do |var|
|
9
|
+
instance_variable_set :"@#{var}", ""
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def area
|
14
|
+
@area ||= Area.get(area_code)
|
15
|
+
rescue Ambry::NotFoundError
|
16
|
+
end
|
17
|
+
|
18
|
+
def mobile?
|
19
|
+
!! mobile
|
20
|
+
end
|
21
|
+
|
22
|
+
def special
|
23
|
+
@special ||= SpecialNumber.get(special_sequence)
|
24
|
+
rescue Ambry::NotFoundError
|
25
|
+
end
|
26
|
+
|
27
|
+
def special?
|
28
|
+
!! special
|
29
|
+
end
|
30
|
+
|
31
|
+
def format_international
|
32
|
+
"+#{country_code} #{mobile? ? 9 : ''} (#{area_code}) #{local_prefix}-#{local_number}".squeeze(' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
def format_international_sms
|
36
|
+
"+#{country_code} (#{area_code}) #{local_prefix}-#{local_number}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_national
|
40
|
+
"(0#{area_code}) #{mobile? ? 15 : ''} #{local_prefix}-#{local_number}".squeeze(' ')
|
41
|
+
end
|
42
|
+
|
43
|
+
def format_local
|
44
|
+
"#{mobile? ? 15 : ''} #{local_prefix}-#{local_number}".squeeze(' ')
|
45
|
+
end
|
46
|
+
|
47
|
+
def real_length
|
48
|
+
area_code.length + local_prefix.length + local_number.length + special_sequence.length
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid?
|
52
|
+
if special? && real_length == 3
|
53
|
+
return true
|
54
|
+
end
|
55
|
+
return false unless area_code
|
56
|
+
return false unless area
|
57
|
+
return false unless local_prefix.length >= 2
|
58
|
+
return false unless local_number.length >= 3
|
59
|
+
return false unless real_length == 10
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def fix!
|
64
|
+
if real_length == 3 && special_sequence == ""
|
65
|
+
@special_sequence = "#{area_code}#{local_prefix}"
|
66
|
+
@area_code = ""
|
67
|
+
@local_prefix = ""
|
68
|
+
return self
|
69
|
+
end
|
70
|
+
|
71
|
+
@country_code = "54" if @country_code == ""
|
72
|
+
# If we didn't dial an area code, then we don't really know how long the
|
73
|
+
# prefix/local numbers are, so fake it.
|
74
|
+
unless area_code
|
75
|
+
until @local_number.length >= @local_prefix.length
|
76
|
+
@local_number.insert(0, @local_prefix.slice!(-1))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module NT54
|
2
|
+
class Province
|
3
|
+
extend Ambry::Model
|
4
|
+
field :code, :name
|
5
|
+
|
6
|
+
def areas
|
7
|
+
Area.find {|x| x.province_code == code}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
CSV.foreach(Pathname(__FILE__).dirname.join("provinces.csv")) do |row|
|
12
|
+
Province.create Hash[[:code, :name].zip(row)]
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
code,name
|
2
|
+
C,Capital Federal
|
3
|
+
B,Buenos Aires
|
4
|
+
K,Catamarca
|
5
|
+
X,Córdoba
|
6
|
+
W,Corrientes
|
7
|
+
H,Chaco
|
8
|
+
U,Chubut
|
9
|
+
E,Entre Ríos
|
10
|
+
P,Formosa
|
11
|
+
Y,Jujuy
|
12
|
+
L,La Pampa
|
13
|
+
F,La Rioja
|
14
|
+
M,Mendoza
|
15
|
+
N,Misiones
|
16
|
+
Q,Neuquén
|
17
|
+
R,Rio Negro
|
18
|
+
A,Salta
|
19
|
+
J,San Juan
|
20
|
+
D,San Luis
|
21
|
+
Z,Santa Cruz
|
22
|
+
S,Santa Fe
|
23
|
+
G,Santiago del Estero
|
24
|
+
V,Tierra del Fuego
|
25
|
+
T,Tucumán
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module NT54
|
2
|
+
class SpecialNumber
|
3
|
+
extend Ambry::Model
|
4
|
+
field :sequence, :comment, :comment_en
|
5
|
+
end
|
6
|
+
|
7
|
+
CSV.foreach(Pathname(__FILE__).dirname.join("special_numbers.csv")) do |row|
|
8
|
+
SpecialNumber.create Hash[[:sequence, :comment, :comment_en].zip(row)]
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
100,Bomberos,Fire department
|
2
|
+
101,Policía,Police
|
3
|
+
102,Teléfono del niño,Child services
|
4
|
+
103,Defensa civil,Civil defense
|
5
|
+
106,Prefectura Naval,Coast Guard
|
6
|
+
107,Servicio público de emergencias médicas,Ambulance
|
7
|
+
110, Información de guía telefónica,Phone directory
|
8
|
+
112,Atención comercial al cliente de la compañía telefónica,Customer service
|
9
|
+
113,Hora oficial,Official time
|
10
|
+
114,Servicio de reparación de la línea telefónica,Phone repair service
|
11
|
+
115,Prueba de línea,Ring test
|
12
|
+
121,Información del consumo de la línea,Phone usage info
|
13
|
+
125,Asistencia para hipoacúsicos,Assistance service for the hearing-impaired
|
14
|
+
911,Emergencias,Emergency
|
data/lib/nt54/version.rb
ADDED
data/nt54.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path("../lib/nt54/version", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "nt54"
|
5
|
+
s.version = NT54::VERSION
|
6
|
+
s.authors = ["Norman Clarke"]
|
7
|
+
s.email = ["norman@njclarke.com"]
|
8
|
+
s.homepage = "http://github.com/norman/nt54"
|
9
|
+
s.summary = "A library for working with Argentine phone numbers"
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.description = "Provides Argentine phone number parsing, validation, formatting and meta-information."
|
14
|
+
|
15
|
+
s.add_dependency "ambry"
|
16
|
+
s.add_dependency "micromachine"
|
17
|
+
s.add_development_dependency "minitest"
|
18
|
+
end
|
data/test/helper.rb
ADDED
data/test/parser_test.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path("../helper", __FILE__)
|
2
|
+
|
3
|
+
module NT54
|
4
|
+
class ParserTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
parsing_tests = {
|
7
|
+
"+54-11-4781-8888" => ["11", "4781", "8888", false, true],
|
8
|
+
"0-11-4781-8888" => ["11", "4781", "8888", false, true],
|
9
|
+
"11-4781-8888" => ["11", "4781", "8888", false, true],
|
10
|
+
"15-6445-3333" => ["", "6445", "3333", true, false],
|
11
|
+
"0342-15-631-2222" => ["342", "631", "2222", true, true],
|
12
|
+
"0291-453-8888" => ["291", "453", "8888", false, true],
|
13
|
+
"+54-291-453-8888" => ["291", "453", "8888", false, true],
|
14
|
+
"0291-15-453-8888" => ["291", "453", "8888", true, true],
|
15
|
+
"+54-9-291-453-8888" => ["291", "453", "8888", true, true],
|
16
|
+
"0-11-15-4430-3333" => ["11", "4430", "3333", true, true],
|
17
|
+
"0810-444-4444" => ["810", "444", "4444", false, true],
|
18
|
+
"0 (221) 15 123-4567" => ["221", "123", "4567", true, true],
|
19
|
+
"0 (3722) 15 12-3456" => ["3722", "12", "3456", true, true],
|
20
|
+
"0387-431-9999" => ["387", "431", "9999", false, true],
|
21
|
+
"03868-42-6666" => ["3868", "42", "6666", false, true],
|
22
|
+
"0387-154-106666" => ["387", "410", "6666", true, true],
|
23
|
+
"03873-424444" => ["3873", "42", "4444", false, true],
|
24
|
+
"03488-218888" => ["3488", "21", "8888", false, true],
|
25
|
+
"03488-15-218888" => ["3488", "21", "8888", true, true],
|
26
|
+
"02965-422222" => ["296", "542", "2222", false, false],
|
27
|
+
"+54 15-5310-7777" => ["", "5310", "7777", true, false]
|
28
|
+
}
|
29
|
+
|
30
|
+
parsing_tests.each do |given, expected|
|
31
|
+
class_eval(<<-END, __FILE__, __LINE__+1)
|
32
|
+
def test_#{given.gsub(/[^0-9]/, "")}
|
33
|
+
number = Parser.parse("#{given}")
|
34
|
+
assert_equal "#{expected[0]}", number.area_code, "Bad area code"
|
35
|
+
assert_equal "#{expected[1]}", number.local_prefix, "Bad local prefix"
|
36
|
+
assert_equal "#{expected[2]}", number.local_number, "Bad local number"
|
37
|
+
assert_equal #{expected[3]}, number.mobile?, "Bad mobile detection"
|
38
|
+
assert_equal #{expected[4]}, number.valid?, "Bad validity check"
|
39
|
+
end
|
40
|
+
END
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_non_argentine_numbers_should_be_invalid
|
44
|
+
assert !Parser.valid?("+1-206-444-5555")
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_incomplete_numbers_should_be_invalid
|
48
|
+
assert !Parser.valid?("+54")
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_numbers_with_unknown_area_codes_should_be_invalid
|
52
|
+
assert Parser.valid?("03861-22-4444")
|
53
|
+
# There's no "3864" area code
|
54
|
+
assert !Parser.valid?("03864-22-4444")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nt54
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Norman Clarke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ambry
|
16
|
+
requirement: &70264475542380 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70264475542380
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: micromachine
|
27
|
+
requirement: &70264475541700 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70264475541700
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: minitest
|
38
|
+
requirement: &70264475541060 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70264475541060
|
47
|
+
description: Provides Argentine phone number parsing, validation, formatting and meta-information.
|
48
|
+
email:
|
49
|
+
- norman@njclarke.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- lib/nt54.rb
|
58
|
+
- lib/nt54/area.rb
|
59
|
+
- lib/nt54/areas.csv
|
60
|
+
- lib/nt54/parser.rb
|
61
|
+
- lib/nt54/parser/machinery.rb
|
62
|
+
- lib/nt54/parser/visitor.rb
|
63
|
+
- lib/nt54/parser/visitors/dialtone.rb
|
64
|
+
- lib/nt54/parser/visitors/wait_for_area_code.rb
|
65
|
+
- lib/nt54/parser/visitors/wait_for_area_code_completion.rb
|
66
|
+
- lib/nt54/parser/visitors/wait_for_area_code_or_mobile_prefix_completion.rb
|
67
|
+
- lib/nt54/parser/visitors/wait_for_country_code_end.rb
|
68
|
+
- lib/nt54/parser/visitors/wait_for_country_code_start.rb
|
69
|
+
- lib/nt54/parser/visitors/wait_for_local_number.rb
|
70
|
+
- lib/nt54/parser/visitors/wait_for_local_prefix.rb
|
71
|
+
- lib/nt54/parser/visitors/wait_for_mobile_prefix_completion.rb
|
72
|
+
- lib/nt54/parser/visitors/wait_for_mobile_prefix_or_area_code.rb
|
73
|
+
- lib/nt54/parser/visitors/wait_for_prefix.rb
|
74
|
+
- lib/nt54/parser/visitors/wait_for_special_number_completion.rb
|
75
|
+
- lib/nt54/phone_number.rb
|
76
|
+
- lib/nt54/province.rb
|
77
|
+
- lib/nt54/provinces.csv
|
78
|
+
- lib/nt54/special_number.rb
|
79
|
+
- lib/nt54/special_numbers.csv
|
80
|
+
- lib/nt54/version.rb
|
81
|
+
- nt54.gemspec
|
82
|
+
- test/helper.rb
|
83
|
+
- test/parser_test.rb
|
84
|
+
homepage: http://github.com/norman/nt54
|
85
|
+
licenses: []
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.10
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: A library for working with Argentine phone numbers
|
108
|
+
test_files: []
|