eco-helpers 2.1.11 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -1
- data/eco-helpers.gemspec +2 -2
- data/lib/eco/api/common/people/person_parser.rb +1 -1
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +11 -1
- data/lib/eco/api/organization/tag_tree.rb +27 -17
- data/lib/eco/api/session/batch/errors.rb +1 -2
- data/lib/eco/api/session/config/base_config.rb +28 -2
- data/lib/eco/api/session/config/files.rb +1 -7
- data/lib/eco/api/session/config/logger.rb +3 -38
- data/lib/eco/api/session/config/mailer.rb +3 -60
- data/lib/eco/api/session/config/people.rb +4 -26
- data/lib/eco/api/session/config/s3_storage.rb +3 -42
- data/lib/eco/api/session/config/sftp.rb +3 -48
- data/lib/eco/api/session/config/tagtree.rb +48 -0
- data/lib/eco/api/session/config.rb +11 -19
- data/lib/eco/api/usecases/default_cases/csv_to_tree_case/helper.rb +90 -0
- data/lib/eco/api/usecases/default_cases/csv_to_tree_case/node.rb +206 -0
- data/lib/eco/api/usecases/default_cases/csv_to_tree_case/nodes_cleaner.rb +73 -0
- data/lib/eco/api/usecases/default_cases/csv_to_tree_case/treeify.rb +33 -0
- data/lib/eco/api/usecases/default_cases/csv_to_tree_case.rb +44 -0
- data/lib/eco/api/usecases/default_cases.rb +1 -0
- data/lib/eco/api/usecases/graphql/base.rb +1 -1
- data/lib/eco/api/usecases/ooze_samples/helpers_migration/copying.rb +1 -1
- data/lib/eco/cli/config/default/usecases.rb +6 -0
- data/lib/eco/version.rb +1 -1
- metadata +15 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c71f3bf20fae0dff4ec0ccd0ee8205b8af1dee3c9fabb02791f6102a84f7f9ab
|
4
|
+
data.tar.gz: 81ba2c67c4653941529051d433189101e6480313447fdbe6c64da617887371b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b67b415da8341ab6d20a4165ef9f761777bcdb871635a33b0681a56228dae6138c779c31852ce2e748156fa41832ab1ea457ad1aa7ff9dc66c3e1c16dc016be4
|
7
|
+
data.tar.gz: 53e6154974cc3db39e56a127710c1a676e34af8786012b0f3c41051fe14d0b27cc55945875843cdfa1f5fb98d64ed8afcae7eebcd2cfb0cb30da43f7aee2c16f
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,30 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [2.
|
4
|
+
## [2.2.2] - 2023-02-xx
|
5
5
|
|
6
6
|
### Added
|
7
7
|
### Changed
|
8
8
|
### Fixed
|
9
9
|
|
10
|
+
## [2.2.1] - 2023-02-24
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- `Ecoportal::API::V1::Person#contractor_organization_id`
|
14
|
+
- **Support** for **Reporting Structures** (breaking change)
|
15
|
+
- `Eco::API::UseCases::DefaultCases::CsvToTree` use case to generate tree json out of a csv
|
16
|
+
- The output file can be fed to `Eco::API::Organization::TagTree`
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
- **Patch** `Ecoportal::API::V1::Person::VALID_TAG_REGEX` it now allows for dot `.`
|
20
|
+
- update gem dependencies
|
21
|
+
|
22
|
+
## [2.1.12] - 2022-11-30
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
- `Eco::API::Session::Batch::Errors#str` remove double up on error message
|
26
|
+
- wrong require
|
27
|
+
|
10
28
|
## [2.1.11] - 2022-11-30
|
11
29
|
|
12
30
|
### Changed
|
data/eco-helpers.gemspec
CHANGED
@@ -31,8 +31,8 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
|
32
32
|
|
33
33
|
spec.add_dependency 'ecoportal-api', '>= 0.8.5', '< 0.9'
|
34
|
-
spec.add_dependency 'ecoportal-api-v2', '>= 0.
|
35
|
-
spec.add_dependency 'ecoportal-api-graphql', '>= 0.
|
34
|
+
spec.add_dependency 'ecoportal-api-v2', '>= 1.0.1', '< 1.1'
|
35
|
+
spec.add_dependency 'ecoportal-api-graphql', '>= 0.2.2', '< 0.3'
|
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', '< 2.8'
|
@@ -13,7 +13,7 @@ module Eco
|
|
13
13
|
autoloads_children_of "Eco::API::Common::Loaders::Parser"
|
14
14
|
autoload_namespace_ignore "Eco::API"
|
15
15
|
|
16
|
-
CORE_ATTRS = ["id", "external_id", "email", "name", "supervisor_id", "filter_tags", "freemium"]
|
16
|
+
CORE_ATTRS = ["id", "external_id", "email", "name", "supervisor_id", "filter_tags", "contractor_organization_id", "freemium"]
|
17
17
|
ACCOUNT_ATTRS = ["policy_group_ids", "default_tag", "send_invites", "landing_page_id", "login_provider_ids"]
|
18
18
|
TYPE = [:select, :text, :date, :number, :phone_number, :boolean, :multiple]
|
19
19
|
FORMAT = [:csv, :xml, :json, :xls]
|
@@ -3,6 +3,17 @@ module Ecoportal
|
|
3
3
|
class V1
|
4
4
|
# @attr entry [Eco::API::Common::People::PersonEntry, Hash] the input entry plain hash data used to update/create this person.
|
5
5
|
class Person
|
6
|
+
class << self
|
7
|
+
def redef_without_warning(const, value)
|
8
|
+
self.class.send(:remove_const, const) if self.class.const_defined?(const)
|
9
|
+
self.class.const_set(const, value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
redef_without_warning('VALID_TAG_REGEX', /^[A-Za-z0-9 &_'\/.-]+$/)
|
14
|
+
|
15
|
+
passthrough :contractor_organization_id
|
16
|
+
|
6
17
|
attr_accessor :entry
|
7
18
|
|
8
19
|
def identify(section = :person)
|
@@ -13,7 +24,6 @@ module Ecoportal
|
|
13
24
|
"'#{name}' (#{str_id}ext_id: '#{external_id}'; email: '#{email}')"
|
14
25
|
end
|
15
26
|
end
|
16
|
-
|
17
27
|
end
|
18
28
|
end
|
19
29
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
module Eco
|
2
2
|
module API
|
3
3
|
module Organization
|
4
|
-
|
5
4
|
# Provides helpers to deal with tagtrees.
|
6
5
|
class TagTree
|
7
|
-
|
6
|
+
attr_accessor :id
|
7
|
+
alias_method :tag, :id
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
attr_reader :nodes, :children_count
|
8
11
|
attr_reader :depth, :path
|
9
12
|
attr_reader :enviro
|
10
13
|
|
@@ -18,7 +21,7 @@ module Eco
|
|
18
21
|
# ]}]
|
19
22
|
# tree = TagTree.new(tree.to_json)
|
20
23
|
# @param tagtree [String] representation of the tagtree in json.
|
21
|
-
def initialize(tagtree = [], depth: -1, path: [], enviro: nil)
|
24
|
+
def initialize(tagtree = [], name: nil, id: nil, depth: -1, path: [], enviro: nil)
|
22
25
|
case tagtree
|
23
26
|
when String
|
24
27
|
@source = JSON.parse(tagtree)
|
@@ -30,23 +33,27 @@ module Eco
|
|
30
33
|
@enviro = enviro
|
31
34
|
|
32
35
|
@depth = depth
|
33
|
-
|
36
|
+
if @source.is_a?(Array)
|
37
|
+
@id = id
|
38
|
+
@name = name
|
39
|
+
@nodes = @source
|
40
|
+
else
|
41
|
+
@id = @source.values_at('tag', 'id').compact.first&.upcase
|
42
|
+
@name = @source['name']
|
43
|
+
@nodes = @source['nodes'] || []
|
44
|
+
end
|
34
45
|
|
35
46
|
@path = path || []
|
36
|
-
@path.push(@
|
47
|
+
@path.push(@id) unless top?
|
37
48
|
|
38
|
-
nodes =
|
39
|
-
|
49
|
+
@nodes = nodes.map do |cnode|
|
50
|
+
TagTree.new(cnode, depth: @depth + 1, path: @path.dup, enviro: @enviro)
|
51
|
+
end
|
40
52
|
@children_count = @nodes.count
|
41
53
|
|
42
54
|
init_hashes
|
43
55
|
end
|
44
56
|
|
45
|
-
# Updates the tag of the current tree
|
46
|
-
def tag=(value)
|
47
|
-
@tag = value
|
48
|
-
end
|
49
|
-
|
50
57
|
# @return [Eco::API::Organization::TagTree]
|
51
58
|
def dup
|
52
59
|
self.class.new(as_json)
|
@@ -69,7 +76,7 @@ module Eco
|
|
69
76
|
nodes_json
|
70
77
|
else
|
71
78
|
{
|
72
|
-
"
|
79
|
+
"id" => tag,
|
73
80
|
"nodes" => nodes_json
|
74
81
|
}
|
75
82
|
end
|
@@ -80,6 +87,11 @@ module Eco
|
|
80
87
|
@has_tags.empty?
|
81
88
|
end
|
82
89
|
|
90
|
+
# @return [Integer] the number of locations
|
91
|
+
def count
|
92
|
+
@hash_tags.keys.count
|
93
|
+
end
|
94
|
+
|
83
95
|
# @return [Integer] the highest `depth` of all the children.
|
84
96
|
def total_depth
|
85
97
|
@total_depth ||= if children_count > 0
|
@@ -245,12 +257,12 @@ module Eco
|
|
245
257
|
|
246
258
|
def init_hashes
|
247
259
|
@hash_tags = {}
|
248
|
-
@hash_tags[@
|
260
|
+
@hash_tags[@id] = self unless top?
|
249
261
|
@hash_tags = @nodes.reduce(@hash_tags) do |h,n|
|
250
262
|
h.merge(n.hash)
|
251
263
|
end
|
252
264
|
@hash_paths = {}
|
253
|
-
@hash_paths[@
|
265
|
+
@hash_paths[@id] = @path unless top?
|
254
266
|
@hash_paths = @nodes.reduce(@hash_paths) do |h,n|
|
255
267
|
h.merge(n.hash_paths)
|
256
268
|
end
|
@@ -266,9 +278,7 @@ module Eco
|
|
266
278
|
raise msg if !@enviro
|
267
279
|
@enviro.logger.warn(msg)
|
268
280
|
end
|
269
|
-
|
270
281
|
end
|
271
|
-
|
272
282
|
end
|
273
283
|
end
|
274
284
|
end
|
@@ -81,7 +81,6 @@ module Eco
|
|
81
81
|
# 3. `entry` -> the entry that generated the error
|
82
82
|
# 4. `response` -> the original response from the server that carries the error
|
83
83
|
def errors
|
84
|
-
require 'byebug'
|
85
84
|
entries.each_with_object([]) do |entry, arr|
|
86
85
|
response = status[entry]
|
87
86
|
if body = response.body
|
@@ -184,7 +183,7 @@ module Eco
|
|
184
183
|
i = to_index(key)
|
185
184
|
entry = queue.to_a[i]
|
186
185
|
response = status[i]
|
187
|
-
msg = "Error #{response.status}
|
186
|
+
msg = "Error #{response.status}: #{response.body}\n"
|
188
187
|
msg += "-- Failed to batch #{method}. Person: #{person_ref(entry)}"
|
189
188
|
end
|
190
189
|
msg
|
@@ -3,14 +3,41 @@ module Eco
|
|
3
3
|
class Session
|
4
4
|
class Config
|
5
5
|
class BaseConfig < Hash
|
6
|
-
|
7
6
|
attr_reader :config
|
8
7
|
|
8
|
+
class << self
|
9
|
+
def attr_key(*attrs)
|
10
|
+
attrs.each do |attr|
|
11
|
+
method = "#{attr}".freeze
|
12
|
+
if self.instance_methods.include?(method.to_sym)
|
13
|
+
puts "WARNING (#{self}): redefining method already defined '#{method}'."
|
14
|
+
end
|
15
|
+
|
16
|
+
define_method method do
|
17
|
+
self[method]
|
18
|
+
end
|
19
|
+
|
20
|
+
define_method "#{method}=" do |value|
|
21
|
+
self[method] = value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
9
28
|
def initialize(config:)
|
10
29
|
super(nil)
|
11
30
|
@config = config
|
12
31
|
end
|
13
32
|
|
33
|
+
def file_manager
|
34
|
+
config.file_manager
|
35
|
+
end
|
36
|
+
|
37
|
+
def apis
|
38
|
+
config.apis
|
39
|
+
end
|
40
|
+
|
14
41
|
def clone(config:)
|
15
42
|
keys.each_with_object(self.class.new(config: config)) do |key, cnf|
|
16
43
|
begin
|
@@ -24,7 +51,6 @@ module Eco
|
|
24
51
|
end
|
25
52
|
end
|
26
53
|
end
|
27
|
-
|
28
54
|
end
|
29
55
|
end
|
30
56
|
end
|
@@ -24,13 +24,7 @@ module Eco
|
|
24
24
|
self["dir"]
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
self["timestamp_pattern"] = pattern
|
29
|
-
end
|
30
|
-
|
31
|
-
def timestamp_pattern
|
32
|
-
self["timestamp_pattern"]
|
33
|
-
end
|
27
|
+
attr_key :timestamp_pattern
|
34
28
|
|
35
29
|
def add_validation(format)
|
36
30
|
raise "Block must be given" unless block_given?
|
@@ -3,47 +3,12 @@ module Eco
|
|
3
3
|
class Session
|
4
4
|
class Config
|
5
5
|
class Logger < BaseConfig
|
6
|
-
|
7
|
-
|
8
|
-
self["console_level"] = value
|
9
|
-
end
|
10
|
-
|
11
|
-
def console_level
|
12
|
-
self["console_level"]
|
13
|
-
end
|
14
|
-
|
15
|
-
def file_level=(value)
|
16
|
-
self["file_level"] = value
|
17
|
-
end
|
18
|
-
|
19
|
-
def file_level
|
20
|
-
self["file_level"]
|
21
|
-
end
|
22
|
-
|
23
|
-
def file=(file)
|
24
|
-
self["file"] = file
|
25
|
-
end
|
26
|
-
|
27
|
-
def file
|
28
|
-
self["file"]
|
29
|
-
end
|
30
|
-
|
31
|
-
def timestamp_console=(value)
|
32
|
-
self["timestamp_console"] = value
|
33
|
-
end
|
34
|
-
|
35
|
-
def timestamp_console
|
36
|
-
self["timestamp_console"]
|
37
|
-
end
|
38
|
-
|
39
|
-
def log_connection=(value)
|
40
|
-
self["log_connection"] = !!value
|
41
|
-
end
|
6
|
+
attr_key :console_level, :file_level, :file
|
7
|
+
attr_key :timestamp_console, :log_connection
|
42
8
|
|
43
9
|
def log_connection?
|
44
|
-
|
10
|
+
!!log_connection
|
45
11
|
end
|
46
|
-
|
47
12
|
end
|
48
13
|
end
|
49
14
|
end
|
@@ -3,71 +3,14 @@ module Eco
|
|
3
3
|
class Session
|
4
4
|
class Config
|
5
5
|
class Mailer < BaseConfig
|
6
|
+
attr_key :access_key_id, :secret_access_key
|
7
|
+
attr_key :region, :server, :message_id_domain
|
8
|
+
attr_key :to, :from
|
6
9
|
|
7
10
|
def configured?
|
8
11
|
required = access_key_id && secret_access_key && region
|
9
12
|
!!required
|
10
13
|
end
|
11
|
-
|
12
|
-
def to=(value)
|
13
|
-
self["to"] = value
|
14
|
-
end
|
15
|
-
|
16
|
-
def to
|
17
|
-
self["to"]
|
18
|
-
end
|
19
|
-
|
20
|
-
def from=(value)
|
21
|
-
self["from"] = value
|
22
|
-
end
|
23
|
-
|
24
|
-
def from
|
25
|
-
self["from"]
|
26
|
-
end
|
27
|
-
|
28
|
-
def access_key_id=(key)
|
29
|
-
self["access_key_id"] = key
|
30
|
-
end
|
31
|
-
|
32
|
-
def access_key_id
|
33
|
-
self["access_key_id"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def secret_access_key=(key)
|
37
|
-
self["secret_access_key"] = key
|
38
|
-
end
|
39
|
-
|
40
|
-
def secret_access_key
|
41
|
-
self["secret_access_key"]
|
42
|
-
end
|
43
|
-
|
44
|
-
# AWS::SES::Client
|
45
|
-
def region=(region)
|
46
|
-
self["region"] = region
|
47
|
-
end
|
48
|
-
|
49
|
-
def region
|
50
|
-
self["region"]
|
51
|
-
end
|
52
|
-
|
53
|
-
# AWS::SES::Base
|
54
|
-
def server=(domain)
|
55
|
-
self["server"] = domain
|
56
|
-
end
|
57
|
-
|
58
|
-
def server
|
59
|
-
self["server"]
|
60
|
-
end
|
61
|
-
|
62
|
-
# AWS::SES::Base
|
63
|
-
def message_id_domain=(domain)
|
64
|
-
self["message_id_domain"] = domain
|
65
|
-
end
|
66
|
-
|
67
|
-
def message_id_domain
|
68
|
-
self["message_id_domain"]
|
69
|
-
end
|
70
|
-
|
71
14
|
end
|
72
15
|
end
|
73
16
|
end
|
@@ -63,40 +63,19 @@ module Eco
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# person model
|
66
|
-
|
67
|
-
self["default_usergroup"] = value
|
68
|
-
end
|
66
|
+
attr_key :default_usergroup, :default_schema, :default_login_method
|
69
67
|
|
70
|
-
def default_usergroup
|
71
|
-
self["default_usergroup"]
|
72
|
-
end
|
73
68
|
|
74
69
|
def default_usergroup?
|
75
|
-
!!
|
76
|
-
end
|
77
|
-
|
78
|
-
def default_schema=(name)
|
79
|
-
self["default_schema"] = name
|
80
|
-
end
|
81
|
-
|
82
|
-
def default_schema
|
83
|
-
self["default_schema"]
|
70
|
+
!!default_usergroup
|
84
71
|
end
|
85
72
|
|
86
73
|
def default_schema?
|
87
|
-
!!
|
88
|
-
end
|
89
|
-
|
90
|
-
def default_login_method=(name)
|
91
|
-
self["default_login_method"] = name
|
92
|
-
end
|
93
|
-
|
94
|
-
def default_login_method
|
95
|
-
self["default_login_method"]
|
74
|
+
!!default_schema
|
96
75
|
end
|
97
76
|
|
98
77
|
def default_login_method?
|
99
|
-
!!
|
78
|
+
!!default_login_method
|
100
79
|
end
|
101
80
|
|
102
81
|
# @return [Hash] with defined pairs format `key` and Person parsers.
|
@@ -116,7 +95,6 @@ module Eco
|
|
116
95
|
prs
|
117
96
|
end
|
118
97
|
end
|
119
|
-
|
120
98
|
end
|
121
99
|
end
|
122
100
|
end
|
@@ -3,52 +3,14 @@ module Eco
|
|
3
3
|
class Session
|
4
4
|
class Config
|
5
5
|
class S3Storage < BaseConfig
|
6
|
-
|
6
|
+
attr_key :bucket_name, :prefix, :region
|
7
|
+
attr_key :access_key_id, :secret_access_key
|
8
|
+
|
7
9
|
def configured?
|
8
10
|
required = bucket_name && prefix && access_key_id && secret_access_key && region
|
9
11
|
!!required
|
10
12
|
end
|
11
13
|
|
12
|
-
def bucket_name=(value)
|
13
|
-
self["bucket_name"] = value
|
14
|
-
end
|
15
|
-
|
16
|
-
def bucket_name
|
17
|
-
self["bucket_name"]
|
18
|
-
end
|
19
|
-
|
20
|
-
def prefix=(value)
|
21
|
-
self["prefix"] = value
|
22
|
-
end
|
23
|
-
|
24
|
-
def prefix
|
25
|
-
self["prefix"]
|
26
|
-
end
|
27
|
-
|
28
|
-
def access_key_id=(key)
|
29
|
-
self["access_key_id"] = key
|
30
|
-
end
|
31
|
-
|
32
|
-
def access_key_id
|
33
|
-
self["access_key_id"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def secret_access_key=(key)
|
37
|
-
self["secret_access_key"] = key
|
38
|
-
end
|
39
|
-
|
40
|
-
def secret_access_key
|
41
|
-
self["secret_access_key"]
|
42
|
-
end
|
43
|
-
|
44
|
-
def region=(region)
|
45
|
-
self["region"] = region
|
46
|
-
end
|
47
|
-
|
48
|
-
def region
|
49
|
-
self["region"]
|
50
|
-
end
|
51
|
-
|
52
14
|
def target_files=(value)
|
53
15
|
self["target_files"] = [value].flatten
|
54
16
|
end
|
@@ -72,7 +34,6 @@ module Eco
|
|
72
34
|
def target_file_patterns
|
73
35
|
self["target_file_patterns"]
|
74
36
|
end
|
75
|
-
|
76
37
|
end
|
77
38
|
end
|
78
39
|
end
|
@@ -3,60 +3,15 @@ module Eco
|
|
3
3
|
class Session
|
4
4
|
class Config
|
5
5
|
class SFTP < BaseConfig
|
6
|
+
attr_key :host, :user
|
7
|
+
attr_key :password, :key_file
|
8
|
+
attr_key :base_path, :enviro_subpaths
|
6
9
|
|
7
10
|
def configured?
|
8
11
|
required = host && user && (key_file || password)
|
9
12
|
!!required
|
10
13
|
end
|
11
14
|
|
12
|
-
def host=(value)
|
13
|
-
self["host"] = value
|
14
|
-
end
|
15
|
-
|
16
|
-
def host
|
17
|
-
self["host"]
|
18
|
-
end
|
19
|
-
|
20
|
-
def user=(value)
|
21
|
-
self["user"] = value
|
22
|
-
end
|
23
|
-
|
24
|
-
def user
|
25
|
-
self["user"]
|
26
|
-
end
|
27
|
-
|
28
|
-
def password=(var)
|
29
|
-
self["password"] = var
|
30
|
-
end
|
31
|
-
|
32
|
-
def password
|
33
|
-
self["password"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def key_file=(key)
|
37
|
-
self["key_file"] = key
|
38
|
-
end
|
39
|
-
|
40
|
-
def key_file
|
41
|
-
self["key_file"]
|
42
|
-
end
|
43
|
-
|
44
|
-
def base_path=(path)
|
45
|
-
self["base_path"] = path
|
46
|
-
end
|
47
|
-
|
48
|
-
def base_path
|
49
|
-
self["base_path"]
|
50
|
-
end
|
51
|
-
|
52
|
-
def enviro_subpaths=(hash)
|
53
|
-
self["enviro_subpaths"] = hash
|
54
|
-
end
|
55
|
-
|
56
|
-
def enviro_subpaths
|
57
|
-
self["enviro_subpaths"]
|
58
|
-
end
|
59
|
-
|
60
15
|
def enviro_subpath
|
61
16
|
enviro_subpaths[config.active_enviro]
|
62
17
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
class Session
|
4
|
+
class Config
|
5
|
+
class TagTree < BaseConfig
|
6
|
+
attr_key :file
|
7
|
+
|
8
|
+
def scope_tree(enviro: nil)
|
9
|
+
return @tagtree if instance_variable_defined?(:@tagtree) && @tagtree.enviro == enviro
|
10
|
+
if tree_file = self.file
|
11
|
+
if (tree = file_manager.load_json(tree_file)) && !tree.empty?
|
12
|
+
@tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@tagtree ||= live_tree(enviro: enviro)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Among all the locations structures it selects the one with more location nodes
|
19
|
+
def live_tree(enviro: nil)
|
20
|
+
return @live_tree if instance_variable_defined?(:@live_tree) && @live_tree.enviro == enviro
|
21
|
+
trees = live_trees(enviro: enviro)
|
22
|
+
@live_tree = trees.reject do |tree|
|
23
|
+
tree.empty?
|
24
|
+
end.max {|a,b| a.count <=> b.count}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Retrieves all the location structures of the organisation
|
28
|
+
def live_trees(enviro: nil)
|
29
|
+
[].tap do |trees|
|
30
|
+
next unless apis.active_api.version_available?(:graphql)
|
31
|
+
next unless graphql = apis.api(version: :graphql)
|
32
|
+
kargs = {
|
33
|
+
includeArchived: false,
|
34
|
+
includeUnpublished: false
|
35
|
+
}
|
36
|
+
next unless trees = graphql.currentOrganization.locationsStructures(**kargs)
|
37
|
+
trees.each do |tree|
|
38
|
+
args = { enviro: enviro, id: tree.id, name: tree.name}
|
39
|
+
eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, **args)
|
40
|
+
trees.push(eco_tree)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -46,6 +46,12 @@ module Eco
|
|
46
46
|
def mailer
|
47
47
|
self["mailer"] ||= Eco::API::Session::Config::Mailer.new(config: self)
|
48
48
|
end
|
49
|
+
|
50
|
+
# Helper scope reporting structures.
|
51
|
+
# @return [Eco::API::Session::Config::TagTree]
|
52
|
+
def tagtree_config
|
53
|
+
org["tagtree_config"] ||= Eco::API::Session::Config::TagTree.new(config: self)
|
54
|
+
end
|
49
55
|
# @!endgroup
|
50
56
|
|
51
57
|
# @!group Logger
|
@@ -225,35 +231,20 @@ module Eco
|
|
225
231
|
end
|
226
232
|
|
227
233
|
def tagtree=(file)
|
228
|
-
|
234
|
+
tagtree_config.file = file
|
229
235
|
end
|
230
236
|
|
231
|
-
# It uses the `tagtree.json` file and in its absence, if `graphql` enabled, the `life_tagtree`
|
237
|
+
# It uses the `tagtree.json` file and in its absence, if `graphql` enabled, the largest `life_tagtree`
|
232
238
|
# @return [Eco::API::Organization::TagTree]
|
233
239
|
def tagtree(enviro: nil)
|
234
|
-
|
235
|
-
if tree_file = org["tagtree"]
|
236
|
-
tree = []
|
237
|
-
tree = file_manager.load_json(tree_file) unless !tree_file
|
238
|
-
@tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
239
|
-
else
|
240
|
-
@tagtree = live_tree(enviro: enviro)
|
241
|
-
end
|
240
|
+
@tagtree ||= tagtree_config.scope_tree(enviro: enviro)
|
242
241
|
end
|
243
242
|
|
244
243
|
# It obtains the first of the live tagtree in the org
|
245
244
|
# @note it requires graphql connection configuration parameters
|
246
245
|
# @return [Eco::API::Organization::TagTree]
|
247
246
|
def live_tree(enviro: nil)
|
248
|
-
|
249
|
-
if apis.active_api.version_available?(:graphql)
|
250
|
-
graphql = apis.api(version: :graphql)
|
251
|
-
if tree = graphql.currentOrganization.tagTrees.to_a.first.treeify
|
252
|
-
@live_tree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
253
|
-
else
|
254
|
-
@live_tree = nil
|
255
|
-
end
|
256
|
-
end
|
247
|
+
@live_tree ||= tagtree_config.live_tree(enviro: enviro)
|
257
248
|
end
|
258
249
|
|
259
250
|
# @return [Eco::API::Organization::PolicyGroups]
|
@@ -415,5 +406,6 @@ require_relative 'config/sftp'
|
|
415
406
|
require_relative 'config/s3_storage'
|
416
407
|
require_relative 'config/files'
|
417
408
|
require_relative 'config/people'
|
409
|
+
require_relative 'config/tagtree'
|
418
410
|
require_relative 'config/post_launch'
|
419
411
|
require_relative 'config/workflow'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::CsvToTree
|
2
|
+
module Helper
|
3
|
+
extend NodesCleaner
|
4
|
+
extend Treeify
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def csv_from(filename)
|
8
|
+
raise "Missing #{filename}" unless File.exists?(filename)
|
9
|
+
result = csv_from_file(filename)
|
10
|
+
if result.is_a?(Integer)
|
11
|
+
puts "An encoding problem was found on line #{result}"
|
12
|
+
result = csv_from_content(filename)
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
def csv_nodes(filename)
|
18
|
+
i = 1; prev_level = nil; prev_node = nil; prev_nodes = Array(1..11).zip(Array.new(11, nil)).to_h
|
19
|
+
nodes = csv_from(filename).each_with_object([]) do |row, out|
|
20
|
+
values = row.fields.map do |value|
|
21
|
+
value = value.to_s.strip
|
22
|
+
value.empty?? nil : value
|
23
|
+
end
|
24
|
+
i += 1
|
25
|
+
node = Node.new(i, *values)
|
26
|
+
prev_node ||= node
|
27
|
+
|
28
|
+
if prev_node.raw_level <= node.raw_level
|
29
|
+
node.set_high_levels(prev_node)
|
30
|
+
else
|
31
|
+
if parent_node = prev_nodes[node.raw_level - 1]
|
32
|
+
node.set_high_levels(parent_node)
|
33
|
+
else
|
34
|
+
raise "Node '#{node.raw_tag}' (#{node.row_num} row) doesn't have parent"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
out << node
|
38
|
+
prev_nodes[node.raw_level] = node
|
39
|
+
prev_node = node
|
40
|
+
end
|
41
|
+
tidy_nodes(nodes)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def csv_from_content(filename)
|
47
|
+
CSV.parse(file_content(filename), headers: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_content(filename)
|
51
|
+
coding = encoding(filename)
|
52
|
+
coding = (coding != "utf-8")? "#{coding}|utf-8": coding
|
53
|
+
if content = File.read(filename, encoding: coding)
|
54
|
+
content.scrub do |bytes|
|
55
|
+
'<' + bytes.unpack('H*')[0] + '>'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def csv_from_file(filename)
|
61
|
+
coding = encoding(filename)
|
62
|
+
coding = (coding != "utf-8")? "#{coding}|utf-8": coding
|
63
|
+
CSV.read(filename, headers: true, encoding: coding)
|
64
|
+
rescue CSV::MalformedCSVError => e
|
65
|
+
if line = e.message.match(/line (?<line>\d+)/i)[:line]
|
66
|
+
return line.to_i
|
67
|
+
else
|
68
|
+
raise
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def has_bom?(path)
|
73
|
+
return false if !path || file_empty?(path)
|
74
|
+
File.open(path, "rb") do |f|
|
75
|
+
bytes = f.read(3)
|
76
|
+
return bytes.unpack("C*") == [239, 187, 191]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def encoding(path)
|
81
|
+
has_bom?(path) ? "bom" : "utf-8"
|
82
|
+
end
|
83
|
+
|
84
|
+
def file_empty?(path)
|
85
|
+
return true if !File.file?(path)
|
86
|
+
File.zero?(path)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::CsvToTree
|
2
|
+
class Node < Struct.new(:row_num, :l1, :l2, :l3, :l4, :l5, :l6, :l7, :l8, :l9, :l10, :l11)
|
3
|
+
TAGS_ATTRS = [:l1, :l2, :l3, :l4, :l5, :l6, :l7, :l8, :l9, :l10, :l11]
|
4
|
+
ADDITIONAL_ATTRS = [:row_num]
|
5
|
+
ALL_ATTRS = ADDITIONAL_ATTRS + TAGS_ATTRS
|
6
|
+
ALLOWED_CHARACTERS = "A-Za-z0-9 &_'\/.-"
|
7
|
+
VALID_TAG_REGEX = /^[#{ALLOWED_CHARACTERS}]+$/
|
8
|
+
INVALID_TAG_REGEX = /[^#{ALLOWED_CHARACTERS}]+/
|
9
|
+
VALID_TAG_CHARS = /[#{ALLOWED_CHARACTERS}]+/
|
10
|
+
DOUBLE_BLANKS = /\s\s+/
|
11
|
+
|
12
|
+
attr_accessor :parentId
|
13
|
+
|
14
|
+
def nodeId
|
15
|
+
id
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
tag.upcase
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
tag
|
24
|
+
end
|
25
|
+
|
26
|
+
def tag
|
27
|
+
raw_tag.yield_self do |str|
|
28
|
+
partial = replace_not_allowed(str)
|
29
|
+
remove_double_blanks(partial).tap do |result|
|
30
|
+
if partial != str
|
31
|
+
invalid_chars = identify_invalid_characters(str)
|
32
|
+
puts "• (Row: #{self.row_num}) Invalid characters _#{invalid_chars}_ (removed): '#{str}' (converted to '#{result}')"
|
33
|
+
end
|
34
|
+
if result != partial
|
35
|
+
#puts "• There were DOUBLE BLANKS: tag '#{str}' (converted to '#{result}')"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def raw_tag
|
42
|
+
values_at(*TAGS_ATTRS.reverse).compact.first
|
43
|
+
end
|
44
|
+
|
45
|
+
def level
|
46
|
+
actual_level
|
47
|
+
end
|
48
|
+
|
49
|
+
def actual_level
|
50
|
+
tags_array.compact.length
|
51
|
+
end
|
52
|
+
|
53
|
+
def raw_level
|
54
|
+
tags_array.index(raw_tag) + 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def tag_idx
|
58
|
+
tags_array.index(raw_tag)
|
59
|
+
end
|
60
|
+
|
61
|
+
def previous_idx
|
62
|
+
idx = tag_idx - 1
|
63
|
+
idx < 0 ? nil : idx
|
64
|
+
end
|
65
|
+
|
66
|
+
def empty_idx
|
67
|
+
tary = tags_array
|
68
|
+
tary.index(nil) || tary.length + 1
|
69
|
+
end
|
70
|
+
|
71
|
+
def copy
|
72
|
+
self.class.new.set_attrs(**self.to_h)
|
73
|
+
end
|
74
|
+
|
75
|
+
# We got a missing level that is compacted in one row
|
76
|
+
# Here we get the missing intermediate levels
|
77
|
+
# This is done from upper to lower level to ensure processing order
|
78
|
+
# It skips last one, as that is this object already
|
79
|
+
def decouple(num = 1)
|
80
|
+
with_info = filled_idxs
|
81
|
+
# must be the last among filled_idxs, so let's use it to verify
|
82
|
+
unless with_info.last == tag_idx
|
83
|
+
raise "Review this (row #{row_num}; '#{raw_tag}'): tag_idx is #{tag_idx}, while last filled idx is #{with_info.last}"
|
84
|
+
end
|
85
|
+
len = with_info.length
|
86
|
+
target_idxs = with_info[len-(num+1)..-2]
|
87
|
+
target_idxs.map do |idx|
|
88
|
+
self.copy.tap do |dup|
|
89
|
+
dup.clear_level(idx_to_level(idx + 1))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def merge!(node)
|
95
|
+
override_upper_levels(node.tags_array)
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_high_levels(node)
|
99
|
+
override_lower_levels(node.tags_array)
|
100
|
+
end
|
101
|
+
|
102
|
+
def clear_level(i)
|
103
|
+
case i
|
104
|
+
when Enumerable
|
105
|
+
target = i.to_a
|
106
|
+
when Integer
|
107
|
+
return false unless i >= 1 && i <= tag_attrs_count
|
108
|
+
target = Array(i..tag_attrs_count)
|
109
|
+
else
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
return false if target.empty?
|
113
|
+
target.each do |n|
|
114
|
+
#puts "clearing 'l#{n}': #{attr("l#{n}")}"
|
115
|
+
set_attr("l#{n}", nil)
|
116
|
+
end
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
def override_upper_levels(src_tags_array, from_level: self.raw_level + 1)
|
121
|
+
target_lev = Array(from_level..tag_attrs_count)
|
122
|
+
target_tags = src_tags_array[level_to_idx(from_level)..level_to_idx(tag_attrs_count)]
|
123
|
+
target_lev.zip(target_tags).each do |(n, tag)|
|
124
|
+
set_attr("l#{n}", tag)
|
125
|
+
end
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
def override_lower_levels(src_tags_array, to_level: self.raw_level - 1)
|
130
|
+
target_lev = Array(1..to_level)
|
131
|
+
target_tags = src_tags_array[level_to_idx(1)..level_to_idx(to_level)]
|
132
|
+
target_lev.zip(target_tags).each do |(n, tag)|
|
133
|
+
set_attr("l#{n}", tag)
|
134
|
+
end
|
135
|
+
self
|
136
|
+
end
|
137
|
+
|
138
|
+
def idx_to_level(x)
|
139
|
+
x + 1
|
140
|
+
end
|
141
|
+
|
142
|
+
def level_to_idx(x)
|
143
|
+
x - 1
|
144
|
+
end
|
145
|
+
|
146
|
+
def filled_idxs
|
147
|
+
tags_array.each_with_index.with_object([]) do |(t, i), o|
|
148
|
+
o << i if t
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def blanks_between?
|
153
|
+
actual_level > empty_idx
|
154
|
+
end
|
155
|
+
|
156
|
+
def tags_array
|
157
|
+
values_at(*TAGS_ATTRS)
|
158
|
+
end
|
159
|
+
|
160
|
+
def values_at(*attrs)
|
161
|
+
attrs.map {|a| attr(a)}
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_h(*attrs)
|
165
|
+
attrs = ALL_ATTRS if attrs.empty?
|
166
|
+
ALL_ATTRS.zip(values_at(*ALL_ATTRS)).to_h
|
167
|
+
end
|
168
|
+
|
169
|
+
def slice(*attrs)
|
170
|
+
return {} if attrs.empty?
|
171
|
+
to_h(*attrs)
|
172
|
+
end
|
173
|
+
|
174
|
+
def set_attrs(**kargs)
|
175
|
+
kargs.each {|attr, value| set_attr(attr, value)}
|
176
|
+
self
|
177
|
+
end
|
178
|
+
|
179
|
+
def set_attr(attr, value)
|
180
|
+
self.send("#{attr}=", value)
|
181
|
+
end
|
182
|
+
|
183
|
+
def attr(sym)
|
184
|
+
self.send(sym.to_sym)
|
185
|
+
end
|
186
|
+
|
187
|
+
def tag_attrs_count
|
188
|
+
TAGS_ATTRS.length
|
189
|
+
end
|
190
|
+
|
191
|
+
def remove_double_blanks(str)
|
192
|
+
return nil if str.nil?
|
193
|
+
str.gsub(DOUBLE_BLANKS, ' ').strip
|
194
|
+
end
|
195
|
+
|
196
|
+
def replace_not_allowed(str)
|
197
|
+
return nil if str.nil?
|
198
|
+
return str if str.match(VALID_TAG_REGEX)
|
199
|
+
str.gsub(INVALID_TAG_REGEX, ' ')
|
200
|
+
end
|
201
|
+
|
202
|
+
def identify_invalid_characters(str)
|
203
|
+
str.gsub(VALID_TAG_CHARS, '')
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::CsvToTree
|
2
|
+
module NodesCleaner
|
3
|
+
def repeated_tags
|
4
|
+
@repeated_tags ||= []
|
5
|
+
end
|
6
|
+
|
7
|
+
def done_tags
|
8
|
+
@done_tags ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def fill_in_parents(nodes)
|
12
|
+
nodes.tap do |nodes|
|
13
|
+
prev_nodes = Array(1..11).zip(Array.new(11, nil)).to_h
|
14
|
+
nodes.each do |node|
|
15
|
+
if parent_node = prev_nodes[node.raw_level - 1]
|
16
|
+
node.parentId = parent_node.id
|
17
|
+
end
|
18
|
+
prev_nodes[node.raw_level] = node
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def tidy_nodes(nodes, prev_level: 0, main: true)
|
24
|
+
out = nodes.each_with_object([]) do |node, out|
|
25
|
+
if done_tags.include?(tag = node.tag)
|
26
|
+
repeated_tags << "#{tag} (level: #{node.level})"
|
27
|
+
else
|
28
|
+
level = node.actual_level
|
29
|
+
if level > prev_level + 1
|
30
|
+
gap = level - (prev_level + 1)
|
31
|
+
puts "(Row: #{node.row_num}) Tag '#{tag}' (lev #{level}) jumps #{gap} level(s) (expected #{prev_level + 1})."
|
32
|
+
#puts " " + node.tags_array.pretty_inspect
|
33
|
+
missing_nodes = node.decouple(gap)
|
34
|
+
puts " Adding missing upper level(s): " + missing_nodes.map(&:raw_tag).pretty_inspect
|
35
|
+
out.push(*tidy_nodes(missing_nodes, prev_level: prev_level, main: false))
|
36
|
+
# puts node.actual_level
|
37
|
+
# pp node.tags_array
|
38
|
+
level = prev_level + 1
|
39
|
+
end
|
40
|
+
out << node
|
41
|
+
done_tags << tag
|
42
|
+
prev_level = level
|
43
|
+
end
|
44
|
+
end
|
45
|
+
if main
|
46
|
+
unless repeated_tags.empty?
|
47
|
+
puts "There were #{repeated_tags.length} repeated tags. Only one included. These excluded:"
|
48
|
+
pp repeated_tags
|
49
|
+
end
|
50
|
+
end
|
51
|
+
fill_in_parents(out)
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_rows(nodes, prev_level: 0, main: true)
|
55
|
+
out = tidy_nodes(nodes).each_with_object([]) do |node, out|
|
56
|
+
tag = node.tag
|
57
|
+
level = node.actual_level
|
58
|
+
out << (row = Array.new(level, nil))
|
59
|
+
row[-1..-1] = [tag.upcase]
|
60
|
+
prev_level = level
|
61
|
+
end
|
62
|
+
if main
|
63
|
+
# Normalize length
|
64
|
+
max_row = out.max {|a, b| a.length <=> b.length}
|
65
|
+
holder = Array.new(max_row.length, nil)
|
66
|
+
out = out.map do |row|
|
67
|
+
row.dup.concat(holder)[0..max_row.length-1]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
out
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::CsvToTree
|
2
|
+
module Treeify
|
3
|
+
def treeify(nodes, &block)
|
4
|
+
get_children(nil, parents_hash(nodes), &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def parents_hash(nodes)
|
10
|
+
nodes.each_with_object({}) do |node, parents|
|
11
|
+
(parents[node.parentId] ||= []).push(node)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_children(node_id, parents, &block)
|
16
|
+
(parents[node_id] ||= []).each_with_object([]) do |child, results|
|
17
|
+
node_hash = {
|
18
|
+
"id" => child.id,
|
19
|
+
"name" => child.name
|
20
|
+
}
|
21
|
+
|
22
|
+
if block_given?
|
23
|
+
yield_hash = yield(child)
|
24
|
+
node_hash.merge(yield_hash) if yield_hash.is_a?(Hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
results << node_hash.merge({
|
28
|
+
"nodes" => get_children(child.id, parents, &block).compact
|
29
|
+
})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::CsvToTree < Eco::API::Common::Loaders::UseCase
|
2
|
+
name "csv-to-tree"
|
3
|
+
type :other
|
4
|
+
|
5
|
+
TIME_FORMAT = '%Y%m%dT%H%M%S'
|
6
|
+
|
7
|
+
attr_reader :session, :options
|
8
|
+
|
9
|
+
def main(session, options, usecase)
|
10
|
+
options[:end_get] = false
|
11
|
+
@session = session; @options = options
|
12
|
+
|
13
|
+
tree_struct = Helper.treeify(Helper.csv_nodes(input_file))
|
14
|
+
|
15
|
+
File.open(output_file, "w") do |fd|
|
16
|
+
json = tree_struct.to_json
|
17
|
+
fd << json
|
18
|
+
end
|
19
|
+
logger.info("Saved structure in '#{output_file}'")
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def input_file
|
25
|
+
@input_file ||= options.dig(:source, :file)
|
26
|
+
end
|
27
|
+
|
28
|
+
def output_file
|
29
|
+
@output_file ||= "#{active_enviro}_tree_#{timestamp}.json"
|
30
|
+
end
|
31
|
+
|
32
|
+
def timestamp(date = Time.now)
|
33
|
+
date.strftime(TIME_FORMAT)
|
34
|
+
end
|
35
|
+
|
36
|
+
def active_enviro
|
37
|
+
config.active_enviro
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
require_relative 'csv_to_tree_case/node'
|
42
|
+
require_relative 'csv_to_tree_case/nodes_cleaner'
|
43
|
+
require_relative 'csv_to_tree_case/treeify'
|
44
|
+
require_relative 'csv_to_tree_case/helper'
|
@@ -22,6 +22,7 @@ require_relative 'default_cases/create_case'
|
|
22
22
|
require_relative 'default_cases/create_details_case'
|
23
23
|
require_relative 'default_cases/create_details_with_supervisor_case'
|
24
24
|
require_relative 'default_cases/create_tag_paths_case'
|
25
|
+
require_relative 'default_cases/csv_to_tree_case'
|
25
26
|
require_relative 'default_cases/delete_trans_case'
|
26
27
|
require_relative 'default_cases/delete_sync_case'
|
27
28
|
require_relative 'default_cases/email_as_id_case'
|
@@ -71,7 +71,7 @@ class Eco::API::UseCases::OozeSamples
|
|
71
71
|
return src_fld, dst_fld if dst_flds.empty? || src_flds.empty?
|
72
72
|
|
73
73
|
if dst_flds.count > 1
|
74
|
-
logger.warn("There are #{dst_flds.count} destination '#{type}' fields named '#{label_dst}' (source: '#{
|
74
|
+
logger.warn("There are #{dst_flds.count} destination '#{type}' fields named '#{label_dst}' (source: '#{dst.id}'). Using first...")
|
75
75
|
end
|
76
76
|
|
77
77
|
if src_flds.count > 1
|
@@ -98,6 +98,12 @@ ASSETS.cli.config do |cnf|
|
|
98
98
|
desc = "Creates a CSV with the paths to each tag"
|
99
99
|
cases.add("-create-tag-paths", :other, desc, case_name: "create-tag-paths")
|
100
100
|
|
101
|
+
desc = "Creates a JSON file with the tagtree from a CSV file"
|
102
|
+
cases.add("-csv-to-tree", :other, desc, case_name: "csv-to-tree") do |session, options, usecase|
|
103
|
+
file = SCR.get_file("-csv-to-tree", required: true, should_exist: true)
|
104
|
+
options.deep_merge!(source: {file: file})
|
105
|
+
end
|
106
|
+
|
101
107
|
desc = "Cleans from filter_tags those tags that are not present in the tagtree (as per tagtree.json file)."
|
102
108
|
desc += " It will preserve standard register tags of most common registers (i.e. EVENT, RISK)."
|
103
109
|
cases.add("-clean-unknown-tags", :transform, desc, case_name: "clean-unknown-tags")
|
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.1
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
@@ -136,40 +136,40 @@ dependencies:
|
|
136
136
|
requirements:
|
137
137
|
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: 0.
|
139
|
+
version: 1.0.1
|
140
140
|
- - "<"
|
141
141
|
- !ruby/object:Gem::Version
|
142
|
-
version: '
|
142
|
+
version: '1.1'
|
143
143
|
type: :runtime
|
144
144
|
prerelease: false
|
145
145
|
version_requirements: !ruby/object:Gem::Requirement
|
146
146
|
requirements:
|
147
147
|
- - ">="
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version: 0.
|
149
|
+
version: 1.0.1
|
150
150
|
- - "<"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '1.1'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: ecoportal-api-graphql
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0.
|
159
|
+
version: 0.2.2
|
160
160
|
- - "<"
|
161
161
|
- !ruby/object:Gem::Version
|
162
|
-
version: '0.
|
162
|
+
version: '0.3'
|
163
163
|
type: :runtime
|
164
164
|
prerelease: false
|
165
165
|
version_requirements: !ruby/object:Gem::Requirement
|
166
166
|
requirements:
|
167
167
|
- - ">="
|
168
168
|
- !ruby/object:Gem::Version
|
169
|
-
version: 0.
|
169
|
+
version: 0.2.2
|
170
170
|
- - "<"
|
171
171
|
- !ruby/object:Gem::Version
|
172
|
-
version: '0.
|
172
|
+
version: '0.3'
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
174
|
name: aws-sdk-s3
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -540,6 +540,7 @@ files:
|
|
540
540
|
- lib/eco/api/session/config/post_launch.rb
|
541
541
|
- lib/eco/api/session/config/s3_storage.rb
|
542
542
|
- lib/eco/api/session/config/sftp.rb
|
543
|
+
- lib/eco/api/session/config/tagtree.rb
|
543
544
|
- lib/eco/api/session/config/workflow.rb
|
544
545
|
- lib/eco/api/usecases.rb
|
545
546
|
- lib/eco/api/usecases/base_case.rb
|
@@ -556,6 +557,11 @@ files:
|
|
556
557
|
- lib/eco/api/usecases/default_cases/create_details_case.rb
|
557
558
|
- lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb
|
558
559
|
- lib/eco/api/usecases/default_cases/create_tag_paths_case.rb
|
560
|
+
- lib/eco/api/usecases/default_cases/csv_to_tree_case.rb
|
561
|
+
- lib/eco/api/usecases/default_cases/csv_to_tree_case/helper.rb
|
562
|
+
- lib/eco/api/usecases/default_cases/csv_to_tree_case/node.rb
|
563
|
+
- lib/eco/api/usecases/default_cases/csv_to_tree_case/nodes_cleaner.rb
|
564
|
+
- lib/eco/api/usecases/default_cases/csv_to_tree_case/treeify.rb
|
559
565
|
- lib/eco/api/usecases/default_cases/delete_sync_case.rb
|
560
566
|
- lib/eco/api/usecases/default_cases/delete_trans_case.rb
|
561
567
|
- lib/eco/api/usecases/default_cases/email_as_id_case.rb
|