eco-helpers 3.2.5 → 3.2.6
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/CHANGELOG.md +22 -0
- data/lib/eco/api/organization/node_classifications.rb +2 -1
- data/lib/eco/api/organization/tag_tree.rb +6 -11
- data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +23 -15
- data/lib/eco/data/locations/node_base/tag_validations.rb +8 -3
- data/lib/eco/data/locations/node_base/treeify.rb +3 -0
- data/lib/eco/data/locations/node_base.rb +2 -1
- data/lib/eco/data/locations/node_level/parsing.rb +4 -1
- data/lib/eco/data/locations/node_level.rb +9 -5
- data/lib/eco/data/locations/node_plain/parsing.rb +4 -1
- data/lib/eco/data/locations/node_plain.rb +12 -11
- data/lib/eco/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bb545e3154c1a65a993a24b6eeab4eebbe125e95492bc2b6961fee0a708a80f
|
4
|
+
data.tar.gz: dc6bd380cd757b5218fadf264c64ef8a61b767916514aebac63fae0739c5153c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9852caf3f9f2dcdcbcbe4d17e325c566e63b3724b92349668e35fb4839aea5b7879b3b080b031868495b40c5bb09a9fc9d43c0b5cd4e9dbc298ec0f25d867d8
|
7
|
+
data.tar.gz: 5941ec298de1bff8205be578bcefaed0602dfea76ceee47a00497b28ff973a293553927d1ce96f0617abe0886c5fa4f5810678e69c3fab2673fd35c6df88dac3
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [3.2.7] - 2025-09-xx
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
## [3.2.6] - 2025-09-05
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- **Improvement**: classifications conversion to ignore ending `s` (plurals).
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
- Node `id` and `parent_id` **upcase** in `NodePlain` (**case insensitive**)
|
22
|
+
- It was failing to pair children with their parent (on input files).
|
23
|
+
- **remove** _classifications treatment_ on `Organization::TagTree` and `NodePlain`
|
24
|
+
- This was a working around due to not using `as_nodes_json` as a **common** converter between `live_tree` and `file_tree` (which was fixed in a previous release).
|
25
|
+
- `as_nodes_json` already does the call to `node_parser_block`, which does the conversion of the **classifications**
|
26
|
+
|
5
27
|
## [3.2.6] - 2025-09-xx
|
6
28
|
|
7
29
|
### Added
|
@@ -66,10 +66,11 @@ module Eco
|
|
66
66
|
treat_classication(val)
|
67
67
|
end
|
68
68
|
|
69
|
+
# Enhances the lookup
|
69
70
|
def treat_classication(value)
|
70
71
|
return value unless value.is_a?(String)
|
71
72
|
|
72
|
-
value.strip.gsub(/\W+/, '')
|
73
|
+
value.strip.downcase.gsub(/s(?:\W|$)/, '').gsub(/\W+/, '-')
|
73
74
|
end
|
74
75
|
|
75
76
|
def init_caches
|
@@ -211,9 +211,9 @@ module Eco
|
|
211
211
|
&block
|
212
212
|
)
|
213
213
|
max_depth ||= total_depth
|
214
|
-
return
|
215
|
-
return []
|
216
|
-
return
|
214
|
+
return if max_depth < depth
|
215
|
+
return [] if top? && !include_children
|
216
|
+
return if archived? && !include_archived
|
217
217
|
|
218
218
|
if include_children
|
219
219
|
child_nodes = nodes
|
@@ -441,14 +441,13 @@ module Eco
|
|
441
441
|
|
442
442
|
def init_node
|
443
443
|
return if source.is_a?(Array)
|
444
|
+
|
444
445
|
@id = source.values_at('tag', 'id').compact.first&.upcase
|
445
446
|
@name = source['name']
|
446
447
|
@weight = source['weight']
|
447
448
|
@archived = as_boolean(source['archived'])
|
448
449
|
@archived_token = source['archived_token']
|
449
|
-
@classifications = into_a(source['classifications'])
|
450
|
-
treat_classication(value)
|
451
|
-
end
|
450
|
+
@classifications = into_a(source['classifications'])
|
452
451
|
@classification_names = into_a(source['classification_names'])
|
453
452
|
@raw_nodes = source['nodes'] || []
|
454
453
|
end
|
@@ -491,11 +490,6 @@ module Eco
|
|
491
490
|
[tnodes, ddepth]
|
492
491
|
end
|
493
492
|
|
494
|
-
def treat_classication(value)
|
495
|
-
return value unless value.is_a?(String)
|
496
|
-
value.strip.gsub(/\W+/, '').downcase
|
497
|
-
end
|
498
|
-
|
499
493
|
# Helper to convert to array
|
500
494
|
def into_a(value)
|
501
495
|
if value.is_a?(String)
|
@@ -510,6 +504,7 @@ module Eco
|
|
510
504
|
return true if value == true
|
511
505
|
return false if value.to_s.strip.empty?
|
512
506
|
return true if %w[yes x true].include?(value.downcase)
|
507
|
+
|
513
508
|
false
|
514
509
|
end
|
515
510
|
end
|
@@ -5,39 +5,46 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
|
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
+
def to_classification_ids(values)
|
9
|
+
values = [values].flatten unless values.is_a?(Array)
|
10
|
+
|
11
|
+
values = values.compact.map {|val| val.split('|')}.flatten
|
12
|
+
values.compact.map {|val| to_classification(val)}.compact.uniq
|
13
|
+
end
|
14
|
+
|
8
15
|
# @note
|
9
16
|
# 1. It returns `nil` unless there are classifications defined
|
10
17
|
# 2. If the value is wrong, it warns and returns `nil`
|
11
18
|
def to_classification(value)
|
12
|
-
return
|
19
|
+
return unless node_classifications?
|
13
20
|
|
14
|
-
|
21
|
+
msg = "Expecting a single element. Given: #{value.class}"
|
22
|
+
raise ArgumentError, msg if value.is_a?(Enumerator)
|
15
23
|
|
16
|
-
return
|
24
|
+
return unless value.is_a?(String)
|
17
25
|
|
18
26
|
node_classifications.to_id(value).tap do |type|
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
27
|
+
next if type
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
values = values.compact.map {|val| val.split('|')}.flatten
|
26
|
-
values.compact.map {|val| to_classification(val)}.compact.uniq
|
29
|
+
unknown_classification!(value)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
# @note
|
30
34
|
# 1. It returns `nil` unless there are classifications defined
|
31
35
|
# 2. If the value is wrong, it warns and returns `nil`
|
32
36
|
def to_classification_name(value)
|
33
|
-
return
|
37
|
+
return unless node_classifications?
|
34
38
|
|
35
|
-
|
39
|
+
msg = "Expecting a single element. Given: #{value.class}"
|
40
|
+
raise ArgumentError, msg if value.is_a?(Enumerator)
|
36
41
|
|
37
|
-
return
|
42
|
+
return unless value.is_a?(String)
|
38
43
|
|
39
44
|
node_classifications.to_name(value) do |name|
|
40
|
-
|
45
|
+
next unless name
|
46
|
+
|
47
|
+
unknown_classification!(value)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -49,10 +56,11 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
|
|
49
56
|
@node_classifications ||= session.node_classifications
|
50
57
|
end
|
51
58
|
|
52
|
-
def
|
59
|
+
def unknown_classification!(value)
|
53
60
|
return if unknown_classifications.include?(value)
|
54
61
|
|
55
62
|
unknown_classifications << value
|
63
|
+
|
56
64
|
log(:warn) {
|
57
65
|
"Unknown location node classification '#{value}'"
|
58
66
|
}
|
@@ -2,7 +2,7 @@ module Eco::Data::Locations::NodeBase
|
|
2
2
|
module TagValidations
|
3
3
|
include Eco::Language::AuxiliarLogger
|
4
4
|
|
5
|
-
ALLOWED_CHARACTERS = "A-Za-z0-9 &_'
|
5
|
+
ALLOWED_CHARACTERS = "A-Za-z0-9 &_'/.-".freeze
|
6
6
|
VALID_TAG_REGEX = /^[#{ALLOWED_CHARACTERS}]+$/
|
7
7
|
INVALID_TAG_REGEX = /[^#{ALLOWED_CHARACTERS}]+/
|
8
8
|
VALID_TAG_CHARS = /[#{ALLOWED_CHARACTERS}]+/
|
@@ -11,9 +11,11 @@ module Eco::Data::Locations::NodeBase
|
|
11
11
|
def clean_id(str, notify: true, ref: '')
|
12
12
|
blanks_x2 = has_double_blanks?(str) # dubocop:disable Naming/VariableNumber
|
13
13
|
partial = replace_not_allowed(str)
|
14
|
+
|
14
15
|
remove_double_blanks(partial).tap do |result|
|
15
16
|
next unless notify
|
16
17
|
next if invalid_warned?(str)
|
18
|
+
|
17
19
|
if partial != str
|
18
20
|
invalid_chars = identify_invalid_characters(str)
|
19
21
|
log(:warn) {
|
@@ -24,6 +26,7 @@ module Eco::Data::Locations::NodeBase
|
|
24
26
|
"* #{ref}Double blanks removed: '#{str}' :_converted_>> '#{result}'"
|
25
27
|
}
|
26
28
|
end
|
29
|
+
|
27
30
|
invalid_warned!(str)
|
28
31
|
end
|
29
32
|
end
|
@@ -46,13 +49,15 @@ module Eco::Data::Locations::NodeBase
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def remove_double_blanks(str)
|
49
|
-
return
|
52
|
+
return if str.nil?
|
53
|
+
|
50
54
|
str.gsub(DOUBLE_BLANKS, ' ').strip
|
51
55
|
end
|
52
56
|
|
53
57
|
def replace_not_allowed(str)
|
54
|
-
return
|
58
|
+
return if str.nil?
|
55
59
|
return str if str.match(VALID_TAG_REGEX)
|
60
|
+
|
56
61
|
str.gsub(INVALID_TAG_REGEX, ' ')
|
57
62
|
end
|
58
63
|
|
@@ -28,10 +28,12 @@ module Eco::Data::Locations::NodeBase
|
|
28
28
|
# @return [Array<Hash>] a hierarchical tree of nested Hashes via `nodes` key.
|
29
29
|
def treeify(nodes, skipped: [], unlinked_trees: [], &block)
|
30
30
|
return [] if nodes.empty?
|
31
|
+
|
31
32
|
block ||= nodes.first.class.serializer
|
32
33
|
done_ids = {}
|
33
34
|
warns = []
|
34
35
|
parents = parents_hash(nodes)
|
36
|
+
|
35
37
|
get_children(
|
36
38
|
nil, parents,
|
37
39
|
done_ids: done_ids, skipped: skipped,
|
@@ -43,6 +45,7 @@ module Eco::Data::Locations::NodeBase
|
|
43
45
|
skipped: skipped, unlinked_trees: unlinked_trees,
|
44
46
|
warns: warns, &block
|
45
47
|
)
|
48
|
+
|
46
49
|
log(:warn) { warns.join("\n") } unless warns.empty?
|
47
50
|
end
|
48
51
|
end
|
@@ -23,7 +23,7 @@ module Eco::Data::Locations
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def attr?(sym)
|
26
|
-
!attr(sym).to_s.strip.empty?
|
26
|
+
!attr(sym).to_s.strip.empty? # rubocop:disable Style/Attr
|
27
27
|
end
|
28
28
|
|
29
29
|
def set_attrs(**kargs)
|
@@ -57,6 +57,7 @@ module Eco::Data::Locations
|
|
57
57
|
|
58
58
|
def slice(*attrs)
|
59
59
|
return {} if attrs.empty?
|
60
|
+
|
60
61
|
to_h(*attrs)
|
61
62
|
end
|
62
63
|
end
|
@@ -17,6 +17,7 @@ class Eco::Data::Locations::NodeLevel
|
|
17
17
|
# @return [Boolean] whether or not it's worthy trying to parse with `NodeLevel`.
|
18
18
|
def csv_matches_format?(csv)
|
19
19
|
return false unless csv.is_a?(::CSV::Table)
|
20
|
+
|
20
21
|
!Eco::Data::Locations::NodePlain.csv_matches_format?(csv)
|
21
22
|
end
|
22
23
|
|
@@ -26,7 +27,8 @@ class Eco::Data::Locations::NodeLevel
|
|
26
27
|
# @param `csv` [CSV::Table]
|
27
28
|
# @return [Array<NodeLevel>]
|
28
29
|
def nodes_from_csv(csv)
|
29
|
-
|
30
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
31
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
30
32
|
|
31
33
|
possible_classifications = csv.headers
|
32
34
|
|
@@ -52,6 +54,7 @@ class Eco::Data::Locations::NodeLevel
|
|
52
54
|
|
53
55
|
prev_node = node
|
54
56
|
end
|
57
|
+
|
55
58
|
tidy_nodes(nodes)
|
56
59
|
end
|
57
60
|
end
|
@@ -36,15 +36,19 @@ module Eco::Data::Locations
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# In node level the parent id is set via parsing
|
39
|
-
|
40
|
-
alias_method :
|
41
|
-
|
39
|
+
attr_writer :parent_id
|
40
|
+
alias_method :parentId=, :parent_id= # rubocop:disable Naming/MethodName
|
41
|
+
|
42
|
+
def parent_id
|
43
|
+
@parent_id&.upcase
|
44
|
+
end
|
45
|
+
alias_method :parentId, :parent_id # rubocop:disable Naming/MethodName
|
42
46
|
|
43
47
|
def id
|
44
48
|
tag.upcase
|
45
49
|
end
|
46
|
-
alias_method :
|
47
|
-
alias_method :
|
50
|
+
alias_method :node_id, :id
|
51
|
+
alias_method :nodeId, :id # rubocop:disable Naming/MethodName
|
48
52
|
|
49
53
|
def name
|
50
54
|
tag
|
@@ -16,6 +16,7 @@ class Eco::Data::Locations::NodePlain
|
|
16
16
|
# @return [Boolean] whether or not it's worthy trying to parse with `NodePlain`.
|
17
17
|
def csv_matches_format?(csv)
|
18
18
|
return false unless csv.is_a?(::CSV::Table)
|
19
|
+
|
19
20
|
(basic_headers & csv.headers) == basic_headers
|
20
21
|
end
|
21
22
|
|
@@ -23,7 +24,9 @@ class Eco::Data::Locations::NodePlain
|
|
23
24
|
# @param `csv` [CSV::Table] with specific headers
|
24
25
|
# @return [Array<NodePlain>]
|
25
26
|
def nodes_from_csv(csv)
|
26
|
-
|
27
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
28
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
29
|
+
|
27
30
|
# Convert to Eco::CSV::Table for a fresh start
|
28
31
|
csv = Eco::CSV.parse(csv.to_csv).nil_blank_cells.add_index_column(:row_num)
|
29
32
|
headers = node_class::ALL_ATTRS.map(&:to_s)
|
@@ -22,7 +22,10 @@ module Eco::Data::Locations
|
|
22
22
|
PROP_ATTRS = (ALL_ATTRS - ADDITIONAL_ATTRS).freeze
|
23
23
|
|
24
24
|
def id
|
25
|
-
clean_id(
|
25
|
+
clean_id(
|
26
|
+
super,
|
27
|
+
ref: "(Row: #{row_num}) "
|
28
|
+
)&.upcase
|
26
29
|
end
|
27
30
|
# backwards compatibility
|
28
31
|
alias_method :tag, :id
|
@@ -32,9 +35,13 @@ module Eco::Data::Locations
|
|
32
35
|
end
|
33
36
|
|
34
37
|
def parent_id
|
35
|
-
clean_id(
|
38
|
+
clean_id(
|
39
|
+
super,
|
40
|
+
notify: false,
|
41
|
+
ref: "(Row: #{row_num} - parent_id) "
|
42
|
+
)&.upcase
|
36
43
|
end
|
37
|
-
alias_method :parentId, :parent_id
|
44
|
+
alias_method :parentId, :parent_id # rubocop:disable Naming/MethodName
|
38
45
|
|
39
46
|
def archived
|
40
47
|
value = super
|
@@ -42,13 +49,12 @@ module Eco::Data::Locations
|
|
42
49
|
return true if value == true
|
43
50
|
return false if value.to_s.strip.empty?
|
44
51
|
return true if %w[yes x true].include?(value.downcase)
|
52
|
+
|
45
53
|
false
|
46
54
|
end
|
47
55
|
|
48
56
|
def classifications
|
49
|
-
into_a(super)
|
50
|
-
treat_classication(value)
|
51
|
-
end
|
57
|
+
into_a(super)
|
52
58
|
end
|
53
59
|
|
54
60
|
def classification_names
|
@@ -68,11 +74,6 @@ module Eco::Data::Locations
|
|
68
74
|
|
69
75
|
private
|
70
76
|
|
71
|
-
def treat_classication(value)
|
72
|
-
return value unless value.is_a?(String)
|
73
|
-
value.strip.gsub(/\W+/, '').downcase
|
74
|
-
end
|
75
|
-
|
76
77
|
# Helper to convert to array
|
77
78
|
def into_a(value)
|
78
79
|
if value.is_a?(String)
|
data/lib/eco/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eco-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|