global_phone_locomote 1.0.2

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 ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Sam Stephenson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # GlobalPhone
2
+
3
+ [![Build Status](https://travis-ci.org/sstephenson/global_phone.png)](https://travis-ci.org/sstephenson/global_phone)
4
+ [![Gem Version](https://badge.fury.io/rb/global_phone.png)](http://badge.fury.io/rb/global_phone)
5
+ [![Dependency Status](https://gemnasium.com/sstephenson/global_phone.png)](https://gemnasium.com/sstephenson/global_phone)
6
+ [![Still Maintained](http://stillmaintained.com/sstephenson/global_phone.png)](http://stillmaintained.com/sstephenson/global_phone)
7
+
8
+ GlobalPhone parses, validates, and formats local and international phone numbers according to the [E.164 standard](http://en.wikipedia.org/wiki/E.164).
9
+
10
+ **Store and display phone numbers in your app.** Accept phone number input in national or international format. Convert phone numbers to international strings (`+13125551212`) for storage and retrieval. Present numbers in national format (`(312) 555-1212`) in your UI.
11
+
12
+ **Designed with the future in mind.** GlobalPhone uses format specifications from Google's open-source [libphonenumber](http://code.google.com/p/libphonenumber/) database. No need to upgrade the library when a new phone format is introduced—just generate a new copy of the database and check it into your app.
13
+
14
+ **Pure Ruby. No dependencies.** GlobalPhone is designed for Ruby 1.9.3 and up. (Works in 1.8.7, too—just bring your own `json` gem.)
15
+
16
+ ## Installation
17
+
18
+ 1. Add the `global_phone` gem to your app. For example, using Bundler:
19
+
20
+ $ echo "gem 'global_phone'" >> Gemfile
21
+ $ bundle install
22
+
23
+ 2. Use `global_phone_dbgen` to convert Google's libphonenumber `PhoneNumberMetaData.xml` file into a JSON database for GlobalPhone.
24
+
25
+ $ gem install global_phone_dbgen
26
+ $ global_phone_dbgen > db/global_phone.json
27
+
28
+ 3. Tell GlobalPhone where to find the database. For example, in a Rails app, create an initializer in `config/initializers/global_phone.rb`:
29
+
30
+ ```ruby
31
+ require 'global_phone'
32
+ GlobalPhone.db_path = Rails.root.join('db/global_phone.json')
33
+ ```
34
+
35
+ ## Examples
36
+
37
+ Parse an international number string into a `GlobalPhone::Number` object:
38
+
39
+ ```ruby
40
+ number = GlobalPhone.parse('+1-312-555-1212')
41
+ # => #<GlobalPhone::Number territory=#<GlobalPhone::Territory country_code=1 name=US> national_string="3125551212">
42
+ ```
43
+
44
+ Query the country code and likely territory name of the number:
45
+
46
+ ```ruby
47
+ number.country_code
48
+ # => "1"
49
+
50
+ number.territory.name
51
+ # => "US"
52
+ ```
53
+
54
+ Present the number in national and international formats:
55
+
56
+ ```ruby
57
+ number.national_format
58
+ # => "(312) 555-1212"
59
+
60
+ number.international_format
61
+ # => "+1 312-555-1212"
62
+ ```
63
+
64
+ Is the number valid? (Note: this is not definitive. For example, the number here is "valid" by format, but there are no US numbers that start with 555. The `valid?` method may return false positives, but *should not* return false negatives unless the database is out of date.)
65
+
66
+ ```ruby
67
+ number.valid?
68
+ # => true
69
+ ```
70
+
71
+ Get the number's normalized E.164 international string:
72
+
73
+ ```ruby
74
+ number.international_string
75
+ # => "+13125551212"
76
+ ```
77
+
78
+ Parse a number in national format for a given territory:
79
+
80
+ ```ruby
81
+ number = GlobalPhone.parse("(0) 20-7031-3000", :gb)
82
+ # => #<GlobalPhone::Number territory=#<GlobalPhone::Territory country_code=44 name=GB> national_string="2070313000">
83
+ ```
84
+
85
+ Parse an international number using a territory's international dialing prefix:
86
+
87
+ ```ruby
88
+ number = GlobalPhone.parse("00 1 3125551212", :gb)
89
+ # => #<GlobalPhone::Number territory=#<GlobalPhone::Territory country_code=1 name=US> national_string="3125551212">
90
+ ```
91
+
92
+ Set the default territory to Great Britain (territory names are [ISO 3166-1 Alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) codes):
93
+
94
+ ```ruby
95
+ GlobalPhone.default_territory_name = :gb
96
+ # => :gb
97
+
98
+ GlobalPhone.parse("(0) 20-7031-3000")
99
+ # => #<GlobalPhone::Number territory=#<GlobalPhone::Territory country_code=44 name=GB> national_string="2070313000">
100
+ ```
101
+
102
+ Shortcuts for validating a phone number:
103
+
104
+ ```ruby
105
+ GlobalPhone.validate("+1 312-555-1212")
106
+ # => true
107
+
108
+ GlobalPhone.validate("+442070313000")
109
+ # => true
110
+
111
+ GlobalPhone.validate("(0) 20-7031-3000")
112
+ # => false
113
+
114
+ GlobalPhone.validate("(0) 20-7031-3000", :gb)
115
+ # => true
116
+ ```
117
+
118
+ Shortcuts for normalizing a phone number in E.164 format:
119
+
120
+ ```ruby
121
+ GlobalPhone.normalize("(312) 555-1212")
122
+ # => "+13125551212"
123
+
124
+ GlobalPhone.normalize("+442070313000")
125
+ # => "+442070313000"
126
+
127
+ GlobalPhone.normalize("(0) 20-7031-3000")
128
+ # => nil
129
+
130
+ GlobalPhone.normalize("(0) 20-7031-3000", :gb)
131
+ # => "+442070313000"
132
+ ```
133
+
134
+ Validate global phone numbers in Rails 3.x and ActiveModel.
135
+
136
+ ```ruby
137
+ class Person < ActiveRecord::Base
138
+ validates :home_phone, :global_phone => true
139
+ end
140
+
141
+ Person.new(home_phone: '+61 3 9876 0010').valid?
142
+ # => true
143
+
144
+ class User < ActiveRecord::Base
145
+ attribute :work_country_code
146
+
147
+ validates :work_phone, :global_phone => { :using => :work_country_code }
148
+ end
149
+
150
+ User.new(work_phone: '03 9876 0010').valid?
151
+ # => true
152
+ ```
153
+
154
+ ## Caveats
155
+
156
+ GlobalPhone currently does not parse emergency numbers or SMS short code numbers.
157
+
158
+ Validation is not definitive and may return false positives, but *should not* return false negatives unless the database is out of date.
159
+
160
+ Territory heuristics are imprecise. Parsing a number will usually result in the territory being set to the primary territory of the region. For example, Canadian numbers will be parsed with a territory of `US`. (In most cases this does not matter, but if your application needs to perform geolocation using phone numbers, GlobalPhone may not be a good fit.)
161
+
162
+ ## Development
163
+
164
+ The GlobalPhone source code is [hosted on GitHub](https://github.com/sstephenson/global_phone). You can check out a copy of the latest code using Git:
165
+
166
+ $ git clone https://github.com/sstephenson/global_phone.git
167
+
168
+ If you've found a bug or have a question, please open an issue on the [issue tracker](https://github.com/sstephenson/global_phone/issues). Or, clone the GlobalPhone repository, write a failing test case, fix the bug, and submit a pull request.
169
+
170
+ GlobalPhone is heavily inspired by Andreas Gal's [PhoneNumber.js](https://github.com/andreasgal/PhoneNumber.js) library.
171
+
172
+ ### Version History
173
+
174
+ **1.0.2** (Unreleased)
175
+
176
+ * Add GlobalPhone ActiveModel Validator
177
+ * GlobalPhone::Number#area_code returns the national area code.
178
+ * GlobalPhone::Number#local_number returns the local number.
179
+ * BUGFIX discard extra whitespace when splitting phone numbers
180
+
181
+ **1.0.1** (May 29, 2013)
182
+
183
+ * GlobalPhone::Number#to_s returns the E.164 international string.
184
+ * Ensure GlobalPhone::Number always returns strings for #national_format, #international_format, and #international_string, regardless of validity.
185
+ * Relax format restrictions to more loosely match available national number patterns.
186
+
187
+ **1.0.0** (May 28, 2013)
188
+
189
+ * Initial public release.
190
+
191
+ ### License
192
+
193
+ Copyright &copy; 2013 Sam Stephenson
194
+
195
+ Released under the MIT license. See [`LICENSE`](LICENSE) for details.
@@ -0,0 +1,36 @@
1
+ require 'global_phone/database'
2
+
3
+ module GlobalPhone
4
+ module Context
5
+ attr_accessor :db_path
6
+
7
+ def db
8
+ @db ||= begin
9
+ raise NoDatabaseError, "set `db_path=' first" unless db_path
10
+ Database.load_file(db_path)
11
+ end
12
+ end
13
+
14
+ def default_territory_name
15
+ @default_territory_name ||= :US
16
+ end
17
+
18
+ def default_territory_name=(territory_name)
19
+ @default_territory_name = territory_name.to_s.intern
20
+ end
21
+
22
+ def parse(string, territory_name = default_territory_name)
23
+ db.parse(string, territory_name)
24
+ end
25
+
26
+ def normalize(string, territory_name = default_territory_name)
27
+ number = parse(string, territory_name)
28
+ number.international_string if number
29
+ end
30
+
31
+ def validate(string, territory_name = default_territory_name)
32
+ number = parse(string, territory_name)
33
+ number && number.valid?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,48 @@
1
+ require 'global_phone/parsing'
2
+ require 'global_phone/region'
3
+
4
+ module GlobalPhone
5
+ class Database
6
+ include Parsing
7
+
8
+ def self.load_file(filename)
9
+ load(File.read(filename))
10
+ end
11
+
12
+ def self.load(json)
13
+ require 'json'
14
+ new(JSON.parse(json))
15
+ end
16
+
17
+ attr_reader :regions
18
+
19
+ def initialize(record_data)
20
+ @regions = record_data.map { |data| Region.new(data) }
21
+ @territories_by_name = {}
22
+ end
23
+
24
+ def region(country_code)
25
+ regions_by_country_code[country_code.to_s]
26
+ end
27
+
28
+ def territory(name)
29
+ name = name.to_s.upcase
30
+ @territories_by_name[name] ||= if region = region_for_territory(name)
31
+ region.territory(name)
32
+ end
33
+ end
34
+
35
+ def inspect
36
+ "#<#{self.class.name}>"
37
+ end
38
+
39
+ protected
40
+ def regions_by_country_code
41
+ @regions_by_country_code ||= Hash[*regions.map { |r| [r.country_code, r] }.flatten]
42
+ end
43
+
44
+ def region_for_territory(name)
45
+ regions.find { |r| r.has_territory?(name) }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ require 'global_phone/record'
2
+
3
+ module GlobalPhone
4
+ class Format < Record
5
+ field 0, :pattern do |p| /^#{p}$/ end
6
+ field 1, :national_format_rule
7
+ field 2, :leading_digits do |d| /^#{d}/ end
8
+ field 3, :national_prefix_formatting_rule
9
+ field 4, :international_format_rule, :fallback => :national_format_rule
10
+
11
+ def match(national_string, match_leading_digits = true)
12
+ return false if match_leading_digits && leading_digits && national_string !~ leading_digits
13
+ national_string =~ pattern
14
+ end
15
+
16
+ def format_replacement_string(type)
17
+ format_rule = send(:"#{type}_format_rule")
18
+ format_rule.to_s.gsub("$", "\\") unless format_rule == "NA"
19
+ end
20
+
21
+ def apply(national_string, type)
22
+ if replacement = format_replacement_string(type)
23
+ national_string.gsub(pattern, replacement)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,114 @@
1
+ require 'forwardable'
2
+
3
+ module GlobalPhone
4
+ class Number
5
+ extend Forwardable
6
+
7
+ E161_MAPPING = Hash[*"a2b2c2d3e3f3g4h4i4j5k5l5m6n6o6p7q7r7s7t8u8v8w9x9y9z9".split("")]
8
+ VALID_ALPHA_CHARS = /[a-zA-Z]/
9
+ LEADING_PLUS_CHARS = /^\++/
10
+ NON_DIALABLE_CHARS = /[^,#+\*\d]/
11
+ SPLIT_FIRST_GROUP = /^(\d+)\W*(.*)$/
12
+
13
+ def self.normalize(string)
14
+ string.to_s.
15
+ gsub(VALID_ALPHA_CHARS) { |c| E161_MAPPING[c.downcase] }.
16
+ gsub(LEADING_PLUS_CHARS, "+").
17
+ gsub(NON_DIALABLE_CHARS, "")
18
+ end
19
+
20
+ attr_reader :territory, :national_string
21
+
22
+ def_delegator :territory, :region
23
+ def_delegator :territory, :country_code
24
+ def_delegator :territory, :national_prefix
25
+ def_delegator :territory, :national_pattern
26
+
27
+ def initialize(territory, national_string)
28
+ @territory = territory
29
+ @national_string = national_string
30
+ end
31
+
32
+ def national_format
33
+ @national_format ||= begin
34
+ if format
35
+ national_string_with_prefix
36
+ else
37
+ national_string
38
+ end
39
+ end
40
+ end
41
+
42
+ def international_string
43
+ @international_string ||= international_format.gsub(NON_DIALABLE_CHARS, "")
44
+ end
45
+
46
+ def international_format
47
+ @international_format ||= begin
48
+ if format && formatted_number = format.apply(national_string, :international)
49
+ "+#{country_code} #{formatted_number}"
50
+ else
51
+ "+#{country_code} #{national_string}"
52
+ end
53
+ end
54
+ end
55
+
56
+ def area_code
57
+ @area_code ||= formatted_national_prefix.gsub(/[^\d]/, '')
58
+ end
59
+
60
+ def local_number
61
+ @local_number ||= national_string_parts[2]
62
+ end
63
+
64
+ def valid?
65
+ !!(format && national_string =~ national_pattern)
66
+ end
67
+
68
+ def inspect
69
+ "#<#{self.class.name} territory=#{territory.inspect} national_string=#{national_string.inspect}>"
70
+ end
71
+
72
+ def to_s
73
+ international_string
74
+ end
75
+
76
+ protected
77
+ def format
78
+ @format ||= find_format_for(national_string)
79
+ end
80
+
81
+ def find_format_for(string)
82
+ region.formats.detect { |format| format.match(string) } ||
83
+ region.formats.detect { |format| format.match(string, false) }
84
+ end
85
+
86
+ def formatted_national_string
87
+ @formatted_national_string ||= format.apply(national_string, :national)
88
+ end
89
+
90
+ def national_string_parts
91
+ @national_string_parts ||= formatted_national_string.match(SPLIT_FIRST_GROUP)
92
+ end
93
+
94
+ def area_code_suffix
95
+ @area_code_suffix ||= national_string_parts[1]
96
+ end
97
+
98
+ def formatted_national_prefix
99
+ @formatted_national_prefix ||= begin
100
+ national_prefix_formatting_rule.gsub("$NP", national_prefix).gsub("$FG", area_code_suffix)
101
+ end
102
+ end
103
+
104
+ def national_string_with_prefix
105
+ @national_string_with_prefix ||= national_prefix_formatting_rule && national_string_parts ?
106
+ "#{formatted_national_prefix} #{local_number}" : formatted_national_string
107
+ end
108
+
109
+ def national_prefix_formatting_rule
110
+ @national_prefix_formatting_rule ||=
111
+ format.national_prefix_formatting_rule || territory.national_prefix_formatting_rule
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,52 @@
1
+ require 'global_phone/number'
2
+ require 'global_phone/utils'
3
+
4
+ module GlobalPhone
5
+ module Parsing
6
+ def parse(string, territory_name)
7
+ string = Number.normalize(string)
8
+ territory = self.territory(territory_name)
9
+ raise ArgumentError, "unknown territory `#{territory_name}'" unless territory
10
+
11
+ if starts_with_plus?(string)
12
+ parse_international_string(string)
13
+ elsif string =~ territory.international_prefix
14
+ string = strip_international_prefix(territory, string)
15
+ parse_international_string(string)
16
+ else
17
+ territory.parse_national_string(string)
18
+ end
19
+ end
20
+
21
+ def parse_international_string(string)
22
+ string = Number.normalize(string)
23
+ string = strip_leading_plus(string) if starts_with_plus?(string)
24
+
25
+ if region = region_for_string(string)
26
+ region.parse_national_string(string)
27
+ end
28
+ end
29
+
30
+ protected
31
+ def starts_with_plus?(string)
32
+ string[0, 1] == "+"
33
+ end
34
+
35
+ def strip_leading_plus(string)
36
+ string[1..-1]
37
+ end
38
+
39
+ def strip_international_prefix(territory, string)
40
+ string.sub(territory.international_prefix, "")
41
+ end
42
+
43
+ def region_for_string(string)
44
+ candidates = country_code_candidates_for(string)
45
+ Utils.map_detect(candidates) { |country_code| region(country_code) }
46
+ end
47
+
48
+ def country_code_candidates_for(string)
49
+ (1..3).map { |length| string[0, length] }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,26 @@
1
+ require 'forwardable'
2
+
3
+ module GlobalPhone
4
+ class Record
5
+ extend Forwardable
6
+
7
+ def self.field(index, name, options = {}, &block)
8
+ if block
9
+ transform_method_name = :"transform_field_#{name}"
10
+ define_method(transform_method_name, block)
11
+ end
12
+
13
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
+ def #{name}
15
+ value = @data[#{index.inspect}]
16
+ #{"value = #{transform_method_name}(value) if value" if block}
17
+ value #{"|| #{options[:fallback]}" if options[:fallback]}
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ def initialize(data)
23
+ @data = data
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,62 @@
1
+ require 'global_phone/format'
2
+ require 'global_phone/record'
3
+ require 'global_phone/territory'
4
+ require 'global_phone/utils'
5
+
6
+ module GlobalPhone
7
+ class Region < Record
8
+ field 0, :country_code
9
+ field 1, :format_record_data
10
+ field 2, :territory_record_data
11
+ field 3, :international_prefix do |p| /^(?:#{p})/ end
12
+ field 4, :national_prefix
13
+ field 5, :national_prefix_for_parsing do |p| /^(?:#{p})/ end
14
+ field 6, :national_prefix_transform_rule
15
+
16
+ def formats
17
+ @formats ||= format_record_data.map { |data| Format.new(data) }
18
+ end
19
+
20
+ def territories
21
+ @territories ||= territory_record_data.map { |data| Territory.new(data, self) }
22
+ end
23
+
24
+ def territory(name)
25
+ name = name.to_s.upcase
26
+ territories.detect { |region| region.name == name }
27
+ end
28
+
29
+ def has_territory?(name)
30
+ territory_names.include?(name.to_s.upcase)
31
+ end
32
+
33
+ def parse_national_string(string)
34
+ string = Number.normalize(string)
35
+ if starts_with_country_code?(string)
36
+ string = strip_country_code(string)
37
+ find_first_parsed_national_string_from_territories(string)
38
+ end
39
+ end
40
+
41
+ def inspect
42
+ "#<#{self.class.name} country_code=#{country_code} territories=[#{territory_names.join(",")}]>"
43
+ end
44
+
45
+ protected
46
+ def territory_names
47
+ territory_record_data.map(&:first)
48
+ end
49
+
50
+ def starts_with_country_code?(string)
51
+ string.index(country_code) == 0
52
+ end
53
+
54
+ def strip_country_code(string)
55
+ string[country_code.length..-1]
56
+ end
57
+
58
+ def find_first_parsed_national_string_from_territories(string)
59
+ Utils.map_detect(territories) { |territory| territory.parse_national_string(string) }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ require 'global_phone/number'
2
+ require 'global_phone/record'
3
+
4
+ module GlobalPhone
5
+ class Territory < Record
6
+ field 0, :name
7
+ field 1, :possible_pattern do |p| /^#{p}$/ end
8
+ field 2, :national_pattern do |p| /^#{p}$/ end
9
+ field 3, :national_prefix_formatting_rule
10
+
11
+ attr_reader :region
12
+
13
+ def_delegator :region, :country_code
14
+ def_delegator :region, :international_prefix
15
+ def_delegator :region, :national_prefix
16
+ def_delegator :region, :national_prefix_for_parsing
17
+ def_delegator :region, :national_prefix_transform_rule
18
+
19
+ def initialize(data, region)
20
+ super(data)
21
+ @region = region
22
+ end
23
+
24
+ def parse_national_string(string)
25
+ string = normalize(string)
26
+ Number.new(self, string) if possible?(string)
27
+ end
28
+
29
+ def inspect
30
+ "#<#{self.class.name} country_code=#{country_code} name=#{name}>"
31
+ end
32
+
33
+ protected
34
+ def strip_national_prefix(string)
35
+ if national_prefix_for_parsing
36
+ transform_rule = national_prefix_transform_rule || ""
37
+ transform_rule = transform_rule.gsub("$", "\\")
38
+ string_without_prefix = string.sub(national_prefix_for_parsing, transform_rule)
39
+ elsif starts_with_national_prefix?(string)
40
+ string_without_prefix = string[national_prefix.length..-1]
41
+ end
42
+
43
+ possible?(string_without_prefix) ? string_without_prefix : string
44
+ end
45
+
46
+ def normalize(string)
47
+ strip_national_prefix(Number.normalize(string))
48
+ end
49
+
50
+ def possible?(string)
51
+ string =~ possible_pattern
52
+ end
53
+
54
+ def starts_with_national_prefix?(string)
55
+ national_prefix && string.index(national_prefix) == 0
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ module GlobalPhone
2
+ module Utils
3
+ extend self
4
+
5
+ def map_detect(collection)
6
+ collection.each do |value|
7
+ if result = yield(value)
8
+ return result
9
+ end
10
+ end
11
+ nil
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ I18n.load_path << File.dirname(__FILE__) + '/locale/phone_number_validator.en.yml'
2
+
3
+ class GlobalPhoneValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ args = [value]
6
+ if (using = options[:using]) && (country_code = record.send(using))
7
+ args << country_code
8
+ end
9
+ unless GlobalPhone.validate(*args)
10
+ record.errors.add attribute, :invalid_phone_number, country_code: country_code
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'global_phone/context'
2
+
3
+ module GlobalPhone
4
+ VERSION = '1.0.2'
5
+
6
+ class Error < ::StandardError; end
7
+ class NoDatabaseError < Error; end
8
+
9
+ extend Context
10
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: global_phone_locomote
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Loco Chris
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-11 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This is a fork of the wonderful sstepenson/global_phone it only exists
15
+ because our company has a runtime dependency on this gem as part of a private gem
16
+ that we use in a rails app. And the gemspec for our private gem can't reference
17
+ a github branch. Hopefully we can delete this if our PRs get merged (ie. sstephenson/global_phone/pull/6
18
+ , sstephenson/global_phone/pull/7 , sstephenson/global_phone/pull/8 , sstephenson/global_phone/pull/9,
19
+ sstephenson/global_phone/pull/10) and we can go back to depending on global_phone
20
+ email:
21
+ - locochris@locomote.com.au
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - README.md
27
+ - LICENSE
28
+ - lib/global_phone/context.rb
29
+ - lib/global_phone/database.rb
30
+ - lib/global_phone/format.rb
31
+ - lib/global_phone/number.rb
32
+ - lib/global_phone/parsing.rb
33
+ - lib/global_phone/record.rb
34
+ - lib/global_phone/region.rb
35
+ - lib/global_phone/territory.rb
36
+ - lib/global_phone/utils.rb
37
+ - lib/global_phone/validator.rb
38
+ - lib/global_phone.rb
39
+ homepage: https://github.com/locochris/global_phone
40
+ licenses:
41
+ - MIT
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ segments:
53
+ - 0
54
+ hash: 4030134707792318067
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ segments:
62
+ - 0
63
+ hash: 4030134707792318067
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.24
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Locomote fork of global_phone (NB. don't use)
70
+ test_files: []