eco-helpers 2.5.5 → 2.5.7
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 +27 -1
- data/eco-helpers.gemspec +1 -1
- data/lib/eco/api/session/config/tagtree.rb +28 -10
- data/lib/eco/api/session/config.rb +5 -5
- data/lib/eco/api/session.rb +1 -1
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_map.rb +66 -0
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_set.rb +95 -0
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +88 -0
- data/lib/eco/api/usecases/graphql/helpers/location.rb +1 -0
- data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +11 -7
- data/lib/eco/data/locations/node_level/cleaner.rb +7 -4
- data/lib/eco/data/locations/node_level/parsing.rb +11 -3
- data/lib/eco/data/locations/node_level.rb +11 -1
- data/lib/eco/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 712a817db8970559d9d45923531ff092edc4eed7a6f937a51251ab7510b21e48
|
4
|
+
data.tar.gz: c00d489419212cfcb52de588b5b066c789e558e5d38b508e3946a3ba90d1a774
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32e7c9cf3d1bb894e7402e7ee162cd823db5c79fe9853ac9a5d6856442b8b09334b1515e0fb61a87d301255f070a0567cf8424828b53db5e9b6cb831f0627159
|
7
|
+
data.tar.gz: e9db4bcaf310a3d77967497f05fb9bab8e8e76c2c328ba3c1a33a02d2c8df8cc730cde8f2534145d9d1d5774a88c83b5647151ee7cd0494babf7b031271a1c7f
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,38 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [2.5.
|
4
|
+
## [2.5.8] - 2023-08-xx
|
5
5
|
|
6
6
|
### Added
|
7
7
|
### Changed
|
8
8
|
### Fixed
|
9
9
|
|
10
|
+
## [2.5.7] - 2023-08-15
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- `Eco::API::Session::Config#tagtree_id=` allows to define a target structure id
|
14
|
+
- This is for `live` retrieval of tagtree on people sync processes
|
15
|
+
- It only makes sense if graphql credentials are configured
|
16
|
+
|
17
|
+
## [2.5.6] - 2023-08-14
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
- `Eco::API::Session::Config::Tagtree#live_tree` remove memmoize tree: it now always trigger a query to the back-end
|
21
|
+
- Better messaging to know what's going on.
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
- `Eco::API::Session#live_tree` was not forwarding target structure id `id`
|
25
|
+
- `Eco::Data::Locations::NodeLevel#override_lower_levels`
|
26
|
+
- By **default** should only override empty upper levels
|
27
|
+
- `Eco::Data::Locations::NodeLevel::Cleaner`
|
28
|
+
- `#tidy_nodes` when **gap** (merged parent) identified, `level` is still correct
|
29
|
+
- `Eco::Data::Locations::NodeLevel`
|
30
|
+
- `#nodes_from_csv` correctly identify parent with big gaps
|
31
|
+
- This fix ensures a correct normalization
|
32
|
+
- `Eco::API::UseCases::GraphQL::Samples::Location::Command::Result`
|
33
|
+
- **Batch remap tags** _built_ requires full path to keep from-filter specificity
|
34
|
+
- This change also wraps into a new class the remap tags table.
|
35
|
+
|
10
36
|
## [2.5.5] - 2023-08-03
|
11
37
|
|
12
38
|
### Added
|
data/eco-helpers.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_dependency 'ecoportal-api', '>= 0.9.4', '< 0.10'
|
34
34
|
spec.add_dependency 'ecoportal-api-v2', '>= 1.1.3', '< 1.2'
|
35
|
-
spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.
|
35
|
+
spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.10', '< 0.4'
|
36
36
|
spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
|
37
37
|
spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
|
38
38
|
spec.add_dependency 'dotenv', '>= 2.7.6', '< 3'
|
@@ -6,23 +6,26 @@ module Eco
|
|
6
6
|
class MissingTagtree < StandardError
|
7
7
|
end
|
8
8
|
|
9
|
-
attr_key :file
|
9
|
+
attr_key :file, :structure_id
|
10
10
|
|
11
11
|
# @param include_archived [Boolean] whether or not it should include archived nodes.
|
12
12
|
# @return [Eco::API::Organization::TagTree]
|
13
13
|
def scope_tree(enviro: nil, include_archived: true, raise_on_missing: true)
|
14
14
|
return @tagtree if instance_variable_defined?(:@tagtree) && @tagtree.enviro == enviro
|
15
|
-
if tree_file = self.file
|
16
|
-
if (tree = file_manager.load_json(tree_file)) && !tree.empty?
|
17
|
-
@tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
18
|
-
end
|
19
|
-
end
|
20
15
|
|
21
16
|
kargs = {
|
22
17
|
enviro: enviro,
|
23
18
|
includeArchivedNodes: include_archived
|
24
19
|
}
|
25
20
|
|
21
|
+
if tree_file = self.file
|
22
|
+
if (tree = file_manager.load_json(tree_file)) && !tree.empty?
|
23
|
+
@tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
24
|
+
end
|
25
|
+
elsif self.structure_id
|
26
|
+
kargs.merge(id: self.structure_id)
|
27
|
+
end
|
28
|
+
|
26
29
|
@tagtree ||= live_tree(**kargs).tap do |tree|
|
27
30
|
unless tree && !tree.empty?
|
28
31
|
msg = "Could not find a local or live locations structure."
|
@@ -34,7 +37,14 @@ module Eco
|
|
34
37
|
# Among all the locations structures it selects the one with more location nodes
|
35
38
|
# If `id` is provided, it only retrieves this locations structure.
|
36
39
|
def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
|
37
|
-
|
40
|
+
existing_cache = !!@live_tree
|
41
|
+
first_load = !existing_cache
|
42
|
+
|
43
|
+
target_change = existing_cache && id && @live_tree.id != id
|
44
|
+
enviro_change = existing_cache && enviro && @live_tree.enviro != enviro
|
45
|
+
|
46
|
+
switching_target = existing_cache && (target_change || enviro_change)
|
47
|
+
refresh_cache = existing_cache && !switching_target
|
38
48
|
|
39
49
|
kargs = {
|
40
50
|
enviro: enviro,
|
@@ -45,7 +55,6 @@ module Eco
|
|
45
55
|
args = { id: id }.merge(kargs)
|
46
56
|
@live_tree = live_tree_get(**args, &block)
|
47
57
|
else
|
48
|
-
kargs
|
49
58
|
trees = live_trees(**kargs, &block)
|
50
59
|
@live_tree = trees.reject do |tree|
|
51
60
|
tree.empty?
|
@@ -54,8 +63,16 @@ module Eco
|
|
54
63
|
end
|
55
64
|
end.tap do |tree|
|
56
65
|
if tree
|
57
|
-
msg = "
|
58
|
-
|
66
|
+
msg = "LIVE LOCATIONS Structure (#{tree.id}): '#{tree.name}' (#{tree.count} nodes)"
|
67
|
+
if first_load
|
68
|
+
session_logger.info("Using #{msg}")
|
69
|
+
elsif switching_target
|
70
|
+
session_logger.info("Switched to #{msg}")
|
71
|
+
else # refresh_cache
|
72
|
+
session_logger.debug("Reloading #{msg}")
|
73
|
+
end
|
74
|
+
else
|
75
|
+
session_logger.info "Could not retrive live tree (#{id})"
|
59
76
|
end
|
60
77
|
end
|
61
78
|
end
|
@@ -74,6 +91,7 @@ module Eco
|
|
74
91
|
}.merge(kargs)
|
75
92
|
|
76
93
|
return nil unless tree = graphql.currentOrganization.locationStructure(**kargs, &block)
|
94
|
+
|
77
95
|
args = { enviro: enviro, id: tree.id, name: tree.name }
|
78
96
|
Eco::API::Organization::TagTree.new(tree.treeify, **args)
|
79
97
|
end
|
@@ -234,6 +234,10 @@ module Eco
|
|
234
234
|
tagtree_config.file = file
|
235
235
|
end
|
236
236
|
|
237
|
+
def tagtree_id=(value)
|
238
|
+
tagtree_config.structure_id = value
|
239
|
+
end
|
240
|
+
|
237
241
|
# It uses the `tagtree.json` file and in its absence, if `graphql` enabled, the largest `life_tagtree`
|
238
242
|
# @note it does NOT include archived nodes by default.
|
239
243
|
# - This is for legacy (most usecases don't)
|
@@ -250,11 +254,7 @@ module Eco
|
|
250
254
|
# @note it requires graphql connection configuration parameters
|
251
255
|
# @return [Eco::API::Organization::TagTree]
|
252
256
|
def live_tree(id: nil, enviro: nil, **kargs, &block)
|
253
|
-
|
254
|
-
tagtree_config.live_tree_get(id: id, enviro: enviro, **kargs, &block)
|
255
|
-
else
|
256
|
-
tagtree_config.live_tree(enviro: enviro, **kargs, &block)
|
257
|
-
end
|
257
|
+
tagtree_config.live_tree(id: id, enviro: enviro, **kargs, &block)
|
258
258
|
end
|
259
259
|
|
260
260
|
# @return [Eco::API::Organization::PolicyGroups]
|
data/lib/eco/api/session.rb
CHANGED
@@ -46,7 +46,7 @@ module Eco
|
|
46
46
|
|
47
47
|
# @see Eco::API::Session::Config#live_tree
|
48
48
|
def live_tree(id: nil, include_archived: false, **kargs, &block)
|
49
|
-
config.live_tree(id:
|
49
|
+
config.live_tree(id: id, include_archived: include_archived, enviro: enviro, **kargs, &block)
|
50
50
|
end
|
51
51
|
|
52
52
|
# @see Eco::API::Session::Config#schemas
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Eco::API::UseCases::GraphQL::Helpers::Location
|
2
|
+
class TagsRemap
|
3
|
+
class TagsMap
|
4
|
+
attr_reader :from, :to
|
5
|
+
|
6
|
+
def initialize(from, to)
|
7
|
+
@from = TagsSet.new(from)
|
8
|
+
@to = TagsSet.new(to)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_csv_row
|
12
|
+
[from.to_s, to.to_s]
|
13
|
+
end
|
14
|
+
|
15
|
+
# @note to create a stable sort we assume `self` is a sorted element
|
16
|
+
def <=>(other)
|
17
|
+
return -1 if maps? && !other.maps?
|
18
|
+
return 1 if !maps? && other.maps?
|
19
|
+
return -1 if rename? && other.move?
|
20
|
+
return 1 if move? && other.rename?
|
21
|
+
return -1 if rename? && other.rename?
|
22
|
+
# both are being moved (specific/long mappings first)
|
23
|
+
return 1 if from.subset_of?(other.from)
|
24
|
+
return -1 if from.superset_of?(other.from)
|
25
|
+
return -1 if (from & other.from).empty?
|
26
|
+
return -1 if from.length >= other.from.length
|
27
|
+
return 1 if from.length < other.from.length
|
28
|
+
-1
|
29
|
+
end
|
30
|
+
|
31
|
+
# @note to create a stable sort we assume `self` is a sorted element
|
32
|
+
def goes_before?(other)
|
33
|
+
(self <=> other) == -1
|
34
|
+
end
|
35
|
+
|
36
|
+
# @note to create a stable sort we assume `self` is a sorted element
|
37
|
+
def goes_after?(other)
|
38
|
+
(self <=> other) == 1
|
39
|
+
end
|
40
|
+
|
41
|
+
def both?(&block)
|
42
|
+
[from, to].all?(&block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def any?(&block)
|
46
|
+
[from, to].any?(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def maps?
|
50
|
+
return false if any?(&:empty?)
|
51
|
+
return false if from == to
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
def rename?
|
56
|
+
return false unless maps?
|
57
|
+
both? {|set| set.length == 1}
|
58
|
+
end
|
59
|
+
|
60
|
+
def move?
|
61
|
+
return false unless maps?
|
62
|
+
!rename?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Eco::API::UseCases::GraphQL::Helpers::Location
|
2
|
+
class TagsRemap
|
3
|
+
class TagsSet
|
4
|
+
class << self
|
5
|
+
def attr_compare(*attrs)
|
6
|
+
attrs.each do |attr|
|
7
|
+
meth = "#{attr}".to_sym
|
8
|
+
define_method meth do |value|
|
9
|
+
set.send(meth, to_set(value))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
def attr_operate(*attrs)
|
14
|
+
attrs.each do |attr|
|
15
|
+
meth = "#{attr}".to_sym
|
16
|
+
define_method meth do |value|
|
17
|
+
self.class.new(set.send(meth, to_set(value)))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
COMPARE_METHODS = %i[< <= == > >=].freeze
|
24
|
+
OPERATE_METHIDS = %i[& + - ^].freeze
|
25
|
+
|
26
|
+
attr_compare *COMPARE_METHODS
|
27
|
+
attr_operate *OPERATE_METHIDS
|
28
|
+
|
29
|
+
attr_reader :tags, :set
|
30
|
+
|
31
|
+
def initialize(tags)
|
32
|
+
@ini_tags = value_to_a(tags)
|
33
|
+
@set = to_set(tags)
|
34
|
+
end
|
35
|
+
|
36
|
+
def length
|
37
|
+
set.length
|
38
|
+
end
|
39
|
+
|
40
|
+
def tags
|
41
|
+
ini_tags.compact.map(&:upcase)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_a
|
45
|
+
tags
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
tags.join('|')
|
50
|
+
end
|
51
|
+
|
52
|
+
def empty?
|
53
|
+
set.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def include?(value)
|
57
|
+
value = value.to_s.strip
|
58
|
+
return false if value.empty?
|
59
|
+
set.include?(value)
|
60
|
+
end
|
61
|
+
|
62
|
+
def include_any?(value)
|
63
|
+
value.to_a.any? {|tag| self.include?(tag)}
|
64
|
+
end
|
65
|
+
|
66
|
+
def subset_of?(value)
|
67
|
+
set.subset?(to_set(value))
|
68
|
+
end
|
69
|
+
|
70
|
+
def superset_of?(value)
|
71
|
+
set.superset?(to_set(value))
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def ini_tags
|
77
|
+
@ini_tags
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def value_to_a(value)
|
83
|
+
return value.ini_tags.dup if value.is_a?(self.class)
|
84
|
+
return value.dup if value.is_a?(Array)
|
85
|
+
return value.to_a if value.is_a?(Set)
|
86
|
+
raise ArgumentError, "Expecting #{self.class}, Set or Array. Given: #{value.class}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_set(value)
|
90
|
+
values = value_to_a(value)
|
91
|
+
Set.new.merge(values.compact.map(&:upcase))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Eco::API::UseCases::GraphQL::Helpers::Location
|
2
|
+
class TagsRemap
|
3
|
+
def self.correct_pair?(pair)
|
4
|
+
correct_pair = pair.is_a?(Array)
|
5
|
+
correct_pair && pair.length == 2
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :src_maps
|
9
|
+
attr_reader :from, :to
|
10
|
+
|
11
|
+
def each(&block)
|
12
|
+
return to_enum(:each) unless block
|
13
|
+
src_maps.each(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_csv(filename)
|
17
|
+
CSV.open(filename, "w") do |fd|
|
18
|
+
fd << ["src_tags", "dst_tags"]
|
19
|
+
each do |tags_map|
|
20
|
+
fd << tags_map.to_csv_row
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"".tap do |str|
|
27
|
+
each.map do |tags_map|
|
28
|
+
from, to = tags_map.to_csv_row
|
29
|
+
str << " • from: #{from}\n"
|
30
|
+
str << " • to: #{to}\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sorts the maps in the correct order
|
36
|
+
# @note it assumes that:
|
37
|
+
# 1. renames go before moving nodes
|
38
|
+
# 2. moving nodes does not include a rename
|
39
|
+
# 3. moving nodes includes all the path on both, source and destination tags
|
40
|
+
# @note DISABLED: the order should be that in what the operations happened!
|
41
|
+
# An important thing is that all the path is always included in the mappings.
|
42
|
+
# * The only way that this would work is to apply upper (previous) tags_maps
|
43
|
+
# to subsequent ones. But the order should still be kept!
|
44
|
+
# def sorted_maps
|
45
|
+
# [].tap do |sorted|
|
46
|
+
# src_maps.each do |curr_map|
|
47
|
+
# pos = nil
|
48
|
+
# sorted.each_with_index.reverse_each do |prev_map, idx|
|
49
|
+
# pos = idx + 1 if prev_map.goes_before?(curr_map)
|
50
|
+
# break if pos
|
51
|
+
# end
|
52
|
+
# sorted.insert(pos || 0, curr_map)
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
|
57
|
+
def empty?
|
58
|
+
src_maps.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
def <<(pair)
|
62
|
+
raise ArgumentError, "Expecting pair of Array in Array. Given: #{pair}" unless self.class.correct_pair?(pair)
|
63
|
+
add(*pair)
|
64
|
+
end
|
65
|
+
|
66
|
+
def add(from, to)
|
67
|
+
raise ArgumentError, "Expecting Array. Given: #{from.class}" unless from.is_a?(Array)
|
68
|
+
raise ArgumentError, "Expecting Array. Given: #{to.class}" unless to.is_a?(Array)
|
69
|
+
new_src TagsMap.new(from, to)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
attr_reader :src_maps
|
75
|
+
attr_reader :from_key, :to_key
|
76
|
+
|
77
|
+
def new_src(tags_map)
|
78
|
+
src_maps << tags_map
|
79
|
+
end
|
80
|
+
|
81
|
+
def src_maps
|
82
|
+
@src_maps ||= []
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
require_relative 'tags_remap/tags_map'
|
88
|
+
require_relative 'tags_remap/tags_set'
|
@@ -18,6 +18,10 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
18
18
|
Eco::API::UseCases::GraphQL::Helpers::Location::Command::Results
|
19
19
|
end
|
20
20
|
|
21
|
+
def tags_remap_class
|
22
|
+
Eco::API::UseCases::GraphQL::Helpers::Location::TagsRemap
|
23
|
+
end
|
24
|
+
|
21
25
|
# Capture results
|
22
26
|
def results
|
23
27
|
@results ||= {}
|
@@ -26,7 +30,7 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
26
30
|
# The maps of tags to be used in batch remap tags
|
27
31
|
# @return [Array<Array>] source/destination pairs of `Array<String>`
|
28
32
|
def tags_remap_table
|
29
|
-
@tags_remap_table ||=
|
33
|
+
@tags_remap_table ||= tags_remap_class.new
|
30
34
|
end
|
31
35
|
|
32
36
|
# Errors tracking/logging.
|
@@ -87,17 +91,17 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
87
91
|
node_id, parent_id = result.command_input_data.values_at(:nodeId, :parentId)
|
88
92
|
prev_node = previous_tree.node(node_id)
|
89
93
|
curr_node = current_tree.node(node_id)
|
90
|
-
|
91
|
-
|
94
|
+
prev_path = prev_node.path.reverse
|
95
|
+
new_path = curr_node.path.reverse
|
92
96
|
|
93
97
|
curr_parent = curr_node.parent.top? ? nil : curr_node.parent
|
94
98
|
unless curr_parent&.id == parent_id
|
95
|
-
msg = "Node '#{node_id}' was moved
|
99
|
+
msg = "Node '#{node_id}' was moved under '#{parent_id}', "
|
96
100
|
msg << "but in current structure has parent '#{curr_parent&.id}'"
|
97
101
|
log(:warn) { msg }
|
98
102
|
end
|
99
103
|
|
100
|
-
tags_remap_table << [
|
104
|
+
tags_remap_table << [prev_path, new_path]
|
101
105
|
end
|
102
106
|
end
|
103
107
|
end
|
@@ -108,8 +112,8 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
108
112
|
timestamp_file(filename).tap do |file|
|
109
113
|
CSV.open(file, 'w') do |csv|
|
110
114
|
csv << ["source_tags", "destination_tags"]
|
111
|
-
tags_remap_table.each do |
|
112
|
-
csv <<
|
115
|
+
tags_remap_table.each do |tags_remap|
|
116
|
+
csv << tags_remap.to_csv_row
|
113
117
|
end
|
114
118
|
end
|
115
119
|
log(:info) { "Generated file '#{file}'" }
|
@@ -28,10 +28,11 @@ class Eco::Data::Locations::NodeLevel
|
|
28
28
|
msg << "\n Adding missing upper level(s): " + missing_nodes.map(&:raw_tag).pretty_inspect
|
29
29
|
log(:info) { msg }
|
30
30
|
|
31
|
-
|
32
|
-
#
|
33
|
-
|
34
|
-
|
31
|
+
# The very top missing node (first in list) should be checked against prev_level
|
32
|
+
# alongside any descendants in missing_nodes (when gap 2+)
|
33
|
+
tidied_nodes = tidy_nodes(missing_nodes, prev_level: prev_level, main: false)
|
34
|
+
out.push(*tidied_nodes)
|
35
|
+
#level = prev_level + 1 # <= we are actually on level and filled in the gaps
|
35
36
|
end
|
36
37
|
out << node
|
37
38
|
done_ids << node_id
|
@@ -44,6 +45,8 @@ class Eco::Data::Locations::NodeLevel
|
|
44
45
|
end
|
45
46
|
|
46
47
|
# Sets the `parentId` property.
|
48
|
+
# Although with normalized nodes parents are self-contained
|
49
|
+
# we use this method
|
47
50
|
def fill_in_parents(nodes)
|
48
51
|
nodes.tap do |nodes|
|
49
52
|
prev_nodes = empty_level_tracker_hash(11)
|
@@ -31,7 +31,13 @@ class Eco::Data::Locations::NodeLevel
|
|
31
31
|
prev_level = nil
|
32
32
|
prev_node = nil
|
33
33
|
prev_nodes = empty_level_tracker_hash(11)
|
34
|
-
|
34
|
+
prev_node_get = proc do |raw_level|
|
35
|
+
prev = nil
|
36
|
+
(1..raw_level).to_a.reverse.each do |lev|
|
37
|
+
prev ||= prev_nodes[lev]
|
38
|
+
end
|
39
|
+
prev
|
40
|
+
end
|
35
41
|
# Convert to Eco::CSV::Table for a fresh start
|
36
42
|
csv = Eco::CSV.parse(csv.to_csv).nil_blank_cells.add_index_column(:row_num)
|
37
43
|
|
@@ -42,10 +48,12 @@ class Eco::Data::Locations::NodeLevel
|
|
42
48
|
|
43
49
|
# If node is nested in prev_node or is a sibling thereof
|
44
50
|
if prev_node.raw_level <= node.raw_level
|
45
|
-
# Make sure
|
51
|
+
# Make sure upper level tags are there (including parent)
|
52
|
+
# This normalizes input to all upper level tags always filled in
|
53
|
+
# which allows to node#actual_level to work
|
46
54
|
node.set_high_levels(prev_node)
|
47
55
|
else
|
48
|
-
if parent_node =
|
56
|
+
if parent_node = prev_node_get[node.raw_level - 1]
|
49
57
|
node.set_high_levels(parent_node)
|
50
58
|
elsif node.raw_level == 1
|
51
59
|
# It is expected not to have parent (as it's top level tag)
|
@@ -47,6 +47,13 @@ module Eco::Data::Locations
|
|
47
47
|
tags_array.index(raw_tag) + 1
|
48
48
|
end
|
49
49
|
|
50
|
+
def raw_prev_empty_level
|
51
|
+
tags_array[0..raw_level-1].each_with_index.reverse_each do |value, idx|
|
52
|
+
return idx + 1 unless value
|
53
|
+
end
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
50
57
|
def tag_idx
|
51
58
|
tags_array.index(raw_tag)
|
52
59
|
end
|
@@ -106,6 +113,7 @@ module Eco::Data::Locations
|
|
106
113
|
true
|
107
114
|
end
|
108
115
|
|
116
|
+
# Cleanses deepest tags
|
109
117
|
def override_upper_levels(src_tags_array, from_level: self.raw_level + 1)
|
110
118
|
target_lev = Array(from_level..tag_attrs_count)
|
111
119
|
target_tags = src_tags_array[level_to_idx(from_level)..level_to_idx(tag_attrs_count)]
|
@@ -115,7 +123,9 @@ module Eco::Data::Locations
|
|
115
123
|
self
|
116
124
|
end
|
117
125
|
|
118
|
-
|
126
|
+
# Ensures parent is among the upper level tags
|
127
|
+
def override_lower_levels(src_tags_array, to_level: self.raw_prev_empty_level)
|
128
|
+
return self unless to_level
|
119
129
|
target_lev = Array(1..to_level)
|
120
130
|
target_tags = src_tags_array[level_to_idx(1)..level_to_idx(to_level)]
|
121
131
|
target_lev.zip(target_tags).each do |(n, tag)|
|
data/lib/eco/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eco-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
@@ -156,7 +156,7 @@ dependencies:
|
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0.3.
|
159
|
+
version: 0.3.10
|
160
160
|
- - "<"
|
161
161
|
- !ruby/object:Gem::Version
|
162
162
|
version: '0.4'
|
@@ -166,7 +166,7 @@ dependencies:
|
|
166
166
|
requirements:
|
167
167
|
- - ">="
|
168
168
|
- !ruby/object:Gem::Version
|
169
|
-
version: 0.3.
|
169
|
+
version: 0.3.10
|
170
170
|
- - "<"
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '0.4'
|
@@ -598,6 +598,9 @@ files:
|
|
598
598
|
- lib/eco/api/usecases/graphql/helpers/location/command.rb
|
599
599
|
- lib/eco/api/usecases/graphql/helpers/location/command/result.rb
|
600
600
|
- lib/eco/api/usecases/graphql/helpers/location/command/results.rb
|
601
|
+
- lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb
|
602
|
+
- lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_map.rb
|
603
|
+
- lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_set.rb
|
601
604
|
- lib/eco/api/usecases/graphql/samples.rb
|
602
605
|
- lib/eco/api/usecases/graphql/samples/location.rb
|
603
606
|
- lib/eco/api/usecases/graphql/samples/location/command.rb
|