german_phone_number_classifier 1.0.0.pre
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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +61 -0
- data/.gitignore +57 -0
- data/.rspec +3 -0
- data/.rubocop.yml +11 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +79 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +89 -0
- data/Rakefile +8 -0
- data/bin/console +16 -0
- data/bin/parse_landline +23 -0
- data/bin/setup +8 -0
- data/german_phone_number_classifier.gemspec +48 -0
- data/lib/german_phone_number_classifier/german_landline_prefixes.rb +5208 -0
- data/lib/german_phone_number_classifier/version.rb +5 -0
- data/lib/german_phone_number_classifier.rb +115 -0
- metadata +192 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'phony'
|
4
|
+
require 'german_phone_number_classifier/version'
|
5
|
+
require 'german_phone_number_classifier/german_landline_prefixes'
|
6
|
+
|
7
|
+
# module providing classifier method for phone numbers
|
8
|
+
# as specified by the Bundesnetzagentur
|
9
|
+
# https://www.bundesnetzagentur.de/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Nummerierung/start.html
|
10
|
+
module GermanPhoneNumberClassifier
|
11
|
+
class Error < StandardError; end
|
12
|
+
|
13
|
+
def self.classify(phone_number)
|
14
|
+
raise ArgumentError, 'nil phone number' unless phone_number
|
15
|
+
|
16
|
+
scanned = phone_number.scan(/(\+|\d)/).join
|
17
|
+
|
18
|
+
return classify_international(scanned) if scanned.start_with?('+', '00')
|
19
|
+
return classify_national(scanned) if scanned.start_with?('0', '1')
|
20
|
+
|
21
|
+
:no_phone_number
|
22
|
+
rescue ArgumentError
|
23
|
+
:no_phone_number
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.landline_location(phone_number)
|
27
|
+
return unless classify(phone_number) == :landline
|
28
|
+
|
29
|
+
scanned = phone_number.scan(/(\+|\d)/).join
|
30
|
+
national_number = if scanned.start_with?('+', '00')
|
31
|
+
_cc, *national_blocks = Phony.split(
|
32
|
+
Phony.normalize(scanned)
|
33
|
+
)
|
34
|
+
prepend_zero(national_blocks)
|
35
|
+
else
|
36
|
+
scanned
|
37
|
+
end
|
38
|
+
|
39
|
+
return unless national_number.length > 5
|
40
|
+
|
41
|
+
(3..6).each do |n|
|
42
|
+
hit = landline_lookup(national_number, n)
|
43
|
+
return hit if hit
|
44
|
+
end
|
45
|
+
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# private class methods
|
50
|
+
|
51
|
+
def self.classify_international(international_phone_number)
|
52
|
+
cc, *national_blocks = Phony.split(
|
53
|
+
Phony.normalize(international_phone_number)
|
54
|
+
)
|
55
|
+
|
56
|
+
return :non_german_phone_number unless cc == '49'
|
57
|
+
return :no_phone_number if national_blocks.join.length.zero?
|
58
|
+
|
59
|
+
classify_national(prepend_zero(national_blocks))
|
60
|
+
end
|
61
|
+
|
62
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
63
|
+
def self.classify_national(national_phone_number)
|
64
|
+
return :authoritative if authoritive?(national_phone_number)
|
65
|
+
return :provider_selection if national_phone_number.match(/^010\d+$/)
|
66
|
+
return :high_connection if national_phone_number.match(/^0137\d+$/)
|
67
|
+
return :service_hotline if national_phone_number.match(/^0180\d+$/)
|
68
|
+
return :vpn if national_phone_number.match(/^018\d+$/)
|
69
|
+
return :online_and_traffic if national_phone_number.match(/^019\d+$/)
|
70
|
+
return :personal_number if national_phone_number.match(/^0700\d+$/)
|
71
|
+
return :free_service_hotline if national_phone_number.match(/^0800\d+$/)
|
72
|
+
return :dialer if national_phone_number.match(/^09009\d+$/)
|
73
|
+
return :premium_service_hotline if national_phone_number.match(/^0900\d+$/)
|
74
|
+
return :mobile if national_phone_number.match(/^015\d+$/)
|
75
|
+
return :mobile if national_phone_number.match(/^016\d+$/)
|
76
|
+
return :mobile if national_phone_number.match(/^017\d+$/)
|
77
|
+
return :test_provider if national_phone_number.match(/^031(0|1)$/)
|
78
|
+
return :landline if landline?(national_phone_number)
|
79
|
+
|
80
|
+
:unknown_class
|
81
|
+
end
|
82
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
83
|
+
|
84
|
+
def self.prepend_zero(national_blocks)
|
85
|
+
national_blocks.dup.prepend('0').join
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.authoritive?(national_phone_number)
|
89
|
+
case national_phone_number
|
90
|
+
when '110', '112', '115', /^116\d{3}$/, /^118\d{2}$/
|
91
|
+
true
|
92
|
+
else
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.landline?(national_phone_number)
|
98
|
+
return false unless national_phone_number.length > 5
|
99
|
+
|
100
|
+
(3..6).each do |n|
|
101
|
+
return true if landline_lookup(national_phone_number, n)
|
102
|
+
end
|
103
|
+
|
104
|
+
false
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.landline_lookup(national_phone_number, length)
|
108
|
+
GermanPhoneNumberClassifier::GERMAN_LANDLINE_PREFIXES[
|
109
|
+
national_phone_number[0, length].to_i
|
110
|
+
]
|
111
|
+
end
|
112
|
+
|
113
|
+
private_class_method :prepend_zero, :classify_national, :landline_lookup,
|
114
|
+
:classify_international, :authoritive?, :landline?
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: german_phone_number_classifier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carsten Wirth
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: phony
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.19.9
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.19.9
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 11.1.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 11.1.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.25'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.25'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.10'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.21.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.21.2
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov-console
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.9'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.9'
|
139
|
+
description: Library for checking in which category a german phone number falls in
|
140
|
+
regards to Bundesnetzagentur classes.
|
141
|
+
email:
|
142
|
+
- carsten.wirth@homeday.de
|
143
|
+
executables: []
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".github/workflows/ruby.yml"
|
148
|
+
- ".gitignore"
|
149
|
+
- ".rspec"
|
150
|
+
- ".rubocop.yml"
|
151
|
+
- ".ruby-version"
|
152
|
+
- ".travis.yml"
|
153
|
+
- Gemfile
|
154
|
+
- Gemfile.lock
|
155
|
+
- LICENSE
|
156
|
+
- LICENSE.txt
|
157
|
+
- README.md
|
158
|
+
- Rakefile
|
159
|
+
- bin/console
|
160
|
+
- bin/parse_landline
|
161
|
+
- bin/setup
|
162
|
+
- german_phone_number_classifier.gemspec
|
163
|
+
- lib/german_phone_number_classifier.rb
|
164
|
+
- lib/german_phone_number_classifier/german_landline_prefixes.rb
|
165
|
+
- lib/german_phone_number_classifier/version.rb
|
166
|
+
homepage: https://github.com/jethroo/german_phone_number_classifier
|
167
|
+
licenses:
|
168
|
+
- MIT
|
169
|
+
metadata:
|
170
|
+
homepage_uri: https://github.com/jethroo/german_phone_number_classifier
|
171
|
+
source_code_uri: https://github.com/jethroo/german_phone_number_classifier
|
172
|
+
rubygems_mfa_required: 'true'
|
173
|
+
post_install_message:
|
174
|
+
rdoc_options: []
|
175
|
+
require_paths:
|
176
|
+
- lib
|
177
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 2.7.0
|
182
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 1.3.1
|
187
|
+
requirements: []
|
188
|
+
rubygems_version: 3.3.5
|
189
|
+
signing_key:
|
190
|
+
specification_version: 4
|
191
|
+
summary: Classifying german phone numbers
|
192
|
+
test_files: []
|