big-phoney 0.0.1
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/LICENSE +22 -0
- data/README.md +24 -0
- data/lib/big-phoney.rb +103 -0
- data/lib/big_phoney.rb +1 -0
- data/lib/big_phoney/.gitignore +0 -0
- data/lib/big_phoney/country_codes.rb +29 -0
- data/spec/big_phoney_spec.rb +159 -0
- data/spec/spec_helper.rb +7 -0
- metadata +74 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(c) Copyright 2010 GroupMe, Pat Nakajima, Steve Martocci
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# BIG PHONEY
|
2
|
+
|
3
|
+
Parse phone numbers with Ruby.
|
4
|
+
|
5
|
+
## It's a work in progress...
|
6
|
+
|
7
|
+
But! Here's what you can do:
|
8
|
+
|
9
|
+
|
10
|
+
phone = PhoneNumber.new('20 484-123-1234 x 123')
|
11
|
+
phone.number # => "4844679726"
|
12
|
+
phone.area_code # => "484"
|
13
|
+
phone.extension # => "123"
|
14
|
+
phone.country_code # => "20"
|
15
|
+
phone.to_s # => "+20 (484) 123-1234 ext. 123"
|
16
|
+
|
17
|
+
Also, check validity:
|
18
|
+
|
19
|
+
phone = PhoneNumber.new('12345')
|
20
|
+
phone.valid? # => false
|
21
|
+
phone.errors # => [:too_short]
|
22
|
+
|
23
|
+
The formatting and prefix type splitting stuff is still very US-centric. That will
|
24
|
+
change as the need arises (or as you send me a pull request, you awesome developer you).
|
data/lib/big-phoney.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
MIN_US_LENGTH = 10
|
2
|
+
MINLEN = 7
|
3
|
+
EXT = /\s*(?:(?:ext|ex|xt|x)[\s.:]*(\d+))/i
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
require 'big_phoney/country_codes'
|
8
|
+
|
9
|
+
class PhoneNumber
|
10
|
+
def self.assume_us? ; @assume_us end
|
11
|
+
def self.assume_us=(us) ; @assume_us = us end
|
12
|
+
|
13
|
+
attr_accessor :country_code, :ext, :number
|
14
|
+
|
15
|
+
def initialize(number)
|
16
|
+
@number = number.strip
|
17
|
+
parse_extension
|
18
|
+
parse_country_code
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
result = '(%s) %s-%s' % [area_code, prefix, rest]
|
23
|
+
|
24
|
+
if country_code != '1'
|
25
|
+
result = '+%s %s' % [country_code, result]
|
26
|
+
end
|
27
|
+
|
28
|
+
if extension
|
29
|
+
result = '%s ext. %s' % [result, extension]
|
30
|
+
end
|
31
|
+
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid?
|
36
|
+
errors.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
def area_code
|
40
|
+
number[0..2]
|
41
|
+
end
|
42
|
+
|
43
|
+
def prefix
|
44
|
+
number[3..5]
|
45
|
+
end
|
46
|
+
|
47
|
+
def rest
|
48
|
+
number[6..9]
|
49
|
+
end
|
50
|
+
|
51
|
+
def errors
|
52
|
+
@errors ||= []
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :extension, :ext
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def parse_extension
|
60
|
+
@number =~ EXT
|
61
|
+
if $1 && $1.size > 4
|
62
|
+
errors << :extension
|
63
|
+
else
|
64
|
+
@ext = $1
|
65
|
+
@number.sub!(EXT, '')
|
66
|
+
end
|
67
|
+
|
68
|
+
@number.gsub!(/\D/, '')
|
69
|
+
@number.sub!(/^0+/, '')
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_country_code
|
73
|
+
if @number.size == 10
|
74
|
+
@number = "1#{@number}"
|
75
|
+
end
|
76
|
+
|
77
|
+
if PhoneNumber.assume_us?
|
78
|
+
if $_ && $_ < MIN_US_LENGTH
|
79
|
+
errors << :too_short
|
80
|
+
else
|
81
|
+
@country_code = "1"
|
82
|
+
@number.sub!(/^1/, '')
|
83
|
+
@num = $_
|
84
|
+
end
|
85
|
+
else
|
86
|
+
0.upto(2) do |len|
|
87
|
+
break if @country_code
|
88
|
+
if COUNTRY_CODES.include?(country_code = @number[0..len])
|
89
|
+
@country_code ||= country_code
|
90
|
+
@number.sub!(/^#{country_code}/, '')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if @country_code.nil?
|
95
|
+
errors << :country_code
|
96
|
+
end
|
97
|
+
|
98
|
+
if @country_code && "#{@country_code}#{@number}".size < MINLEN
|
99
|
+
errors << :too_short
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/big_phoney.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'big-phoney'
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class PhoneNumber
|
2
|
+
COUNTRY_CODES = %w[
|
3
|
+
1 7 20 27 30 31 32 33 34
|
4
|
+
36 39 40 41 43 44 45 46 47
|
5
|
+
48 49 51 52 53 54 55 56 57
|
6
|
+
58 60 61 62 63 64 65 66 81
|
7
|
+
82 84 86 90 91 92 93 94 95
|
8
|
+
98 212 213 216 218 220 221 222 223
|
9
|
+
224 225 226 227 228 229 230 231 232
|
10
|
+
233 234 235 236 237 238 239 240 241
|
11
|
+
242 243 244 245 246 247 248 249 250
|
12
|
+
251 252 253 254 255 256 257 258 260
|
13
|
+
261 262 263 264 265 266 267 268 269
|
14
|
+
290 291 297 298 299 350 351 352 353
|
15
|
+
354 355 356 357 358 359 370 371 372
|
16
|
+
373 374 375 376 377 378 380 381 385
|
17
|
+
386 387 388 389 420 421 423 500 501
|
18
|
+
502 503 504 505 506 507 508 509 590
|
19
|
+
591 592 593 594 595 596 597 598 599
|
20
|
+
670 672 673 674 675 676 677 678 679
|
21
|
+
680 681 682 683 684 685 686 687 688
|
22
|
+
689 690 691 692 800 808 850 852 853
|
23
|
+
655 856 870 871 872 873 874 878 880
|
24
|
+
881 882 886 960 961 962 963 964 965
|
25
|
+
966 967 968 970 971 972 973 974 975
|
26
|
+
976 977 979 991 992 993 994 995 996
|
27
|
+
998
|
28
|
+
]
|
29
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe PhoneNumber do
|
4
|
+
describe "validity" do
|
5
|
+
it "is valid with a valid number" do
|
6
|
+
number = PhoneNumber.new('(484) 123-1234')
|
7
|
+
number.should be_valid
|
8
|
+
end
|
9
|
+
|
10
|
+
it "is invalid with wrong country code" do
|
11
|
+
number = PhoneNumber.new('+29 (484) 123-1234')
|
12
|
+
number.should_not be_valid
|
13
|
+
number.errors.should include(:country_code)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "is invalid with extension that is too long" do
|
17
|
+
number = PhoneNumber.new('(484) 123-1234 x2343423432')
|
18
|
+
number.should_not be_valid
|
19
|
+
number.errors.should include(:extension)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is invalid when too short" do
|
23
|
+
number = PhoneNumber.new('423432')
|
24
|
+
number.should_not be_valid
|
25
|
+
number.errors.should include(:too_short)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "stripping other characters" do
|
30
|
+
it "strips parens" do
|
31
|
+
PhoneNumber.new('(484) 123-1234').number.should == '4841231234'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "allows spaces" do
|
35
|
+
PhoneNumber.new('484 123 1234').number.should == '4841231234'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "allows dashes" do
|
39
|
+
PhoneNumber.new('484-123-1234').number.should == '4841231234'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "allows dots" do
|
43
|
+
PhoneNumber.new('484.123.1234').number.should == '4841231234'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "allows plus signs" do
|
47
|
+
PhoneNumber.new('+1 (484) 123-1234').number.should == '4841231234'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "parsing extension" do
|
52
|
+
it "returns nil when there is none" do
|
53
|
+
PhoneNumber.new('4841231234').ext.should be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "when 'ext' (no spaces) is used" do
|
57
|
+
PhoneNumber.new('4841231234ext123').ext.should == '123'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "when ' ext ' (with spaces) is used" do
|
61
|
+
PhoneNumber.new('4841231234 ext 123').ext.should == '123'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "when ' ext. ' (with period) is used" do
|
65
|
+
PhoneNumber.new('4841231234 ext. 123').ext.should == '123'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "when 'ex' (no spaces) is used" do
|
69
|
+
PhoneNumber.new('4841231234ex123').ext.should == '123'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "when ' ex ' (with spaces) is used" do
|
73
|
+
PhoneNumber.new('4841231234 ex 123').ext.should == '123'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "when 'x' (no spaces) is used" do
|
77
|
+
PhoneNumber.new('4841231234x123').ext.should == '123'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "when ' x ' (with spaces) is used" do
|
81
|
+
PhoneNumber.new('4841231234 x 123').ext.should == '123'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "gets removed from number" do
|
85
|
+
PhoneNumber.new('4841231234 x 123').number.should == '4841231234'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "country code" do
|
90
|
+
context "when in US-only mode" do
|
91
|
+
before(:each) do
|
92
|
+
PhoneNumber.assume_us = true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "assumes 1" do
|
96
|
+
phone = PhoneNumber.new('4841231234')
|
97
|
+
phone.country_code.should == '1'
|
98
|
+
phone.number.should == '4841231234'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "also parses country code as 1" do
|
102
|
+
phone = PhoneNumber.new('14841231234')
|
103
|
+
phone.country_code.should == '1'
|
104
|
+
phone.number.should == '4841231234'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when not in US-only mode" do
|
109
|
+
before(:each) do
|
110
|
+
PhoneNumber.assume_us = false
|
111
|
+
end
|
112
|
+
|
113
|
+
it "parses 1 digit country code" do
|
114
|
+
phone = PhoneNumber.new('74841231234')
|
115
|
+
phone.country_code.should == '7'
|
116
|
+
phone.number.should == '4841231234'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "parses 2 digit country code" do
|
120
|
+
phone = PhoneNumber.new('204841231234')
|
121
|
+
phone.country_code.should == '20'
|
122
|
+
phone.number.should == '4841231234'
|
123
|
+
end
|
124
|
+
|
125
|
+
it "parses 3 digit country code" do
|
126
|
+
phone = PhoneNumber.new('9964841231234')
|
127
|
+
phone.country_code.should == '996'
|
128
|
+
phone.number.should == '4841231234'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "parses international type numbers" do
|
132
|
+
phone = PhoneNumber.new('54-11-4444-3333')
|
133
|
+
phone.country_code.should == '54'
|
134
|
+
phone.number.should == '1144443333'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "area_code" do
|
140
|
+
it "takes the first 3 digits of number" do
|
141
|
+
phone = PhoneNumber.new('4841231234')
|
142
|
+
phone.area_code.should == '484'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "formatting" do
|
147
|
+
it "formats with parens by default" do
|
148
|
+
PhoneNumber.new('4841231234').to_s.should == '(484) 123-1234'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "includes country code when not 1" do
|
152
|
+
PhoneNumber.new('544841231234').to_s.should == '+54 (484) 123-1234'
|
153
|
+
end
|
154
|
+
|
155
|
+
it "includes extension" do
|
156
|
+
PhoneNumber.new('4841231234x123').to_s.should == '(484) 123-1234 ext. 123'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: big-phoney
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Pat Nakajima
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-03 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email:
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- LICENSE
|
32
|
+
- README.md
|
33
|
+
- lib/big-phoney.rb
|
34
|
+
- lib/big_phoney.rb
|
35
|
+
- lib/big_phoney/.gitignore
|
36
|
+
- lib/big_phoney/country_codes.rb
|
37
|
+
- spec/big_phoney_spec.rb
|
38
|
+
- spec/spec_helper.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage:
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
hash: 3
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.7
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Simple phone number parsing in Ruby
|
73
|
+
test_files: []
|
74
|
+
|