lite-address 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +39 -55
- data/README.md +19 -15
- data/Rakefile +2 -2
- data/bin/console +3 -3
- data/lib/lite/address/format.rb +21 -40
- data/lib/lite/address/list.rb +29 -29
- data/lib/lite/address/parser.rb +38 -38
- data/lib/lite/address/regexp.rb +3 -3
- data/lib/lite/address/types/part.yml +17 -0
- data/lib/lite/address/ukey.rb +6 -8
- data/lib/lite/address/version.rb +1 -1
- data/lib/lite/address.rb +6 -6
- data/lite-address.gemspec +23 -30
- metadata +10 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36e2c1997170c93506425dd544c0062935dcd259907358f65369939d2eaa6873
|
4
|
+
data.tar.gz: e49a679ac35e9112ace7cefcf692801764b75dfecc7c0fbe36d144906b4c1b2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6325e5bbb27050fbb0d187c4a82f0198972c1cf570fd323bb08eb786bde058724c9dc678bd078e060c62b6a046b5474b9a172cc7793026bf83e6f7628b66b907
|
7
|
+
data.tar.gz: 8f345971caa3e404ab079b970f07e2e4bab655c2c64eba1abf93af3b69f593857c1853dc1fb791a290268709a1eb8ea74d936cc21dc9b423ec5cd0d1f66fd891
|
data/.rubocop.yml
CHANGED
@@ -3,7 +3,6 @@ require:
|
|
3
3
|
- rubocop-rake
|
4
4
|
- rubocop-rspec
|
5
5
|
AllCops:
|
6
|
-
TargetRubyVersion: 3.0
|
7
6
|
NewCops: enable
|
8
7
|
DisplayCopNames: true
|
9
8
|
DisplayStyleGuide: true
|
@@ -19,13 +18,15 @@ Layout/EmptyLinesAroundClassBody:
|
|
19
18
|
Layout/EmptyLinesAroundModuleBody:
|
20
19
|
EnforcedStyle: empty_lines_except_namespace
|
21
20
|
Layout/LineLength:
|
22
|
-
|
21
|
+
Enabled: false
|
23
22
|
Layout/SpaceAroundMethodCallOperator:
|
24
23
|
Enabled: true
|
25
24
|
Lint/RaiseException:
|
26
25
|
Enabled: true
|
27
26
|
Lint/StructNewOverride:
|
28
27
|
Enabled: true
|
28
|
+
Metrics/AbcSize:
|
29
|
+
Enabled: false
|
29
30
|
Metrics/BlockLength:
|
30
31
|
Exclude:
|
31
32
|
- 'spec/**/**/*'
|
@@ -38,11 +39,15 @@ RSpec/ExampleLength:
|
|
38
39
|
Enabled: false
|
39
40
|
RSpec/MultipleExpectations:
|
40
41
|
Enabled: false
|
42
|
+
RSpec/NoExpectationExample:
|
43
|
+
Enabled: false
|
41
44
|
Style/ArgumentsForwarding:
|
42
45
|
Enabled: false
|
43
46
|
Style/Documentation:
|
44
47
|
Enabled: false
|
45
48
|
Style/ExpandPathArguments:
|
46
49
|
Enabled: false
|
50
|
+
Style/StringLiterals:
|
51
|
+
EnforcedStyle: double_quotes
|
47
52
|
Style/StructInheritance:
|
48
53
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [1.1.0] - 2022-11-17
|
10
|
+
### Changed
|
11
|
+
- Improved docs
|
12
|
+
- Updated internal setup
|
13
|
+
- Improved rubocop setup
|
14
|
+
|
15
|
+
## [1.0.1] - 2021-09-09
|
16
|
+
### Changed
|
17
|
+
- Remove snail dependency
|
18
|
+
|
9
19
|
## [1.0.0] - 2021-09-09
|
10
20
|
### Added
|
11
21
|
- Initial project version
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,85 +1,69 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lite-address (1.
|
4
|
+
lite-address (1.1.0)
|
5
5
|
countries
|
6
|
-
snail
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: https://rubygems.org/
|
10
9
|
specs:
|
11
|
-
activesupport (6.1.4.1)
|
12
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
-
i18n (>= 1.6, < 2)
|
14
|
-
minitest (>= 5.1)
|
15
|
-
tzinfo (~> 2.0)
|
16
|
-
zeitwerk (~> 2.3)
|
17
10
|
ast (2.4.2)
|
18
11
|
colorize (0.8.1)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
diff-lcs (1.4.4)
|
24
|
-
fasterer (0.9.0)
|
12
|
+
countries (5.2.0)
|
13
|
+
unaccent (~> 0.3)
|
14
|
+
diff-lcs (1.5.0)
|
15
|
+
fasterer (0.10.0)
|
25
16
|
colorize (~> 0.7)
|
26
|
-
ruby_parser (>= 3.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
minitest (5.14.4)
|
31
|
-
parallel (1.20.2)
|
32
|
-
parser (3.0.2.0)
|
17
|
+
ruby_parser (>= 3.19.1)
|
18
|
+
json (2.6.2)
|
19
|
+
parallel (1.22.1)
|
20
|
+
parser (3.1.2.1)
|
33
21
|
ast (~> 2.4.1)
|
34
|
-
rainbow (3.
|
22
|
+
rainbow (3.1.1)
|
35
23
|
rake (13.0.6)
|
36
|
-
regexp_parser (2.
|
24
|
+
regexp_parser (2.6.1)
|
37
25
|
rexml (3.2.5)
|
38
|
-
rspec (3.
|
39
|
-
rspec-core (~> 3.
|
40
|
-
rspec-expectations (~> 3.
|
41
|
-
rspec-mocks (~> 3.
|
42
|
-
rspec-core (3.
|
43
|
-
rspec-support (~> 3.
|
44
|
-
rspec-expectations (3.
|
26
|
+
rspec (3.12.0)
|
27
|
+
rspec-core (~> 3.12.0)
|
28
|
+
rspec-expectations (~> 3.12.0)
|
29
|
+
rspec-mocks (~> 3.12.0)
|
30
|
+
rspec-core (3.12.0)
|
31
|
+
rspec-support (~> 3.12.0)
|
32
|
+
rspec-expectations (3.12.0)
|
45
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
-
rspec-support (~> 3.
|
47
|
-
rspec-mocks (3.
|
34
|
+
rspec-support (~> 3.12.0)
|
35
|
+
rspec-mocks (3.12.0)
|
48
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
49
|
-
rspec-support (~> 3.
|
50
|
-
rspec-support (3.
|
51
|
-
rubocop (1.
|
37
|
+
rspec-support (~> 3.12.0)
|
38
|
+
rspec-support (3.12.0)
|
39
|
+
rubocop (1.39.0)
|
40
|
+
json (~> 2.3)
|
52
41
|
parallel (~> 1.10)
|
53
|
-
parser (>= 3.
|
42
|
+
parser (>= 3.1.2.1)
|
54
43
|
rainbow (>= 2.2.2, < 4.0)
|
55
44
|
regexp_parser (>= 1.8, < 3.0)
|
56
|
-
rexml
|
57
|
-
rubocop-ast (>= 1.
|
45
|
+
rexml (>= 3.2.5, < 4.0)
|
46
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
58
47
|
ruby-progressbar (~> 1.7)
|
59
48
|
unicode-display_width (>= 1.4.0, < 3.0)
|
60
|
-
rubocop-ast (1.
|
61
|
-
parser (>= 3.
|
62
|
-
rubocop-performance (1.
|
49
|
+
rubocop-ast (1.23.0)
|
50
|
+
parser (>= 3.1.1.0)
|
51
|
+
rubocop-performance (1.15.1)
|
63
52
|
rubocop (>= 1.7.0, < 2.0)
|
64
53
|
rubocop-ast (>= 0.4.0)
|
65
54
|
rubocop-rake (0.6.0)
|
66
55
|
rubocop (~> 1.0)
|
67
|
-
rubocop-rspec (2.
|
68
|
-
rubocop (~> 1.
|
69
|
-
rubocop-ast (>= 1.1.0)
|
56
|
+
rubocop-rspec (2.15.0)
|
57
|
+
rubocop (~> 1.33)
|
70
58
|
ruby-progressbar (1.11.0)
|
71
|
-
ruby_parser (3.
|
72
|
-
sexp_processor (~> 4.
|
73
|
-
sexp_processor (4.
|
74
|
-
|
75
|
-
|
76
|
-
activesupport
|
77
|
-
tzinfo (2.0.4)
|
78
|
-
concurrent-ruby (~> 1.0)
|
79
|
-
unicode-display_width (2.0.0)
|
80
|
-
zeitwerk (2.4.2)
|
59
|
+
ruby_parser (3.19.1)
|
60
|
+
sexp_processor (~> 4.16)
|
61
|
+
sexp_processor (4.16.1)
|
62
|
+
unaccent (0.4.0)
|
63
|
+
unicode-display_width (2.3.0)
|
81
64
|
|
82
65
|
PLATFORMS
|
66
|
+
arm64-darwin-21
|
83
67
|
x86_64-darwin-20
|
84
68
|
|
85
69
|
DEPENDENCIES
|
@@ -94,4 +78,4 @@ DEPENDENCIES
|
|
94
78
|
rubocop-rspec
|
95
79
|
|
96
80
|
BUNDLED WITH
|
97
|
-
2.
|
81
|
+
2.3.26
|
data/README.md
CHANGED
@@ -31,8 +31,9 @@ methods below (check the class to see more). If an address cannot be parsed then
|
|
31
31
|
will be returned, but partial matches can be returned. All addresses will try to be
|
32
32
|
normalized to return a predictable pattern.
|
33
33
|
|
34
|
+
#### Full matches
|
34
35
|
```
|
35
|
-
address = Lite::Address::
|
36
|
+
address = Lite::Address::Parser.any("1600 Pennsylvania Ave, Washington, DC, 20500")
|
36
37
|
address.street #=> Pennsylvania
|
37
38
|
address.number #=> 1600
|
38
39
|
address.postal_code #=> 20500
|
@@ -41,17 +42,14 @@ address.state #=> DC
|
|
41
42
|
address.state_name #=> District of Columbia
|
42
43
|
address.street_type #=> Ave
|
43
44
|
address.intersection? #=> false
|
45
|
+
```
|
44
46
|
|
45
|
-
|
47
|
+
#### Partial matches
|
48
|
+
```
|
49
|
+
address = Lite::Address::Parser.any("1600 Pennsylvania Ave")
|
46
50
|
address.street #=> Pennsylvania
|
47
51
|
address.number #=> 1600
|
48
52
|
address.state #=> nil
|
49
|
-
|
50
|
-
address = Lite::Address::Parse.parse("5904 Richmond Hwy Ste 340 Alexandria VA 22303-1864")
|
51
|
-
address.postal_code_ext #=> 1846
|
52
|
-
|
53
|
-
address = Lite::Address::Parse.parse("5904 Richmond Hwy Ste 340 Alexandria VA 223031864")
|
54
|
-
address.postal_code_ext #=> 1846
|
55
53
|
```
|
56
54
|
|
57
55
|
## Formatting
|
@@ -59,7 +57,7 @@ address.postal_code_ext #=> 1846
|
|
59
57
|
A formatted can be returned to as a whole or in parts of simple strings.
|
60
58
|
|
61
59
|
```
|
62
|
-
address = Lite::Address::
|
60
|
+
address = Lite::Address::Parser.any("1600 Pennsylvania Ave, Washington, DC, 20500")
|
63
61
|
address.to_s #=> 1600 Pennsylvania Ave, Washington, DC 20500
|
64
62
|
address.to_s(:line1) #=> 1600 Pennsylvania Ave
|
65
63
|
address.to_s(:line2) #=> Washington, DC 20500
|
@@ -67,14 +65,20 @@ address.to_s(:line2) #=> Washington, DC 20500
|
|
67
65
|
|
68
66
|
You can also format strings to the proper country mail format.
|
69
67
|
|
68
|
+
#### Address only
|
70
69
|
```
|
71
|
-
address = Lite::Address::
|
72
|
-
address.to_snail
|
73
|
-
|
70
|
+
address = Lite::Address::Parser.any("1600 Pennsylvania Ave, Washington, DC, 20500")
|
71
|
+
address.to_snail #=> 1600 Pennsylvania Ave,
|
72
|
+
Washington, DC 20500
|
74
73
|
|
75
|
-
|
76
|
-
|
77
|
-
|
74
|
+
```
|
75
|
+
|
76
|
+
#### Name prepended
|
77
|
+
```
|
78
|
+
address = Lite::Address::Parser.any("1600 Pennsylvania Ave, Washington, DC, 20500")
|
79
|
+
address.to_snail(name: 'John Doe') #=> John Doe
|
80
|
+
1600 Pennsylvania Ave,
|
81
|
+
Washington, DC 20500
|
78
82
|
```
|
79
83
|
|
80
84
|
## Development
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "lite/address"
|
6
6
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -11,5 +11,5 @@ require 'lite/address'
|
|
11
11
|
# require "pry"
|
12
12
|
# Pry.start
|
13
13
|
|
14
|
-
require
|
14
|
+
require "irb"
|
15
15
|
IRB.start(__FILE__)
|
data/lib/lite/address/format.rb
CHANGED
@@ -1,31 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'snail' unless defined?(Snail)
|
4
|
-
|
5
3
|
module Lite
|
6
4
|
module Address
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
suffix suffix2
|
15
|
-
city
|
16
|
-
state
|
17
|
-
postal_code postal_code_ext
|
18
|
-
country list regexp
|
19
|
-
].freeze
|
20
|
-
|
21
|
-
class Format < Struct.new(*FORMAT_KEYS, keyword_init: true)
|
6
|
+
PARTS = begin
|
7
|
+
file_path = File.expand_path("types/part.yml", File.dirname(__FILE__))
|
8
|
+
YAML.load_file(file_path).map(&:to_sym)
|
9
|
+
end
|
10
|
+
|
11
|
+
class Format < Struct.new(:list, *PARTS, keyword_init: true)
|
22
12
|
|
23
13
|
def country_code
|
24
14
|
country.alpha2
|
25
15
|
end
|
26
16
|
|
27
17
|
def country_name
|
28
|
-
country.
|
18
|
+
country.iso_short_name
|
29
19
|
end
|
30
20
|
|
31
21
|
def intersection?
|
@@ -35,16 +25,16 @@ module Lite
|
|
35
25
|
def full_postal_code
|
36
26
|
return if postal_code.nil?
|
37
27
|
|
38
|
-
@full_postal_code ||= [postal_code, postal_code_ext].compact.join(
|
28
|
+
@full_postal_code ||= [postal_code, postal_code_ext].compact.join("-")
|
39
29
|
end
|
40
30
|
|
41
|
-
def line1(str = +
|
31
|
+
def line1(str = +"")
|
42
32
|
parts = intersection? ? intersection_line1 : address_line1
|
43
|
-
str + parts.compact.join(
|
33
|
+
str + parts.compact.join(" ").strip
|
44
34
|
end
|
45
35
|
|
46
|
-
def line2(str = +
|
47
|
-
str += [city, state].compact.join(
|
36
|
+
def line2(str = +"")
|
37
|
+
str += [city, state].compact.join(", ")
|
48
38
|
str << " #{full_postal_code}" if postal_code
|
49
39
|
str.strip
|
50
40
|
end
|
@@ -54,7 +44,7 @@ module Lite
|
|
54
44
|
end
|
55
45
|
|
56
46
|
def to_h
|
57
|
-
@to_h ||= Lite::Address::
|
47
|
+
@to_h ||= Lite::Address::PARTS.each_with_object({}) do |key, hash|
|
58
48
|
hash[key] = public_send(key)
|
59
49
|
end
|
60
50
|
end
|
@@ -63,12 +53,14 @@ module Lite
|
|
63
53
|
case format
|
64
54
|
when :line1 then line1
|
65
55
|
when :line2 then line2
|
66
|
-
else [line1, line2].reject(&:empty?).join(
|
56
|
+
else [line1, line2].reject(&:empty?).join(", ")
|
67
57
|
end
|
68
58
|
end
|
69
59
|
|
70
|
-
def to_snail(
|
71
|
-
|
60
|
+
def to_snail(prefixes: [], include_country: false)
|
61
|
+
prefixes.push(line1, line2)
|
62
|
+
prefixes.push(country_name) if include_country
|
63
|
+
prefixes.compact.join("\n")
|
72
64
|
end
|
73
65
|
|
74
66
|
def to_ukey
|
@@ -84,7 +76,6 @@ module Lite
|
|
84
76
|
|
85
77
|
private
|
86
78
|
|
87
|
-
# rubocop:disable Metrics/AbcSize, Naming/VariableNumber
|
88
79
|
def address_line1
|
89
80
|
parts = []
|
90
81
|
parts << number
|
@@ -94,34 +85,24 @@ module Lite
|
|
94
85
|
parts << suffix
|
95
86
|
parts << unit_prefix
|
96
87
|
# http://pe.usps.gov/cpim/ftp/pubs/Pub28/pub28.pdf pg28
|
97
|
-
parts << (unit_prefix ? unit : "
|
88
|
+
parts << (unit_prefix ? unit : "# #{unit}") if unit
|
98
89
|
parts
|
99
90
|
end
|
100
91
|
|
101
|
-
def snail_params
|
102
|
-
{
|
103
|
-
line_1: line1,
|
104
|
-
city: city,
|
105
|
-
region: state,
|
106
|
-
postal_code: full_postal_code,
|
107
|
-
country: country_code
|
108
|
-
}
|
109
|
-
end
|
110
|
-
|
111
92
|
def intersection_line1
|
112
93
|
parts = []
|
113
94
|
parts << prefix
|
114
95
|
parts << street
|
115
96
|
parts << street_type
|
116
97
|
parts << suffix
|
117
|
-
parts <<
|
98
|
+
parts << "and"
|
118
99
|
parts << prefix2
|
119
100
|
parts << street2
|
120
101
|
parts << street_type2
|
121
102
|
parts << suffix2
|
122
103
|
parts
|
123
104
|
end
|
124
|
-
# rubocop:enable Metrics/AbcSize
|
105
|
+
# rubocop:enable Metrics/AbcSize
|
125
106
|
|
126
107
|
end
|
127
108
|
|
data/lib/lite/address/list.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "yaml" unless defined?(YAML)
|
4
4
|
|
5
5
|
module Lite
|
6
6
|
module Address
|
@@ -18,14 +18,14 @@ module Lite
|
|
18
18
|
|
19
19
|
def cardinal_types
|
20
20
|
@cardinal_types ||= begin
|
21
|
-
file_path = File.expand_path(
|
21
|
+
file_path = File.expand_path("types/cardinal.yml", File.dirname(__FILE__))
|
22
22
|
YAML.load_file(file_path)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
def street_types
|
27
27
|
@street_types ||= begin
|
28
|
-
file_path = File.expand_path(
|
28
|
+
file_path = File.expand_path("types/street.yml", File.dirname(__FILE__))
|
29
29
|
YAML.load_file(file_path)
|
30
30
|
end
|
31
31
|
end
|
@@ -57,37 +57,37 @@ module Lite
|
|
57
57
|
|
58
58
|
def unit_abbr_numbered_regexps
|
59
59
|
@unit_abbr_numbered_regexps ||= {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
60
|
+
"Apt" => /(?:ap|dep)(?:ar)?t(?:me?nt)?/i,
|
61
|
+
"PO Box" => /p\W*[om]\W*b(?:ox)?/i,
|
62
|
+
"Bldg" => /bu?i?ldi?n?g/i,
|
63
|
+
"Dept" => /dep(artmen)?t/i,
|
64
|
+
"Floor" => /flo*r?/i,
|
65
|
+
"Hanger" => /ha?nga?r/i,
|
66
|
+
"Lot" => /lo?t/i,
|
67
|
+
"Room" => /ro*m/i,
|
68
|
+
"Pier" => /pier/i,
|
69
|
+
"Slip" => /slip/i,
|
70
|
+
"Space" => /spa?ce?/i,
|
71
|
+
"Stop" => /stop/i,
|
72
|
+
"Drawer" => /drawer/i,
|
73
|
+
"Suite" => /su?i?te/i,
|
74
|
+
"Trailer" => /tra?i?le?r/i,
|
75
|
+
"Box" => /\w*(?<!po\W)box/i,
|
76
|
+
"Unit" => /uni?t/i
|
77
77
|
}
|
78
78
|
end
|
79
79
|
|
80
80
|
def unit_abbr_unnumbered_regexps
|
81
81
|
@unit_abbr_unnumbered_regexps ||= {
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
"Basement" => /ba?se?me?n?t/i,
|
83
|
+
"Front" => /fro?nt/i,
|
84
|
+
"Lobby" => /lo?bby/i,
|
85
|
+
"Lower" => /lowe?r/i,
|
86
|
+
"Office" => /off?i?ce?/i,
|
87
|
+
"PH" => /pe?n?t?ho?u?s?e?/i,
|
88
|
+
"Rear" => /rear/i,
|
89
|
+
"Side" => /side/i,
|
90
|
+
"Upper" => /uppe?r/i
|
91
91
|
}
|
92
92
|
end
|
93
93
|
|
data/lib/lite/address/parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "countries" unless defined?(ISO3166::Country)
|
4
4
|
|
5
5
|
module Lite
|
6
6
|
module Address
|
@@ -8,11 +8,11 @@ module Lite
|
|
8
8
|
|
9
9
|
LOOKUPS = %i[any formal informal intersectional].freeze
|
10
10
|
CAPITALIZATION_PARTS = %w[street street_type street2 street_type2 city unit_prefix].freeze
|
11
|
-
STREET_POSITIONS = [
|
11
|
+
STREET_POSITIONS = ["", "1", "2"].freeze
|
12
12
|
|
13
13
|
attr_reader :address, :country_code
|
14
14
|
|
15
|
-
def initialize(address, country_code:
|
15
|
+
def initialize(address, country_code: "US")
|
16
16
|
@address = sanitize_address(address)
|
17
17
|
@country_code = sanitize_country_code(country_code)
|
18
18
|
end
|
@@ -21,7 +21,7 @@ module Lite
|
|
21
21
|
|
22
22
|
LOOKUPS.each do |method_name|
|
23
23
|
define_method(method_name) do |address, args = {}|
|
24
|
-
instance = new(address, country_code: args.delete(:country_code) ||
|
24
|
+
instance = new(address, country_code: args.delete(:country_code) || "US")
|
25
25
|
instance.public_send(method_name, args)
|
26
26
|
end
|
27
27
|
end
|
@@ -52,9 +52,9 @@ module Lite
|
|
52
52
|
return unless (match = regexp.intersectional_address.match(address))
|
53
53
|
|
54
54
|
map = match_map(match)
|
55
|
-
intersectional_submatch(match, map,
|
56
|
-
intersectional_submatch(match, map,
|
57
|
-
intersectional_rematch(match, map,
|
55
|
+
intersectional_submatch(match, map, "street")
|
56
|
+
intersectional_submatch(match, map, "street_type")
|
57
|
+
intersectional_rematch(match, map, "street_type")
|
58
58
|
|
59
59
|
generate_address(map, args)
|
60
60
|
end
|
@@ -76,7 +76,7 @@ module Lite
|
|
76
76
|
private
|
77
77
|
|
78
78
|
def sanitize_address(value)
|
79
|
-
value.delete_prefix(
|
79
|
+
value.delete_prefix("(").delete_suffix(")")
|
80
80
|
end
|
81
81
|
|
82
82
|
def sanitize_country_code(value)
|
@@ -89,19 +89,18 @@ module Lite
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
# rubocop:disable Metrics/AbcSize
|
93
92
|
def normalization_map
|
94
93
|
@normalization_map ||= {
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
94
|
+
"prefix" => list.cardinal_types,
|
95
|
+
"prefix1" => list.cardinal_types,
|
96
|
+
"prefix2" => list.cardinal_types,
|
97
|
+
"suffix" => list.cardinal_types,
|
98
|
+
"suffix1" => list.cardinal_types,
|
99
|
+
"suffix2" => list.cardinal_types,
|
100
|
+
"street_type" => list.street_types,
|
101
|
+
"street_type1" => list.street_types,
|
102
|
+
"street_type2" => list.street_types,
|
103
|
+
"state" => list.subdivision_names
|
105
104
|
}
|
106
105
|
end
|
107
106
|
# rubocop:enable Metrics/AbcSize
|
@@ -117,7 +116,7 @@ module Lite
|
|
117
116
|
return unless map[part] && (!map["#{part}2"] || (map[part] == map["#{part}2"]))
|
118
117
|
|
119
118
|
type = map[part].dup
|
120
|
-
return unless type.gsub!(/s\W*$/i,
|
119
|
+
return unless type.gsub!(/s\W*$/i, "") && (/\A#{regexp.public_send(part)}\z/io =~ type)
|
121
120
|
|
122
121
|
map[part] = map["#{part}2"] = type
|
123
122
|
end
|
@@ -126,27 +125,27 @@ module Lite
|
|
126
125
|
map.each do |key, string|
|
127
126
|
string.strip!
|
128
127
|
|
129
|
-
if key ==
|
130
|
-
string.gsub!(%r{[^\w\s\-\#&/.]},
|
128
|
+
if key == "number"
|
129
|
+
string.gsub!(%r{[^\w\s\-\#&/.]}, "")
|
131
130
|
else
|
132
|
-
string.gsub!(%r{[^\w\s\-\#&/]},
|
131
|
+
string.gsub!(%r{[^\w\s\-\#&/]}, "")
|
133
132
|
end
|
134
133
|
end
|
135
134
|
end
|
136
135
|
|
137
136
|
def address_redundantize_street_type(map)
|
138
|
-
map[
|
139
|
-
return unless map[
|
137
|
+
map["redundant_street_type"] = false
|
138
|
+
return unless map["street"] && !map["street_type"]
|
140
139
|
|
141
|
-
match = regexp.street.match(map[
|
142
|
-
map[
|
143
|
-
map[
|
140
|
+
match = regexp.street.match(map["street"])
|
141
|
+
map["street_type"] = match["street_type"] if match
|
142
|
+
map["redundant_street_type"] = true
|
144
143
|
end
|
145
144
|
|
146
145
|
def address_abbreviate_unit_prefixes(map)
|
147
146
|
list.unit_abbr_regexps.each do |abbr, regex|
|
148
|
-
regex.match(map[
|
149
|
-
map[
|
147
|
+
regex.match(map["unit_prefix"]) do |_match|
|
148
|
+
map["unit_prefix"] = abbr
|
150
149
|
end
|
151
150
|
end
|
152
151
|
end
|
@@ -174,25 +173,25 @@ module Lite
|
|
174
173
|
end
|
175
174
|
|
176
175
|
def address_expand_cardinals(map)
|
177
|
-
return unless map[
|
176
|
+
return unless map["city"]
|
178
177
|
|
179
|
-
map[
|
178
|
+
map["city"].gsub!(/^(#{regexp.cardinal_code})\s+(?=\S)/o) do |match|
|
180
179
|
"#{list.cardinal_codes[match[0].upcase]} "
|
181
180
|
end
|
182
181
|
end
|
183
182
|
|
184
183
|
def address_fix_dirty_ordinals(map)
|
185
184
|
# Sometimes parcel data will have addresses like "1 1ST ST" as "1 1 ST ST"
|
186
|
-
return unless map[
|
185
|
+
return unless map["street"]
|
187
186
|
|
188
|
-
map[
|
189
|
-
match.gsub!(/\s+/,
|
187
|
+
map["street"].gsub!(/\A(\d+\s+st|\d+\s+nd|\d+\s+rd|\d+\s+th)\z/i) do |match|
|
188
|
+
match.gsub!(/\s+/, "")
|
190
189
|
end
|
191
190
|
end
|
192
191
|
|
193
192
|
def address_capitalize_parts(map)
|
194
193
|
CAPITALIZATION_PARTS.each do |k|
|
195
|
-
map[k] = map[k].split.map(&:capitalize).join(
|
194
|
+
map[k] = map[k].split.map(&:capitalize).join(" ") if map[k]
|
196
195
|
end
|
197
196
|
end
|
198
197
|
|
@@ -206,8 +205,9 @@ module Lite
|
|
206
205
|
address_fix_dirty_ordinals(map)
|
207
206
|
address_capitalize_parts(map)
|
208
207
|
|
209
|
-
map
|
210
|
-
|
208
|
+
map[:country] = country
|
209
|
+
|
210
|
+
Lite::Address::Format.new(list:, **map)
|
211
211
|
end
|
212
212
|
|
213
213
|
end
|
data/lib/lite/address/regexp.rb
CHANGED
@@ -17,7 +17,7 @@ module Lite
|
|
17
17
|
def cardinal_code
|
18
18
|
@cardinal_code ||= begin
|
19
19
|
values = list.cardinal_codes.keys
|
20
|
-
::Regexp.new(values.join(
|
20
|
+
::Regexp.new(values.join("|"), ::Regexp::IGNORECASE)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -28,7 +28,7 @@ module Lite
|
|
28
28
|
array << [::Regexp.quote(val.gsub(/(\w)/, '\1.')), ::Regexp.quote(val)]
|
29
29
|
end
|
30
30
|
|
31
|
-
::Regexp.new(values.join(
|
31
|
+
::Regexp.new(values.join("|"), ::Regexp::IGNORECASE)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -113,7 +113,7 @@ module Lite
|
|
113
113
|
def street_type
|
114
114
|
@street_type ||= begin
|
115
115
|
values = (list.street_types.keys + list.street_types.values).uniq
|
116
|
-
::Regexp.new(values.join(
|
116
|
+
::Regexp.new(values.join("|"), ::Regexp::IGNORECASE)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
data/lib/lite/address/ukey.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "digest" unless defined?(Digest)
|
4
4
|
|
5
5
|
module Lite
|
6
6
|
module Address
|
7
|
-
|
7
|
+
module Ukey
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def generate(value)
|
12
|
-
result = value.downcase.gsub(/[^0-9a-z]/i, '')
|
13
|
-
Digest::MD5.hexdigest(result)
|
14
|
-
end
|
9
|
+
module_function
|
15
10
|
|
11
|
+
def generate(value)
|
12
|
+
result = value.downcase.gsub(/[^0-9a-z]/i, "")
|
13
|
+
Digest::MD5.hexdigest(result)
|
16
14
|
end
|
17
15
|
|
18
16
|
end
|
data/lib/lite/address/version.rb
CHANGED
data/lib/lite/address.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "lite/address/version"
|
4
|
+
require "lite/address/ukey"
|
5
|
+
require "lite/address/list"
|
6
|
+
require "lite/address/regexp"
|
7
|
+
require "lite/address/format"
|
8
|
+
require "lite/address/parser"
|
data/lite-address.gemspec
CHANGED
@@ -1,51 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
5
|
+
require "lite/address/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
8
|
+
spec.name = "lite-address"
|
9
9
|
spec.version = Lite::Address::VERSION
|
10
|
-
spec.authors = [
|
10
|
+
spec.authors = ["Juan Gomez"]
|
11
11
|
spec.email = %w[j.gomez@drexed.com]
|
12
12
|
|
13
|
-
spec.summary =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = "Parse and normalize street addresses"
|
14
|
+
spec.homepage = "http://drexed.github.io/lite-address"
|
15
|
+
spec.license = "MIT"
|
16
16
|
|
17
17
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
18
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
'source_code_uri' => 'https://github.com/drexed/lite-address'
|
25
|
-
)
|
26
|
-
else
|
27
|
-
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
28
|
-
'public gem pushes.'
|
29
|
-
end
|
19
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/drexed/lite-address/blob/master/CHANGELOG.md"
|
21
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
22
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
23
|
+
spec.metadata["source_code_uri"] = "https://github.com/drexed/lite-address"
|
30
24
|
|
31
25
|
# Specify which files should be added to the gem when it is released.
|
32
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
33
|
-
spec.files = Dir.chdir(File.expand_path(
|
27
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
34
28
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
35
29
|
end
|
36
|
-
spec.bindir =
|
30
|
+
spec.bindir = "exe"
|
37
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
32
|
spec.require_paths = %w[lib]
|
39
33
|
|
40
|
-
spec.add_dependency
|
41
|
-
spec.add_dependency 'snail'
|
34
|
+
spec.add_dependency "countries"
|
42
35
|
|
43
|
-
spec.add_development_dependency
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
46
|
-
spec.add_development_dependency
|
47
|
-
spec.add_development_dependency
|
48
|
-
spec.add_development_dependency
|
49
|
-
spec.add_development_dependency
|
50
|
-
spec.add_development_dependency
|
36
|
+
spec.add_development_dependency "bundler"
|
37
|
+
spec.add_development_dependency "fasterer"
|
38
|
+
spec.add_development_dependency "rake"
|
39
|
+
spec.add_development_dependency "rspec"
|
40
|
+
spec.add_development_dependency "rubocop"
|
41
|
+
spec.add_development_dependency "rubocop-performance"
|
42
|
+
spec.add_development_dependency "rubocop-rake"
|
43
|
+
spec.add_development_dependency "rubocop-rspec"
|
51
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lite-address
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Gomez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: countries
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: snail
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,6 +163,7 @@ files:
|
|
177
163
|
- lib/lite/address/parser.rb
|
178
164
|
- lib/lite/address/regexp.rb
|
179
165
|
- lib/lite/address/types/cardinal.yml
|
166
|
+
- lib/lite/address/types/part.yml
|
180
167
|
- lib/lite/address/types/street.yml
|
181
168
|
- lib/lite/address/ukey.rb
|
182
169
|
- lib/lite/address/version.rb
|
@@ -184,7 +171,12 @@ files:
|
|
184
171
|
homepage: http://drexed.github.io/lite-address
|
185
172
|
licenses:
|
186
173
|
- MIT
|
187
|
-
metadata:
|
174
|
+
metadata:
|
175
|
+
allowed_push_host: https://rubygems.org
|
176
|
+
changelog_uri: https://github.com/drexed/lite-address/blob/master/CHANGELOG.md
|
177
|
+
homepage_uri: http://drexed.github.io/lite-address
|
178
|
+
rubygems_mfa_required: 'true'
|
179
|
+
source_code_uri: https://github.com/drexed/lite-address
|
188
180
|
post_install_message:
|
189
181
|
rdoc_options: []
|
190
182
|
require_paths:
|
@@ -200,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
192
|
- !ruby/object:Gem::Version
|
201
193
|
version: '0'
|
202
194
|
requirements: []
|
203
|
-
rubygems_version: 3.
|
195
|
+
rubygems_version: 3.3.26
|
204
196
|
signing_key:
|
205
197
|
specification_version: 4
|
206
198
|
summary: Parse and normalize street addresses
|