clli 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.
@@ -0,0 +1,71 @@
1
+ ---
2
+ switching_types:
3
+ MGx: 'End Office Complete Switching System: Crossbar'
4
+ SGx: 'End Office Complete Switching System: Step-By-Step'
5
+ CGx: 'End Office Complete Switching System: Electonic-Analog'
6
+ DSx: 'End Office Complete Switching System: Electonic-Digital'
7
+ nnx: 'End Office: Single or Multiple Entity'
8
+ nnT: 'Tandem Office: Individual Tandem'
9
+ CnT: 'Tandem Office Combination: Tandem/Tandem'
10
+ BnT: 'Tandem Office Combination: Tandem/Switchboard'
11
+ nGT: 'Tandem Office Combination: Tandem/Marker or Control Group'
12
+ ZaZ: 'Common Control Switching Arrangement'
13
+ RSn: 'Remote Switching System'
14
+ XaX: 'Teletypewriter Switching System'
15
+ CTx: 'Concentrator'
16
+
17
+ switchboard_and_desk:
18
+ C: 'Centralized Automatic Message Accounting (CAMA) Board'
19
+ D: 'Dial Service Assistance (DSA) Board'
20
+ B: 'Combined Toll, Dial Service Assistance (DSA), and Centralized Automatic Message Accounting (CAMA)'
21
+ I: 'Directory Assistance (Information)'
22
+ N: 'Intercept Board'
23
+ Q: 'Combined Directory Assistance and Intercept'
24
+ W: 'Inward Toll Board'
25
+ M: 'Manual Switchboard'
26
+ V: 'Overseas Toll Board'
27
+ R: 'Rate and Route Desk'
28
+ O: 'Service Observing Switchboard (Service Evaluation Center and Signal Converter Allotter Used for the Service Evaluation System)'
29
+ L: 'Special Boards (Conference, Mobile, Marine, Switchboard Converted to Special Operation Service Traffic (SOST))'
30
+ '0': 'Teleconference Board'
31
+ '1': 'Teleconference Board'
32
+ '2': 'Teleconference Board'
33
+ '3': 'Teleconference Board'
34
+ '4': 'Teleconference Board'
35
+ '5': 'Teleconference Board'
36
+ '6': 'Teleconference Board'
37
+ '7': 'Teleconference Board'
38
+ '8': 'Teleconference Board'
39
+ '9': 'Teleconference Board'
40
+ P: 'Telephone Company PBX (Offical)'
41
+ E: 'Traffic Service Position System (TSPS) Board'
42
+ U: 'Traffic Service Position (Universal TSP)'
43
+ T: 'Toll Board (Through, Outward)'
44
+ Z: 'Other Switchboard and Desk Entity'
45
+
46
+ miscellaneous_switching_termination:
47
+ A: 'Announcement Machine (including Voice Storage System (VSS), Public Announcement System (PA), Mass Announcement Systems (MAS), Audio Response Units)'
48
+ X: 'Centrex (Central Office)'
49
+ C: 'Automatic Distributor'
50
+ T: 'Time Distributor'
51
+ W: 'Weather Distributor'
52
+ D: 'Other Distributor'
53
+ E: 'Emergency (911 Service)'
54
+ I: 'Automatic Intercept System: File Access System (FAS)'
55
+ N: 'Combined Operator, Trouble, and Machine Intercept'
56
+ P: 'Position Link Frame'
57
+ Q: 'Rate and Quote System'
58
+ U: 'TSPS Common Control Unit (Remote Trunking Arrangement)'
59
+ M: 'Other Switching Termination Entities (including Improved Mobile Telephone System (IMTS) and all other mobile control terminals Bellboy Control terminal Coin to Collect Verification Circuit Switchers at Other Common Carrier Locations)'
60
+
61
+ nonswitching_types:
62
+ F: 'Frame (all types)'
63
+ A: 'Administrative Entity'
64
+ E: 'Exchange Switchroom'
65
+ K: 'Software Cross-connectable Entity'
66
+ M: 'Maintenance Group (including work centers, such as Switching Control Centers, and Operations Systems such as CAROT, CMS, CTMS)'
67
+ P: 'Test or Service Position'
68
+ Q: 'Radio Tower (collocated on building)'
69
+ S: 'Service Center'
70
+ T: 'Toll Test Room (or Board)'
71
+ W: 'Other Nonswitching Entity'
@@ -0,0 +1,37 @@
1
+ ---
2
+ A: 'Bell Operating Company Nonbuilding Location'
3
+ B: 'International Boundary Crossing Point'
4
+ C: 'Bell Operating Company Nonbuilding Location'
5
+ D: 'Bell Operating Company Nonbuilding Location'
6
+ E: 'End Point'
7
+ F: 'Bell Operating Company Nonbuilding Location'
8
+ G: 'Bell Operating Company Nonbuilding Location'
9
+ H: 'Bell Operating Company Nonbuilding Location'
10
+ I: 'Bell Operating Company Nonbuilding Location'
11
+ J: 'Junction'
12
+ K: 'Bell Operating Company Nonbuilding Location'
13
+ L: 'Bell Operating Company Nonbuilding Location'
14
+ M: 'Manhole'
15
+ N: 'Bell Operating Company Nonbuilding Location'
16
+ O: 'Bell Operating Company Nonbuilding Location'
17
+ P: 'Pole'
18
+ Q: 'Radio'
19
+ R: 'Repeater'
20
+ S: 'Toll Station'
21
+ T: 'Bell Operating Company Nonbuilding Location'
22
+ U: 'Other'
23
+ V: 'Bell Operating Company Nonbuilding Location'
24
+ W: 'Bell Operating Company Nonbuilding Location'
25
+ X: 'Independent Telephone Company Nonbuilding Location'
26
+ Y: 'Bell Operating Company Nonbuilding Location'
27
+ Z: 'Bell Operating Company Nonbuilding Location'
28
+ '0': 'Customer Location'
29
+ '1': 'Customer Location'
30
+ '2': 'Customer Location'
31
+ '3': 'Customer Location'
32
+ '4': 'Customer Location'
33
+ '5': 'Customer Location'
34
+ '6': 'Customer Location'
35
+ '7': 'Customer Location'
36
+ '8': 'Customer Location'
37
+ '9': 'Customer Location'
@@ -0,0 +1,25 @@
1
+ ---
2
+ # Quebec, Canada
3
+ PQ:
4
+ state: QC
5
+ country: CA
6
+
7
+ # Nunavut, Canada
8
+ VU:
9
+ state: NU
10
+ country: CA
11
+
12
+ # Newfoundland and Labrador, Canada
13
+ NF:
14
+ state: NL
15
+ country: CA
16
+
17
+ # High Seas / International Waters
18
+ HS:
19
+ state:
20
+ country: XZ
21
+
22
+ # Earth Orbit / Satellite
23
+ EO:
24
+ state:
25
+ country: XS
@@ -0,0 +1,59 @@
1
+ class CLLI
2
+ ##
3
+ # This module provides methods to lookup the entity code description for a
4
+ # parsed +CLLI+ string.
5
+ module EntityType
6
+ ##
7
+ # When this modeule is included then extend the including class with the
8
+ # methods defined in +ClassMethods+.
9
+ def self.included(o)
10
+ o.extend(ClassMethods)
11
+ end
12
+
13
+ ##
14
+ # These methods will be available in the +CLLI+ class.
15
+ module ClassMethods
16
+ include Pattern
17
+
18
+ @entity_type_data = nil
19
+
20
+ ##
21
+ # Lookup the entity code description for a parsed +CLLI+ string.
22
+ #
23
+ # Params:
24
+ # +code+:: the +CLLI+ +:entity_code+ attribute value.
25
+ def entity_type(code)
26
+ @entity_type_data ||= YAMLData.new(%w(clli data entity_types.yml))
27
+ @entity_type_data.get(*code_keys(code))
28
+ end
29
+
30
+ private
31
+
32
+ ##
33
+ # Determine which key to use for the parsed entity code.
34
+ #
35
+ # Params:
36
+ # +code+:: the +CLLI+ +:entity_code+ attribute value.
37
+ def code_keys(code)
38
+ case code
39
+ when Regexp.new("MG[#{x1}]") then %w(switching_types MGx)
40
+ when Regexp.new("SG[#{x1}]") then %w(switching_types SGx)
41
+ when Regexp.new("CG[#{x1}]") then %w(switching_types CGx)
42
+ when Regexp.new("DS[#{x1}]") then %w(switching_types DSx)
43
+ when Regexp.new("[#{n}]{2}[#{x1}]") then %w(switching_types nnx)
44
+ when Regexp.new("[#{n}]{2}T") then %w(switching_types nnT)
45
+ when Regexp.new("C[#{n}]T") then %w(switching_types CnT)
46
+ when Regexp.new("B[#{n}]T") then %w(switching_types BnT)
47
+ when Regexp.new("[#{n}]GT") then %w(switching_types nGT)
48
+ when Regexp.new("Z[#{a}]Z") then %w(switching_types ZaZ)
49
+ when Regexp.new("RS[#{n}]") then %w(switching_types RSn)
50
+ when Regexp.new("X[#{a}]X") then %w(switching_types XaX)
51
+ when Regexp.new("CT[#{x1}]") then %w(switching_types CTx)
52
+ when Regexp.new(switchboard_and_desk_entity_code_pattern) then ['switchboard_and_desk', code[1]]
53
+ when Regexp.new(miscellaneous_switching_termination_entity_code_pattern) then ['miscellaneous_switching_termination', code[1]]
54
+ when Regexp.new(nonswitching_entity_code_pattern) then ['nonswitching_types', code[0]]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,104 @@
1
+ class CLLI
2
+ # This module is used to convert CLLI region codes into ISO 3166 codes.
3
+ module ISO3166
4
+ ##
5
+ # When this modeule is included then extend the including class with the
6
+ # methods defined in +ClassMethods+.
7
+ def self.included(o)
8
+ o.extend(ClassMethods)
9
+ end
10
+
11
+ ##
12
+ # These methods will be available in the CLLI class.
13
+ module ClassMethods
14
+ @region_conversion_data = nil
15
+
16
+ ##
17
+ # Convert the +CLLI+ region code into an ISO 3166 country code.
18
+ #
19
+ # Params:
20
+ # +region-code+:: the +CLLI+ +:region+ attribute value.
21
+ def iso_country(region_code)
22
+ load_data
23
+ return @region_conversion_data[region_code]['country'] if @region_conversion_data.key?(region_code)
24
+ country = ::ISO3166::Country.new(region_code)
25
+ country.nil? ? 'ZZ' : country.alpha2
26
+ end
27
+
28
+ ##
29
+ # Lookup the name of the country for the specified +region_code+.
30
+ #
31
+ # Params:
32
+ # +region-code+:: the +CLLI+ +:region+ attribute value.
33
+ def country_name(region_code)
34
+ country_code = iso_country(region_code)
35
+ country = ::ISO3166::Country.new(country_code)
36
+ return if country.nil?
37
+ country.name
38
+ end
39
+
40
+ ##
41
+ # Convert the +CLLI+ region code into an ISO 3166 state code.
42
+ #
43
+ # Params:
44
+ # +region-code+:: the +CLLI+ +:region+ attribute value.
45
+ def iso_state(region_code)
46
+ load_data
47
+ return @region_conversion_data[region_code]['state'] if @region_conversion_data.key?(region_code)
48
+ end
49
+
50
+ ##
51
+ # Lookup the name of the state for the specified +region_code+.
52
+ #
53
+ # Params:
54
+ # +region-code+:: the +CLLI+ +:region+ attribute value.
55
+ def state_name(region_code)
56
+ state_code = iso_state(region_code)
57
+ return unless state_code
58
+ country_code = iso_country(region_code)
59
+ return unless country_code
60
+ country = ::ISO3166::Country.new(country_code)
61
+ return unless country
62
+ state_data = country.states[state_code]
63
+ return unless state_data
64
+ state_data['name']
65
+ end
66
+
67
+ private
68
+
69
+ ##
70
+ # Get an array of all the state codes in the specified country.
71
+ #
72
+ # Params:
73
+ # +iso_country+:: the ISO 3166 country code.
74
+ def state_codes(iso_country)
75
+ country = ::ISO3166::Country.new(iso_country)
76
+ return [] unless country
77
+ country.states.keys
78
+ end
79
+
80
+ ##
81
+ # Load the region code conversion data.
82
+ def load_data
83
+ return unless @region_conversion_data.nil?
84
+ data = {}
85
+ # Load the YAML region code conversion data.
86
+ data.merge!(YAMLData.new(%w(clli data region_conversions.yml)).data)
87
+
88
+ # load the US & Canadian state conversions.
89
+ data.merge!(us_ca_state_conversions)
90
+ @region_conversion_data = data
91
+ end
92
+
93
+ ##
94
+ # load the US & Canadian state conversions.
95
+ def us_ca_state_conversions
96
+ %w(US CA).each_with_object({}) do |country, data|
97
+ state_codes(country).each do |state|
98
+ data[state] = { 'state' => state, 'country' => country }
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,31 @@
1
+ class CLLI
2
+ ##
3
+ # This module provides methods to lookup the location code description for a
4
+ # parsed +CLLI+ string.
5
+ module LocationType
6
+ ##
7
+ # When this modeule is included then extend the including class with the
8
+ # methods defined in +ClassMethods+.
9
+ def self.included(o)
10
+ o.extend(ClassMethods)
11
+ end
12
+
13
+ ##
14
+ # These methods will be available in the CLLI class.
15
+ module ClassMethods
16
+ include Pattern
17
+
18
+ @location_type_data = nil
19
+
20
+ ##
21
+ # Lookup the entity code description for a parsed +CLLI+ string.
22
+ #
23
+ # Params:
24
+ # +code+:: the +CLLI+ +:location_code+ or +:customer_code+ attribute value.
25
+ def location_type(code)
26
+ @location_type_data ||= YAMLData.new(%w(clli data location_types.yml))
27
+ @location_type_data.get(code)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,203 @@
1
+ class CLLI
2
+ ##
3
+ # This module provides the various patterns used for parsing +CLLI+ strings.
4
+ module Pattern
5
+ ##
6
+ # When this modeule is included then extend the including class with the
7
+ # methods defined in +ClassMethods+.
8
+ def self.included(o)
9
+ o.extend(ClassMethods)
10
+ end
11
+
12
+ ##
13
+ # These methods will be available in the CLLI class.
14
+ module ClassMethods
15
+ DEFAULT_PATTERN_OPTIONS = {
16
+ strict: true,
17
+ place_group: 'place',
18
+ region_group: 'region',
19
+ network_site_group: 'network_site',
20
+ entity_code_group: 'entity_code',
21
+ nonbuilding_code_group: 'location_code',
22
+ nonbuilding_id_group: 'location_id',
23
+ customer_code_group: 'customer_code',
24
+ customer_id_group: 'customer_id'
25
+ }
26
+
27
+ ##
28
+ # Get the complete +CLLI+ pattern.
29
+ #
30
+ # Params:
31
+ # +options+:: the following options are supported.
32
+ # [:strict] whether or not the rules in section
33
+ # +795-100-100+ are enforced for all fields.
34
+ # [:place_group] the name to use for the place abbreviation.
35
+ # [:region_group] the name to use for the region code.
36
+ # [:network_site_group] the name to use for the network site code.
37
+ # [:entity_code_group] the name to use for the entity code.
38
+ # [:nonbuilding_code_group] the name to use for the nonbuilding code.
39
+ # [:nonbuilding_id_group] the name to use for the nonbuilding ID.
40
+ # [:customer_code_group] the name to use for the customer code.
41
+ # [:customer_id_group] the name to use for the customer ID.
42
+ def pattern(**options)
43
+ place = place_pattern(options)
44
+ network_site = network_site_pattern(options)
45
+ entity_code = entity_code_pattern(options)
46
+ nonbuilding_location = nonbuilding_location_pattern(options)
47
+ customer_location = customer_location_pattern(options)
48
+ "#{place}(?:#{network_site}(?:#{entity_code})?|#{nonbuilding_location}|#{customer_location})"
49
+ end
50
+
51
+ ##
52
+ # Get the complete +CLLI+ pattern as a compiled +Regexp+.
53
+ #
54
+ # Params:
55
+ # +options+:: see #pattern for more details.
56
+ def regexp(**options)
57
+ Regexp.new(pattern(options))
58
+ end
59
+
60
+ ##
61
+ # Get the place abbreviation and region code pattern.
62
+ #
63
+ # Params:
64
+ # +options+:: see #pattern for more details.
65
+ def place_pattern(**options)
66
+ options = DEFAULT_PATTERN_OPTIONS.merge(options)
67
+ pattern = named_group(options[:place_group], options[:strict] ? "[#{a}]{4}|[#{a}]{3}[ ]|[#{a}]{2}[ ]{2}" : "[#{x}\s]{4}")
68
+ pattern << named_group(options[:region_group], '[A-Z]{2}')
69
+ end
70
+
71
+ ##
72
+ # Get the network site code pattern.
73
+ #
74
+ # Params:
75
+ # +options+:: see #pattern for more details.
76
+ def network_site_pattern(**options)
77
+ options = DEFAULT_PATTERN_OPTIONS.merge(options)
78
+ named_group(options[:network_site_group], options[:strict] ? "(?:[#{a}]{2}|[#{n}]{2})" : "(?:[#{a}#{n}]{2})")
79
+ end
80
+
81
+ ##
82
+ # Get the entity code pattern.
83
+ #
84
+ # Params:
85
+ # +options+:: see #pattern for more details.
86
+ def entity_code_pattern(**options)
87
+ options = DEFAULT_PATTERN_OPTIONS.merge(options)
88
+ named_group(options[:entity_code_group], [
89
+ switching_entity_code_pattern, # (Table B)
90
+ switchboard_and_desk_entity_code_pattern, # (Table C)
91
+ miscellaneous_switching_termination_entity_code_pattern, # (Table D)
92
+ nonswitching_entity_code_pattern # (Table E)
93
+ ].join('|'))
94
+ end
95
+
96
+ # Switching Entities (Table B)
97
+ def switching_entity_code_pattern
98
+ [
99
+ "(?:MG|SG|CG|DS|[#{n}][#{n}])[#{x1}]",
100
+ "[CB#{n}][#{n}]T",
101
+ "[#{n}]GT",
102
+ "Z[#{a}]Z",
103
+ "RS[#{n}]",
104
+ "X[#{a}]X",
105
+ "CT[#{x1}]"
106
+ ].join('|')
107
+ end
108
+
109
+ # Switchboard and Desk Termination Entities (Table C)
110
+ def switchboard_and_desk_entity_code_pattern
111
+ "[#{n}][CDBINQWMVROLPEUTZ#{n}]B"
112
+ end
113
+
114
+ # Miscellaneous switching termination entities (Table D)
115
+ def miscellaneous_switching_termination_entity_code_pattern
116
+ ["[#{n}][AXCTWDEINPQ]D", "[#{x}][UM]D"].join('|')
117
+ end
118
+
119
+ # Non-Switching Entities (Table E)
120
+ def nonswitching_entity_code_pattern
121
+ ["[FAEKMPSTW][#{x2}][#{x1}]", "Q[#{n}][#{n}]"].join('|')
122
+ end
123
+
124
+ ##
125
+ # Get the non-building location code pattern.
126
+ #
127
+ # Params:
128
+ # +options+:: see #pattern for more details.
129
+ def nonbuilding_location_pattern(**options)
130
+ options = DEFAULT_PATTERN_OPTIONS.merge(options)
131
+ pattern = named_group(options[:nonbuilding_code_group], "[#{a}]")
132
+ pattern << named_group(options[:nonbuilding_id_group], "[#{n}]{4}")
133
+ end
134
+
135
+ ##
136
+ # Get the customer non-building location pattern.
137
+ #
138
+ # Params:
139
+ # +options+:: see #pattern for more details.
140
+ def customer_location_pattern(**options)
141
+ options = DEFAULT_PATTERN_OPTIONS.merge(options)
142
+ pattern = named_group(options[:customer_code_group], "[#{n}]")
143
+ pattern << named_group(options[:customer_id_group], "[#{a}][#{n}]{3}")
144
+ end
145
+
146
+ ##
147
+ # A character group excluding B, D, I, O, T, U, W, and Y.
148
+ def a1
149
+ 'ACE-HJ-NP-SVXZ'
150
+ end
151
+
152
+ ##
153
+ # A character group excluding G.
154
+ def a2
155
+ 'A-FH-Z'
156
+ end
157
+
158
+ ##
159
+ # A character group containing all alpha characters.
160
+ def a
161
+ 'A-Z'
162
+ end
163
+
164
+ ##
165
+ # A character group containing all digit characters.
166
+ def n
167
+ '0-9'
168
+ end
169
+
170
+ ##
171
+ # A character group containing all alpha and digit characters.
172
+ def x
173
+ a + n
174
+ end
175
+
176
+ ##
177
+ # A character group containing both +a1+ and all digit characters.
178
+ def x1
179
+ a1 + n
180
+ end
181
+
182
+ ##
183
+ # A character group containing both +a2+ and all digit characters.
184
+ def x2
185
+ a2 + n
186
+ end
187
+
188
+ private
189
+
190
+ ##
191
+ # Generate a named group using the specified +name+ and +pattern+. If the
192
+ # +name+ is +nil+ then just the +pattern+ will be returned.
193
+ #
194
+ # Params:
195
+ # +name+:: the name of the group.
196
+ # +pattern+:: the pattern inside the group.
197
+ def named_group(name, pattern)
198
+ return pattern if name.nil? || name.respond_to?(:empty?) && name.empty?
199
+ "(?<#{name}>#{pattern})"
200
+ end
201
+ end
202
+ end
203
+ end