municipitaly2 2.0.2 → 2.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 224c12115ea80572b0572b38215e5d4253b3a8a857f01cda384a32239707be13
4
- data.tar.gz: cdcb4d301ba9420fcc4b4c7800bbb2cbb92fd37cd1e9436db0a81a2de1f989a7
3
+ metadata.gz: 6d902371314d1cd9ee768b61f9ea0b3b2068725802993273fc369a9e8e155ae9
4
+ data.tar.gz: 3791df596b257073b1f9607ef574c102ec3bf398480f4a5982be6f2bcdbd7926
5
5
  SHA512:
6
- metadata.gz: 472c21524089a08d167ab736fd7fd22274b66efccf1cf0e669da133c1cd7356607771999416a78588f6f13744b25ac6da5f290392b828f2fafdd10d838c27574
7
- data.tar.gz: 303c00313760f6572b63683857fc998828b5e972b5d28f76c71800cf6355c87223830290a373df115e3078a1892a5450aa4301452ba550927d8bd4c976d57061
6
+ metadata.gz: d056647d30265de06c3e6750e8ecb3009de4c3cd03e771764fdc8b2592774478fa61988cbc7ea66e740fee3e9ec19258c6b2c05c2321e3deb78f8ef3221fee62
7
+ data.tar.gz: f6e9d07aaf5089cd5eb30d677b6360bd628083a02362f32403abfa1996a97eae6cf66067ac8345fcb2c6e857033958f466b7ed8b860d5aeafef156a18670f92d
data/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.4] - 2025-09-09
9
+
10
+ - Updated database
11
+ - Updated gems
12
+ - Improved search municipalities results order
13
+
14
+ ## [2.0.3] - 2024-12-17
15
+
16
+ - Search region by its name: `Municipitaly::Search.region_from_name('a region')`
17
+ - Fixed and tested specs
18
+
8
19
  ## [2.0.2] - 2024-12-13
9
20
 
10
21
  - Added `csv` to spec as advised for ruby `3.4.0` onward
data/Gemfile CHANGED
@@ -4,3 +4,9 @@ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in fitbark.gemspec
6
6
  gemspec
7
+
8
+ gem 'bundler', '~> 2.7'
9
+ gem 'rake', '~> 13.3'
10
+ gem 'rspec', '~> 3.13'
11
+ gem 'rubocop', '~> 1.80'
12
+ gem 'simplecov', '~> 0.22'
data/Gemfile.lock CHANGED
@@ -1,73 +1,77 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- municipitaly2 (2.0.0)
4
+ municipitaly2 (2.0.4)
5
+ csv (~> 3.3.5)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
- ast (2.4.2)
10
- diff-lcs (1.5.1)
11
- docile (1.4.0)
12
- json (2.7.2)
13
- language_server-protocol (3.17.0.3)
14
- parallel (1.25.1)
15
- parser (3.3.4.0)
10
+ ast (2.4.3)
11
+ csv (3.3.5)
12
+ diff-lcs (1.6.2)
13
+ docile (1.4.1)
14
+ json (2.13.2)
15
+ language_server-protocol (3.17.0.5)
16
+ lint_roller (1.1.0)
17
+ parallel (1.27.0)
18
+ parser (3.3.9.0)
16
19
  ast (~> 2.4.1)
17
20
  racc
18
- racc (1.8.0)
21
+ prism (1.4.0)
22
+ racc (1.8.1)
19
23
  rainbow (3.1.1)
20
- rake (13.2.1)
21
- regexp_parser (2.9.2)
22
- rexml (3.3.2)
23
- strscan
24
- rspec (3.13.0)
24
+ rake (13.3.0)
25
+ regexp_parser (2.11.2)
26
+ rspec (3.13.1)
25
27
  rspec-core (~> 3.13.0)
26
28
  rspec-expectations (~> 3.13.0)
27
29
  rspec-mocks (~> 3.13.0)
28
- rspec-core (3.13.0)
30
+ rspec-core (3.13.5)
29
31
  rspec-support (~> 3.13.0)
30
- rspec-expectations (3.13.1)
32
+ rspec-expectations (3.13.5)
31
33
  diff-lcs (>= 1.2.0, < 2.0)
32
34
  rspec-support (~> 3.13.0)
33
- rspec-mocks (3.13.1)
35
+ rspec-mocks (3.13.5)
34
36
  diff-lcs (>= 1.2.0, < 2.0)
35
37
  rspec-support (~> 3.13.0)
36
- rspec-support (3.13.1)
37
- rubocop (1.64.1)
38
+ rspec-support (3.13.5)
39
+ rubocop (1.80.2)
38
40
  json (~> 2.3)
39
- language_server-protocol (>= 3.17.0)
41
+ language_server-protocol (~> 3.17.0.2)
42
+ lint_roller (~> 1.1.0)
40
43
  parallel (~> 1.10)
41
44
  parser (>= 3.3.0.2)
42
45
  rainbow (>= 2.2.2, < 4.0)
43
- regexp_parser (>= 1.8, < 3.0)
44
- rexml (>= 3.2.5, < 4.0)
45
- rubocop-ast (>= 1.31.1, < 2.0)
46
+ regexp_parser (>= 2.9.3, < 3.0)
47
+ rubocop-ast (>= 1.46.0, < 2.0)
46
48
  ruby-progressbar (~> 1.7)
47
- unicode-display_width (>= 2.4.0, < 3.0)
48
- rubocop-ast (1.31.3)
49
- parser (>= 3.3.1.0)
49
+ unicode-display_width (>= 2.4.0, < 4.0)
50
+ rubocop-ast (1.46.0)
51
+ parser (>= 3.3.7.2)
52
+ prism (~> 1.4)
50
53
  ruby-progressbar (1.13.0)
51
54
  simplecov (0.22.0)
52
55
  docile (~> 1.1)
53
56
  simplecov-html (~> 0.11)
54
57
  simplecov_json_formatter (~> 0.1)
55
- simplecov-html (0.12.3)
58
+ simplecov-html (0.13.2)
56
59
  simplecov_json_formatter (0.1.4)
57
- strscan (3.1.0)
58
- unicode-display_width (2.5.0)
60
+ unicode-display_width (3.1.5)
61
+ unicode-emoji (~> 4.0, >= 4.0.4)
62
+ unicode-emoji (4.0.4)
59
63
 
60
64
  PLATFORMS
61
65
  ruby
62
66
  x86_64-linux
63
67
 
64
68
  DEPENDENCIES
65
- bundler (~> 2.5.11)
69
+ bundler (~> 2.7)
66
70
  municipitaly2!
67
- rake (~> 13.2.1)
71
+ rake (~> 13.3)
68
72
  rspec (~> 3.13)
69
- rubocop (~> 1.64.1)
70
- simplecov (~> 0.22.0)
73
+ rubocop (~> 1.80)
74
+ simplecov (~> 0.22)
71
75
 
72
76
  BUNDLED WITH
73
- 2.5.11
77
+ 2.7.2
data/README.md CHANGED
@@ -14,6 +14,12 @@ Thanks to natydev for the brilliant project.
14
14
 
15
15
  Add this line to your application's Gemfile:
16
16
 
17
+ ```ruby
18
+ gem 'municipitaly2'
19
+ ```
20
+
21
+ or if you want to use directly from the git repo:
22
+
17
23
  ```ruby
18
24
  gem 'municipitaly2', git: 'https://github.com/yupswing/municipitaly2.git', branch: 'master'
19
25
  ```
@@ -252,5 +258,6 @@ Check the `tools` folder.
252
258
  The tool is rought but it gets the job done. Hopefully I will improve it in the future.
253
259
 
254
260
  ### Generate vendor/data/municipalities.csv
261
+
255
262
  Update links in `tools/generate.rb` (and/or data in `tools/data/istat*`) and execute
256
263
  `./tools/generate.rb`
@@ -15,11 +15,18 @@ module Municipitaly2
15
15
  class Search
16
16
  include DataCaller
17
17
 
18
- CLASS_METHODS = %i[zone_from_code region_from_istat regions_from_zone_code
19
- province_from_name province_from_istat
20
- province_from_acronym provinces_from_region_istat
21
- provinces_from_zone_code municipalities_from_name
22
- municipality_from_cadastrial municipality_from_istat
18
+ CLASS_METHODS = %i[zone_from_code
19
+ region_from_name
20
+ region_from_istat
21
+ regions_from_zone_code
22
+ province_from_name
23
+ province_from_istat
24
+ province_from_acronym
25
+ provinces_from_region_istat
26
+ provinces_from_zone_code
27
+ municipalities_from_name
28
+ municipality_from_cadastrial
29
+ municipality_from_istat
23
30
  municipalities_from_postal_code
24
31
  municipalities_from_province_istat
25
32
  municipalities_from_region_istat
@@ -50,6 +57,20 @@ module Municipitaly2
50
57
  end
51
58
  end
52
59
 
60
+ # returns a +Municipitaly2::Region+ object from a <b>region name</b> term
61
+ #
62
+ # example usage:
63
+ # region = Search.region_from_name('liguria')
64
+ def region_from_name # :doc:
65
+ term_set = Municipitaly2.sanitize_term(term)
66
+ return nil if term_set.size < 3
67
+
68
+ data.regions.find do |r|
69
+ name_set = Municipitaly2.sanitize_term(r.name)
70
+ name_set =~ Regexp.new(term_set)
71
+ end
72
+ end
73
+
53
74
  # returns a +Municipitaly2::Region+ object from a <b>region istat</b> term
54
75
  #
55
76
  # example usage:
@@ -103,8 +124,9 @@ module Municipitaly2
103
124
  # example usage:
104
125
  # province = Search.province_from_acronym('MI')
105
126
  def province_from_acronym # :doc:
127
+ acronym = term.strip.upcase
106
128
  data.provinces.find do |p|
107
- p.acronym == term
129
+ p.acronym == acronym
108
130
  end
109
131
  end
110
132
 
@@ -136,6 +158,9 @@ module Municipitaly2
136
158
  # Term can be a partial string and is case insensitive.
137
159
  # The optional parameter +greedy+ [boolean] permit to serch exact term
138
160
  # name (if false) or partial word (true by default).
161
+ # Matches are sorted by relevance: exact matches first, then starting with the
162
+ # term, then words starting with the term, then other matches. Within each
163
+ # group, matches are sorted by population (descending) and then by name.
139
164
  #
140
165
  # example usage:
141
166
  # municipalities = Search.municipalities_from_name('monte')
@@ -146,14 +171,15 @@ module Municipitaly2
146
171
 
147
172
  return [] if term_set.size < 3
148
173
 
149
- regexp = if greedy
150
- Regexp.new(term_set, true)
151
- else
152
- Regexp.new("^#{term_set}$", true)
153
- end
154
- data.municipalities.select do |m|
155
- Municipitaly2.sanitize_term(m.name) =~ regexp || (m.name_alt && Municipitaly2.sanitize_term(m.name_alt) =~ regexp)
156
- end
174
+ # regex per match "greedy" e per match esatto
175
+ exact_re = Regexp.new("^#{term_set}$", true)
176
+ search_re = greedy ? Regexp.new(term_set, true) : exact_re
177
+
178
+ # search results
179
+ matches = filter(data.municipalities, search_re: search_re)
180
+
181
+ # sorts results by relevance
182
+ matches.sort_by { |match| rank(match, term: term_set, exact_re: exact_re, greedy: greedy) }
157
183
  end
158
184
 
159
185
  # returns a +Municipitaly2::Municipality+ object from a <b>cadastrial
@@ -229,5 +255,39 @@ module Municipitaly2
229
255
  istats.include? m.province_istat
230
256
  end
231
257
  end
258
+
259
+ # filters municipalities/provinces (name, name_alt required)
260
+ def filter(list, search_re:)
261
+ list.select do |item|
262
+ name_s = Municipitaly2.sanitize_term(item.name)
263
+ alt_s = item.name_alt && Municipitaly2.sanitize_term(item.name_alt)
264
+ (name_s =~ search_re) || (alt_s && alt_s =~ search_re)
265
+ end
266
+ end
267
+
268
+ # rank municipalities/provinces (name, name_alt, population required)
269
+ def rank(match, term:, exact_re:, greedy: true)
270
+ name_s = Municipitaly2.sanitize_term(match.name)
271
+ alt_s = match.name_alt && Municipitaly2.sanitize_term(match.name_alt)
272
+ names_s = [name_s, alt_s].compact
273
+
274
+ exact_match = names_s.any? { |n| n =~ exact_re }
275
+ any_word_starts = names_s.any? { |n| n.split.any? { |w| w.start_with?(term) } }
276
+
277
+ # Order: 0 = exact, 2 = any word starts, 3 = contains
278
+ priority = if !greedy || exact_match
279
+ 0 # Exact match
280
+ # Disabled because it causes problems in some cases, like putting San Giuliano Milanese after Milazzo
281
+ # elsif names_s.any? { |s| s.start_with?(q) }
282
+ # 1 # Starts with the term
283
+ elsif any_word_starts
284
+ 2 # Any word starts with the term
285
+ else
286
+ 3 # Other (match inside any word)
287
+ end
288
+
289
+ # Priority, population (desc), name (asc)
290
+ [priority, -match.population.to_i, name_s]
291
+ end
232
292
  end
233
293
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Municipitaly2
4
4
  # :nodoc:
5
- VERSION = '2.0.2'
5
+ VERSION = '2.0.4'
6
6
  end
data/lib/municipitaly2.rb CHANGED
@@ -24,6 +24,6 @@ module Municipitaly2
24
24
  # example usage:
25
25
  # sanitized_term = Search.sanitize_term('Forlì Cesena')
26
26
  def self.sanitize_term(term) # :doc:
27
- term.strip.downcase.tr('àâçèéêìòôù', 'aaceeeioou').gsub(/[^a-z]/, '')
27
+ term.strip.downcase.tr('àâçèéêìòôù', 'aaceeeioou').gsub(/[^a-z ]/, '')
28
28
  end
29
29
  end
@@ -32,11 +32,5 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.required_ruby_version = '>= 3.0.0'
34
34
 
35
- spec.add_development_dependency 'bundler', '~> 2.5.11'
36
- spec.add_development_dependency 'rake', '~> 13.2.1'
37
- spec.add_development_dependency 'rspec', '~> 3.13'
38
- spec.add_development_dependency 'rubocop', '~> 1.64.1'
39
- spec.add_development_dependency 'simplecov', '~> 0.22.0'
40
-
41
- spec.add_dependency 'csv', '~> 3.3.0' # removed from stdlib in Ruby 3.4
35
+ spec.add_dependency 'csv', '~> 3.3.5' # removed from stdlib in Ruby 3.4
42
36
  end