Class: PhoneSystem::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/gts/utils/phone_system.rb

Constant Summary collapse

@@phone_codes_file_path =
File.join(File.dirname(__FILE__), "phone_codes.yml")
@@phone_codes =
YAML.load(File.read(@@phone_codes_file_path))

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.parse(pstring, options = {}) ⇒ Object

area/operator codes found in phone_codes.yml. If none of the area/operator code matches pstring, exception is raised. Use only if you have complete

list of the area/operator codes for given country. Defaults to false.


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/gts/utils/phone_system.rb', line 52

def self.parse(pstring, options = {})
  
  options = {
    :country_code => 421, # Slovakia
    :strict => false
  }.merge(options)

  text_number = pstring
  # if it starts with "+" or "00" then the country code should be given and we will
  # try to get it.
  if pstring =~ /^(\+|00)/
    cc_match = pstring.match(/^(?:\+|00)(\d*)[ -\(]+/)
    unless  cc_match
    then    raise(CannotParsePhoneNumberString, "The string \"#{text_number}\" does not seem to be valid international phone number."); end
    pstring             = pstring.match(/^[\+0\d]*[ -\(]+(.*)$/)[1] # chop the country code off 
    country_code        = cc_match[1].to_i
  else
    # if the country code is not set, fall to default
    # and chop the first zero, so the area/operator code will be at the first place
    unless  options[:country_code]
    then    raise(CannotDetermineCountryCode, "The string \"#{text_number}\" does not seem to be valid phone number. Cannot determine country code."); end
    pstring       = pstring.sub("0","") # remove the leading zero, to get the area code to the first place
    country_code  = options[:country_code]
  end
  
  # do some cleaning - remove all the remaining characters, that are not digits
  pstring = remove_other_than_digits(pstring)
  
  area_code   = nil
  area_name   = nil
  
  # let's try to identify the country, area/operator and get the correct format for the country
  # if possible
  if @@phone_codes.include? country_code
    country     = @@phone_codes[country_code]["country"]
    area_codes  = @@phone_codes[country_code]["area_codes"]
    pn_format   = Regexp.new(@@phone_codes[country_code]["format"]) if @@phone_codes[country_code].include? "format"
    area_codes.each do |code, name|
      if pstring =~ /^#{code}/
        area_code = code
        area_name = name
        pstring   = pstring.sub(/#{code}/, "") # chop the area code off
        break
      end
    end
    # if not area code found and in strict mode, raise exception
    if    !area_code && options[:strict]
    then  raise(AreaCodeNotValidForGivenCountry, "The string \"#{text_number}\" does not seem to be valid phone number. Area code was not recognized."); end

    # set the number size boundaries if found for given country
    min_size  = @@phone_codes[country_code].include?("min_size") ? @@phone_codes[country_code]["min_size"] : nil
    max_size  = @@phone_codes[country_code].include?("max_size") ? @@phone_codes[country_code]["max_size"] : nil
  end
    
  # if not specific format of numbers for given country set, then 
  # use general format
  pn_format           ||= /^(\+|0)[\d\s\(\)-\/]+$/
  unless text_number  =~  pn_format
  then   raise(CannotParsePhoneNumberString, "The string \"#{text_number}\" does not seem to be valid international phone number."); end
    
  # if no size boundaries set, set them to reasonable defaults
  min_size  ||= 6
  max_size  ||= 15
  # and check the remaining number against them
  if  pstring.size < min_size
  then raise(NumberTooShort, "Cannot parse the string \"#{text_number}\" to phone number. The phone number would be too short."); end
  if  pstring.size > max_size
  then raise(NumberTooLong, "Cannot parse the string \"#{text_number}\" to phone number. The phone number would be too long."); end

  # if we made it here, we have the line number
  number = pstring
  
  out = {
    :text         => text_number,
    :country_code => country_code,
    :country      => country,
    :area_code    => area_code,
    :area_name    => area_name,
    :number       => number
  }
  return out
rescue PhoneSystemError
  false
end

Instance Method Details

#parse(pstring, options) ⇒ Object



23
24
25
# File 'lib/gts/utils/phone_system.rb', line 23

def parse(pstring, options)
  self.class.parse(pstring, options)
end