lite-address 1.0.1 → 1.1.0
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 +4 -4
- data/.rubocop.yml +7 -2
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +39 -39
- data/README.md +19 -15
- data/Rakefile +2 -2
- data/bin/console +3 -3
- data/lib/lite/address/format.rb +16 -25
- 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 -29
- metadata +10 -4
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,12 @@ 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
|
+
|
|
9
15
|
## [1.0.1] - 2021-09-09
|
|
10
16
|
### Changed
|
|
11
17
|
- Remove snail dependency
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
lite-address (1.0
|
|
4
|
+
lite-address (1.1.0)
|
|
5
5
|
countries
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -9,61 +9,61 @@ GEM
|
|
|
9
9
|
specs:
|
|
10
10
|
ast (2.4.2)
|
|
11
11
|
colorize (0.8.1)
|
|
12
|
-
countries (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
fasterer (0.9.0)
|
|
12
|
+
countries (5.2.0)
|
|
13
|
+
unaccent (~> 0.3)
|
|
14
|
+
diff-lcs (1.5.0)
|
|
15
|
+
fasterer (0.10.0)
|
|
17
16
|
colorize (~> 0.7)
|
|
18
|
-
ruby_parser (>= 3.
|
|
19
|
-
|
|
20
|
-
parallel (1.
|
|
21
|
-
parser (3.
|
|
17
|
+
ruby_parser (>= 3.19.1)
|
|
18
|
+
json (2.6.2)
|
|
19
|
+
parallel (1.22.1)
|
|
20
|
+
parser (3.1.2.1)
|
|
22
21
|
ast (~> 2.4.1)
|
|
23
|
-
rainbow (3.
|
|
22
|
+
rainbow (3.1.1)
|
|
24
23
|
rake (13.0.6)
|
|
25
|
-
regexp_parser (2.
|
|
24
|
+
regexp_parser (2.6.1)
|
|
26
25
|
rexml (3.2.5)
|
|
27
|
-
rspec (3.
|
|
28
|
-
rspec-core (~> 3.
|
|
29
|
-
rspec-expectations (~> 3.
|
|
30
|
-
rspec-mocks (~> 3.
|
|
31
|
-
rspec-core (3.
|
|
32
|
-
rspec-support (~> 3.
|
|
33
|
-
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)
|
|
34
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
-
rspec-support (~> 3.
|
|
36
|
-
rspec-mocks (3.
|
|
34
|
+
rspec-support (~> 3.12.0)
|
|
35
|
+
rspec-mocks (3.12.0)
|
|
37
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
-
rspec-support (~> 3.
|
|
39
|
-
rspec-support (3.
|
|
40
|
-
rubocop (1.
|
|
37
|
+
rspec-support (~> 3.12.0)
|
|
38
|
+
rspec-support (3.12.0)
|
|
39
|
+
rubocop (1.39.0)
|
|
40
|
+
json (~> 2.3)
|
|
41
41
|
parallel (~> 1.10)
|
|
42
|
-
parser (>= 3.
|
|
42
|
+
parser (>= 3.1.2.1)
|
|
43
43
|
rainbow (>= 2.2.2, < 4.0)
|
|
44
44
|
regexp_parser (>= 1.8, < 3.0)
|
|
45
|
-
rexml
|
|
46
|
-
rubocop-ast (>= 1.
|
|
45
|
+
rexml (>= 3.2.5, < 4.0)
|
|
46
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
|
47
47
|
ruby-progressbar (~> 1.7)
|
|
48
48
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
49
|
-
rubocop-ast (1.
|
|
50
|
-
parser (>= 3.
|
|
51
|
-
rubocop-performance (1.
|
|
49
|
+
rubocop-ast (1.23.0)
|
|
50
|
+
parser (>= 3.1.1.0)
|
|
51
|
+
rubocop-performance (1.15.1)
|
|
52
52
|
rubocop (>= 1.7.0, < 2.0)
|
|
53
53
|
rubocop-ast (>= 0.4.0)
|
|
54
54
|
rubocop-rake (0.6.0)
|
|
55
55
|
rubocop (~> 1.0)
|
|
56
|
-
rubocop-rspec (2.
|
|
57
|
-
rubocop (~> 1.
|
|
58
|
-
rubocop-ast (>= 1.1.0)
|
|
56
|
+
rubocop-rspec (2.15.0)
|
|
57
|
+
rubocop (~> 1.33)
|
|
59
58
|
ruby-progressbar (1.11.0)
|
|
60
|
-
ruby_parser (3.
|
|
61
|
-
sexp_processor (~> 4.
|
|
62
|
-
sexp_processor (4.
|
|
63
|
-
|
|
64
|
-
unicode-display_width (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)
|
|
65
64
|
|
|
66
65
|
PLATFORMS
|
|
66
|
+
arm64-darwin-21
|
|
67
67
|
x86_64-darwin-20
|
|
68
68
|
|
|
69
69
|
DEPENDENCIES
|
|
@@ -78,4 +78,4 @@ DEPENDENCIES
|
|
|
78
78
|
rubocop-rspec
|
|
79
79
|
|
|
80
80
|
BUNDLED WITH
|
|
81
|
-
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
|
@@ -3,27 +3,19 @@
|
|
|
3
3
|
module Lite
|
|
4
4
|
module Address
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
suffix suffix2
|
|
13
|
-
city
|
|
14
|
-
state
|
|
15
|
-
postal_code postal_code_ext
|
|
16
|
-
country list regexp
|
|
17
|
-
].freeze
|
|
18
|
-
|
|
19
|
-
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)
|
|
20
12
|
|
|
21
13
|
def country_code
|
|
22
14
|
country.alpha2
|
|
23
15
|
end
|
|
24
16
|
|
|
25
17
|
def country_name
|
|
26
|
-
country.
|
|
18
|
+
country.iso_short_name
|
|
27
19
|
end
|
|
28
20
|
|
|
29
21
|
def intersection?
|
|
@@ -33,16 +25,16 @@ module Lite
|
|
|
33
25
|
def full_postal_code
|
|
34
26
|
return if postal_code.nil?
|
|
35
27
|
|
|
36
|
-
@full_postal_code ||= [postal_code, postal_code_ext].compact.join(
|
|
28
|
+
@full_postal_code ||= [postal_code, postal_code_ext].compact.join("-")
|
|
37
29
|
end
|
|
38
30
|
|
|
39
|
-
def line1(str = +
|
|
31
|
+
def line1(str = +"")
|
|
40
32
|
parts = intersection? ? intersection_line1 : address_line1
|
|
41
|
-
str + parts.compact.join(
|
|
33
|
+
str + parts.compact.join(" ").strip
|
|
42
34
|
end
|
|
43
35
|
|
|
44
|
-
def line2(str = +
|
|
45
|
-
str += [city, state].compact.join(
|
|
36
|
+
def line2(str = +"")
|
|
37
|
+
str += [city, state].compact.join(", ")
|
|
46
38
|
str << " #{full_postal_code}" if postal_code
|
|
47
39
|
str.strip
|
|
48
40
|
end
|
|
@@ -52,7 +44,7 @@ module Lite
|
|
|
52
44
|
end
|
|
53
45
|
|
|
54
46
|
def to_h
|
|
55
|
-
@to_h ||= Lite::Address::
|
|
47
|
+
@to_h ||= Lite::Address::PARTS.each_with_object({}) do |key, hash|
|
|
56
48
|
hash[key] = public_send(key)
|
|
57
49
|
end
|
|
58
50
|
end
|
|
@@ -61,7 +53,7 @@ module Lite
|
|
|
61
53
|
case format
|
|
62
54
|
when :line1 then line1
|
|
63
55
|
when :line2 then line2
|
|
64
|
-
else [line1, line2].reject(&:empty?).join(
|
|
56
|
+
else [line1, line2].reject(&:empty?).join(", ")
|
|
65
57
|
end
|
|
66
58
|
end
|
|
67
59
|
|
|
@@ -84,7 +76,6 @@ module Lite
|
|
|
84
76
|
|
|
85
77
|
private
|
|
86
78
|
|
|
87
|
-
# rubocop:disable Metrics/AbcSize
|
|
88
79
|
def address_line1
|
|
89
80
|
parts = []
|
|
90
81
|
parts << number
|
|
@@ -94,7 +85,7 @@ 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
|
|
|
@@ -104,7 +95,7 @@ module Lite
|
|
|
104
95
|
parts << street
|
|
105
96
|
parts << street_type
|
|
106
97
|
parts << suffix
|
|
107
|
-
parts <<
|
|
98
|
+
parts << "and"
|
|
108
99
|
parts << prefix2
|
|
109
100
|
parts << street2
|
|
110
101
|
parts << street_type2
|
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,50 +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
|
|
34
|
+
spec.add_dependency "countries"
|
|
41
35
|
|
|
42
|
-
spec.add_development_dependency
|
|
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
|
|
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"
|
|
50
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.0
|
|
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
|
|
@@ -163,6 +163,7 @@ files:
|
|
|
163
163
|
- lib/lite/address/parser.rb
|
|
164
164
|
- lib/lite/address/regexp.rb
|
|
165
165
|
- lib/lite/address/types/cardinal.yml
|
|
166
|
+
- lib/lite/address/types/part.yml
|
|
166
167
|
- lib/lite/address/types/street.yml
|
|
167
168
|
- lib/lite/address/ukey.rb
|
|
168
169
|
- lib/lite/address/version.rb
|
|
@@ -170,7 +171,12 @@ files:
|
|
|
170
171
|
homepage: http://drexed.github.io/lite-address
|
|
171
172
|
licenses:
|
|
172
173
|
- MIT
|
|
173
|
-
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
|
|
174
180
|
post_install_message:
|
|
175
181
|
rdoc_options: []
|
|
176
182
|
require_paths:
|
|
@@ -186,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
186
192
|
- !ruby/object:Gem::Version
|
|
187
193
|
version: '0'
|
|
188
194
|
requirements: []
|
|
189
|
-
rubygems_version: 3.
|
|
195
|
+
rubygems_version: 3.3.26
|
|
190
196
|
signing_key:
|
|
191
197
|
specification_version: 4
|
|
192
198
|
summary: Parse and normalize street addresses
|