eco-helpers 2.7.20 → 2.7.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -2
- data/lib/eco/api/common/session/file_manager.rb +66 -29
- data/lib/eco/api/common/version_patches/exception.rb +5 -0
- data/lib/eco/api/microcases/fix_filter_tags.rb +20 -13
- data/lib/eco/api/microcases/preserve_filter_tags.rb +12 -12
- data/lib/eco/api/microcases/set_core.rb +4 -5
- data/lib/eco/api/microcases/set_core_with_supervisor.rb +15 -10
- data/lib/eco/api/microcases/set_supervisor.rb +1 -0
- data/lib/eco/api/session/config/api.rb +6 -3
- data/lib/eco/api/session/config/tagtree.rb +1 -0
- data/lib/eco/api/usecases/base_case.rb +11 -3
- data/lib/eco/api/usecases/base_io.rb +9 -1
- data/lib/eco/api/usecases/default/people/amend/clean_unknown_tags_case.rb +133 -27
- data/lib/eco/api/usecases/default/people/amend/cli/clean_unknown_tags_cli.rb +16 -0
- data/lib/eco/api/usecases/default/people/migrate/remap_tags_case.rb +9 -4
- data/lib/eco/api/usecases/use_case.rb +41 -23
- data/lib/eco/cli_default/usecases.rb +0 -7
- data/lib/eco/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cc77a4ee2eb9f30b13efc22f5eaedff1b564f9831c3b7f4d9430b80185ffb83
|
4
|
+
data.tar.gz: fbe4135c3c9c08d46c1ee39b1b3de0c28fd2be547243d2137e49517997052d96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f9d81d2a91bf458dadd99e60b15c2e4063e902fa4e9663383367f91a0ad39fdbf4bd4f367a11fa5aef6f9aacfe82ee22161adc4f36ec46781e2d23ef9798168
|
7
|
+
data.tar.gz: 823605e14716575990fcc13db6e538bc7642164b77b889d10fb0b3037bd8a9304751e012ba1fe3229895e0ec1d3585ea69318496a4226df5af18a7c288a42f81
|
data/CHANGELOG.md
CHANGED
@@ -2,20 +2,32 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [2.7.
|
5
|
+
## [2.7.22] - 2024-07-xx
|
6
6
|
|
7
7
|
### Added
|
8
8
|
|
9
9
|
### Changed
|
10
10
|
|
11
|
+
- Patch on exception: to show cause
|
12
|
+
- `Eco::Common::Session::FileManager`
|
13
|
+
- `load_json` prevent avoidable memory leaks
|
14
|
+
- `save_json` prevent avoidable memory leaks
|
15
|
+
|
11
16
|
### Fixed
|
12
17
|
|
13
|
-
## [2.7.
|
18
|
+
## [2.7.21] - 2024-07-13
|
14
19
|
|
15
20
|
### Added
|
16
21
|
|
22
|
+
- Ability to skip GraphQL schema fetch (`GRAPHQL_FETCH_SCHEMA`)
|
23
|
+
|
17
24
|
### Changed
|
18
25
|
|
26
|
+
- `-clean-unknown-tags` case
|
27
|
+
- option for `clean-archived-nodes` by default it won't clean them
|
28
|
+
|
29
|
+
## [2.7.20] - 2024-07-11
|
30
|
+
|
19
31
|
### Fixed
|
20
32
|
|
21
33
|
- Patch on exception
|
@@ -3,7 +3,6 @@ module Eco
|
|
3
3
|
module Common
|
4
4
|
module Session
|
5
5
|
class FileManager
|
6
|
-
|
7
6
|
include Eco::Data::Files
|
8
7
|
|
9
8
|
attr_reader :dir, :dir_path
|
@@ -11,18 +10,17 @@ module Eco
|
|
11
10
|
|
12
11
|
def initialize(init = {}, enviro: nil)
|
13
12
|
@enviro = enviro
|
14
|
-
init
|
13
|
+
init = @enviro.config if @enviro && init.empty?
|
14
|
+
|
15
15
|
@timestamp_pattern = init.files.timestamp_pattern || DEFAULT_TIMESTAMP_PATTERN
|
16
|
-
self.dir_path
|
16
|
+
self.dir_path = init.working_directory || Dir.pwd
|
17
17
|
end
|
18
18
|
|
19
19
|
def dir_path=(value)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
logger.error("could not create or make any sense of directory '#{value}': #{e.to_s}")
|
25
|
-
end
|
20
|
+
@dir = Eco::Data::Files::Directory.new(value)
|
21
|
+
@dir_path = @dir.create
|
22
|
+
rescue StandardError => e
|
23
|
+
logger.error("could not create or make any sense of directory '#{value}': #{e.to_s}")
|
26
24
|
end
|
27
25
|
|
28
26
|
def logger
|
@@ -40,53 +38,92 @@ module Eco
|
|
40
38
|
|
41
39
|
def file_content(filename, mode: nil)
|
42
40
|
file = dir.file(filename, should_exist: true)
|
43
|
-
|
41
|
+
|
42
|
+
unless file
|
44
43
|
logger.error("Can't read from file '#{filename}' because it does not exist.")
|
45
44
|
return nil
|
46
45
|
end
|
46
|
+
|
47
47
|
logger.debug("Reading from file '#{file}'")
|
48
48
|
mode ? File.read(file, mode: mode) : File.read(file)
|
49
49
|
end
|
50
50
|
|
51
51
|
def load_json(filename)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
raise e
|
52
|
+
file = dir.file(filename, should_exist: true)
|
53
|
+
|
54
|
+
unless file
|
55
|
+
logger.error("Can't read from file '#{filename}' because it does not exist.")
|
56
|
+
return nil
|
58
57
|
end
|
59
|
-
|
58
|
+
|
59
|
+
fd = File.open(file)
|
60
|
+
JSON.load fd # rubocop:disable Security/JSONLoad
|
61
|
+
rescue JSON::ParserError => e
|
62
|
+
pp "Parsing error on file #{file}"
|
63
|
+
raise e
|
64
|
+
ensure
|
65
|
+
fd&.close
|
60
66
|
end
|
61
67
|
|
62
68
|
def touch(filename, modifier = :no_stamp, mode: :string)
|
63
69
|
save("", filename, modifier, mode: mode)
|
64
70
|
end
|
65
71
|
|
66
|
-
def
|
67
|
-
|
68
|
-
file = FileManager.timestamp_file(file) if modifier == :timestamp
|
69
|
-
mode = (mode == :binary) ? 'wb' : 'w'
|
72
|
+
def save_json(data, filename, modifier = :no_stamp)
|
73
|
+
return save(data.to_json, filename, modifier) unless data.is_a?(Array)
|
70
74
|
|
71
|
-
|
75
|
+
file = filename_for(filename, modifier)
|
76
|
+
FileManager.create_directory(
|
77
|
+
FileManager.file_fullpath(file)
|
78
|
+
)
|
72
79
|
|
73
80
|
logger.debug("Writting to file '#{file}'")
|
74
|
-
|
75
|
-
|
81
|
+
|
82
|
+
mode = mode == :binary ? 'wb' : 'w'
|
83
|
+
|
84
|
+
File.open(file, mode) do |fd|
|
85
|
+
first = true
|
86
|
+
|
87
|
+
fd << '['
|
88
|
+
data.each do |elem|
|
89
|
+
fd << "," unless first
|
90
|
+
first = false
|
91
|
+
|
92
|
+
fd << elem.to_json
|
93
|
+
end
|
94
|
+
fd << ']'
|
95
|
+
end
|
96
|
+
|
97
|
+
file
|
76
98
|
end
|
77
99
|
|
78
|
-
def
|
79
|
-
|
100
|
+
def save(content, filename, modifier = :no_stamp, mode: :string)
|
101
|
+
file = filename_for(filename, modifier)
|
102
|
+
FileManager.create_directory(
|
103
|
+
FileManager.file_fullpath(file)
|
104
|
+
)
|
105
|
+
|
106
|
+
logger.debug("Writting to file '#{file}'")
|
107
|
+
|
108
|
+
mode = mode == :binary ? 'wb' : 'w'
|
109
|
+
File.open(file, mode) { |fd| fd << content }
|
110
|
+
file
|
80
111
|
end
|
81
112
|
|
82
113
|
# if the file does not exist, it creates it
|
83
114
|
def append(content, filename, mode: :string)
|
84
115
|
file = dir.file(filename)
|
85
|
-
mode = (mode == :binary) ? 'ab' : 'a'
|
86
116
|
|
87
117
|
logger.debug("Appending to file '#{file}'")
|
88
|
-
|
89
|
-
|
118
|
+
|
119
|
+
mode = mode == :binary ? 'ab' : 'a'
|
120
|
+
File.open(file, mode) { |fd| fd << "#{content}\n" }
|
121
|
+
file
|
122
|
+
end
|
123
|
+
|
124
|
+
def filename_for(filename, modifier = :no_stamp)
|
125
|
+
file = dir.file(filename)
|
126
|
+
FileManager.timestamp_file(file) if modifier == :timestamp
|
90
127
|
end
|
91
128
|
end
|
92
129
|
end
|
@@ -12,6 +12,11 @@ class ::Exception
|
|
12
12
|
msg << "#{" " * 8}#{i + 1}: from #{bt}"
|
13
13
|
end
|
14
14
|
|
15
|
+
unless cause.nil?
|
16
|
+
msg << "\nCAUSE:"
|
17
|
+
msg << cause.patch_full_message(trace_count: trace_count)
|
18
|
+
end
|
19
|
+
|
15
20
|
msg.join("\n")
|
16
21
|
rescue StandardError => e
|
17
22
|
puts "Something is wrong with 'patch_full_message': #{e}"
|
@@ -11,16 +11,20 @@ module Eco
|
|
11
11
|
# * `:preserve_custom` (Boolean) [true] indicates if original tags that are not in the tree should be added/preserved.
|
12
12
|
# * `:add_custom` (Boolean) [true] indicates if target tags that are not in the tree should be really added.
|
13
13
|
def fix_filter_tags(person, options)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
return unless session.tagtree
|
15
|
+
|
16
|
+
filter_tags_excluded =
|
17
|
+
options.dig(:exclude, :core) ||
|
18
|
+
options.dig(:exclude, :filter_tags)
|
19
|
+
|
20
|
+
return if !person.new? && filter_tags_excluded
|
21
|
+
|
22
|
+
person.filter_tags = session.tagtree.user_tags(
|
23
|
+
initial: person.original_doc["filter_tags"] || [],
|
24
|
+
final: person.filter_tags,
|
25
|
+
preserve_custom: _fix_filter_tags_preserve_custom?(options),
|
26
|
+
add_custom: _fix_filter_tags_add_custom?(options)
|
27
|
+
)
|
24
28
|
end
|
25
29
|
|
26
30
|
private
|
@@ -28,15 +32,18 @@ module Eco
|
|
28
32
|
# default `true`
|
29
33
|
def _fix_filter_tags_preserve_custom?(options)
|
30
34
|
key_defined = options.key?(:filter_tags) && options[:filter_tags].key?(:preserve_custom)
|
31
|
-
|
35
|
+
return true unless key_defined
|
36
|
+
|
37
|
+
options.dig(:filter_tags, :preserve_custom)
|
32
38
|
end
|
33
39
|
|
34
40
|
# default `true`
|
35
41
|
def _fix_filter_tags_add_custom?(options)
|
36
42
|
key_defined = options.key?(:filter_tags) && options[:filter_tags].key?(:add_custom)
|
37
|
-
|
38
|
-
end
|
43
|
+
return true unless key_defined
|
39
44
|
|
45
|
+
options.dig(:filter_tags, :add_custom)
|
46
|
+
end
|
40
47
|
end
|
41
48
|
end
|
42
49
|
end
|
@@ -8,21 +8,21 @@ module Eco
|
|
8
8
|
# @param options [Hash] the options.
|
9
9
|
# @param keep_new [Boolean] tells if it should keep the new tags or get rid of them.
|
10
10
|
# @return [Array<String>] the final value of `filter_tags`.
|
11
|
-
def preserve_filter_tags(person,
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
def preserve_filter_tags(person, _options, keep_new: false)
|
12
|
+
person.filter_tags.tap do
|
13
|
+
next unless person.as_update.key?('filter_tags')
|
14
|
+
next unless (original = person.original_doc['filter_tags'])
|
15
|
+
next if original.empty?
|
16
|
+
|
17
|
+
if keep_new
|
18
|
+
person.filter_tags += original
|
19
|
+
else
|
20
|
+
person.filter_tags = original
|
21
21
|
end
|
22
|
+
|
23
|
+
return person.filter_tags
|
22
24
|
end
|
23
|
-
person.filter_tags
|
24
25
|
end
|
25
|
-
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -7,12 +7,11 @@ module Eco
|
|
7
7
|
# @param person [Ecoportal::API::V1::Person] the person we want to update, carrying the changes to be done.
|
8
8
|
# @param options [Hash] the options
|
9
9
|
def set_core(entry, person, options)
|
10
|
-
|
11
|
-
entry.set_core(person, exclude: micro.core_excluded(person, options))
|
12
|
-
micro.fix_filter_tags(person, options)
|
13
|
-
end
|
14
|
-
end
|
10
|
+
return if options.dig(:exclude, :core) && !person.new?
|
15
11
|
|
12
|
+
entry.set_core(person, exclude: micro.core_excluded(person, options))
|
13
|
+
micro.fix_filter_tags(person, options)
|
14
|
+
end
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -9,19 +9,24 @@ module Eco
|
|
9
9
|
# @param supers_job [Eco::API::Session::Batch::Job] the job that will run the supers .
|
10
10
|
# @param options [Hash] the options.
|
11
11
|
def set_core_with_supervisor(entry, person, people, supers_job, options)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
return if options.dig(:exclude, :core) && !person.new?
|
13
|
+
|
14
|
+
micro.set_core(entry, person, options)
|
15
|
+
|
16
|
+
return unless entry.supervisor_id?
|
17
|
+
|
18
|
+
micro.set_supervisor(
|
19
|
+
person,
|
20
|
+
entry.supervisor_id,
|
21
|
+
people,
|
22
|
+
options
|
23
|
+
) do |unknown_id|
|
24
|
+
# delay setting supervisor if does not exit
|
25
|
+
supers_job.add(person) do |pers|
|
26
|
+
micro.set_supervisor(pers, unknown_id, people, options)
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
24
|
-
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
@@ -30,6 +30,7 @@ module Eco
|
|
30
30
|
require 'ecoportal/api-graphql'
|
31
31
|
Ecoportal::API::GraphQL
|
32
32
|
else
|
33
|
+
puts "Unknown api version '#{version}'"
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -104,7 +105,7 @@ module Eco
|
|
104
105
|
end
|
105
106
|
|
106
107
|
def external_key
|
107
|
-
self["external_key"] || ([
|
108
|
+
self["external_key"] || (%i[v1 v2].include?(version) && key)
|
108
109
|
end
|
109
110
|
|
110
111
|
def internal_key
|
@@ -129,7 +130,7 @@ module Eco
|
|
129
130
|
|
130
131
|
# @param mode [Symbol] to define if running on `:remote` or `:local`
|
131
132
|
def mode=(mode)
|
132
|
-
self["mode"] =
|
133
|
+
self["mode"] = mode == :remote ? :remote : :local
|
133
134
|
end
|
134
135
|
|
135
136
|
# @return [Symbol] if running on `:remote` or `:local`
|
@@ -163,7 +164,7 @@ module Eco
|
|
163
164
|
private
|
164
165
|
|
165
166
|
# Generates a **new** `API` object of version `version`.
|
166
|
-
def new_api(version)
|
167
|
+
def new_api(version) # rubocop:disable Metrics/AbcSize
|
167
168
|
klass = self.class.api_class(version)
|
168
169
|
case self.version(version)
|
169
170
|
when :v0
|
@@ -173,6 +174,8 @@ module Eco
|
|
173
174
|
when :v2
|
174
175
|
klass.new(user_key: user_key, org_key: external_key, host: host, logger: logger)
|
175
176
|
when :graphql
|
177
|
+
kargs = {host: host, org_id: org_id, email: email, pass: pass}
|
178
|
+
kargs.merge!({no_schema: true}) if ENV['GRAPHQL_FETCH_SCHEMA'] == "false"
|
176
179
|
klass.new(host: host, org_id: org_id, email: email, pass: pass)
|
177
180
|
end.tap do |api|
|
178
181
|
unless !api || log_connection?
|
@@ -5,15 +5,23 @@ module Eco
|
|
5
5
|
class BaseCase
|
6
6
|
class InvalidType < StandardError
|
7
7
|
def initialize(msg = nil, type:, types:)
|
8
|
-
msg ||= "Invalid type."
|
9
|
-
msg
|
8
|
+
msg ||= "Invalid type. "
|
9
|
+
msg << "Given type '#{type}'. Valid types: #{types}"
|
10
10
|
super(msg)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
extend Eco::API::Common::ClassHelpers
|
15
15
|
|
16
|
-
@types = [
|
16
|
+
@types = %i[
|
17
|
+
import
|
18
|
+
filter
|
19
|
+
transform
|
20
|
+
sync
|
21
|
+
error_handler
|
22
|
+
export
|
23
|
+
other
|
24
|
+
]
|
17
25
|
|
18
26
|
class << self
|
19
27
|
attr_reader :types
|
@@ -71,6 +71,7 @@ module Eco
|
|
71
71
|
type: type,
|
72
72
|
output: output
|
73
73
|
}).slice(:type, :input, :people, :session, :options, :output) # :validate <- ?
|
74
|
+
|
74
75
|
Eco::API::UseCases::BaseIO.new(**kargs)
|
75
76
|
end
|
76
77
|
|
@@ -95,6 +96,7 @@ module Eco
|
|
95
96
|
kargs.merge!(input: input) if input_required? || all
|
96
97
|
kargs.merge!(people: people) if people_required? || all
|
97
98
|
kargs.merge!(session: session, options: options)
|
99
|
+
|
98
100
|
keyed ? kargs : kargs.values
|
99
101
|
end
|
100
102
|
|
@@ -104,7 +106,12 @@ module Eco
|
|
104
106
|
# 2. does this, **before** the target `case_name` launch and **after
|
105
107
|
# @return [Eco::API::UseCases::BaseIO]
|
106
108
|
def process_case(case_name, case_type, **params)
|
107
|
-
session.process_case(
|
109
|
+
session.process_case(
|
110
|
+
case_name,
|
111
|
+
io: chained,
|
112
|
+
type: case_type,
|
113
|
+
**params
|
114
|
+
).chained
|
108
115
|
end
|
109
116
|
|
110
117
|
# Does the switch from output to result in a new IO object.
|
@@ -115,6 +122,7 @@ module Eco
|
|
115
122
|
def chained(as: type) # rubocop:disable Naming/MethodParameterName
|
116
123
|
base.tap do |io_base|
|
117
124
|
next unless io_base.output
|
125
|
+
|
118
126
|
case as
|
119
127
|
when :import
|
120
128
|
io_base.output_be_input!
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags < Eco::API::Common::Loaders::UseCase
|
2
|
-
name
|
2
|
+
name 'clean-unknown-tags'
|
3
3
|
type :transform
|
4
4
|
|
5
|
+
require_relative 'cli/clean_unknown_tags_cli'
|
6
|
+
|
5
7
|
REGISTER_TAGS = %w[
|
6
8
|
EVENT INJURY RISK CONTRACTOR PERMIT
|
7
9
|
AUDIT JSEA
|
@@ -11,58 +13,162 @@ class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags < Eco::API::C
|
|
11
13
|
POLICY IDEA REPORTS
|
12
14
|
].freeze
|
13
15
|
|
14
|
-
def main(
|
15
|
-
|
16
|
+
def main(*_args)
|
17
|
+
tune_options!
|
18
|
+
|
16
19
|
people.each do |person|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
update.add(person)
|
20
|
+
update_job.add(person)
|
21
|
+
|
22
|
+
update_filter_tags!(person)
|
23
|
+
update_default_tag!(person)
|
24
|
+
|
25
|
+
clean_unkown_tags!(person)
|
26
|
+
clean_archived_nodes!(person) if clean_archived?
|
25
27
|
end
|
28
|
+
end
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
}
|
30
|
+
def update_job
|
31
|
+
@update_job ||= session.new_job('main', 'update', :update, usecase) do |_job, _job_status|
|
32
|
+
report_archived_cleaned
|
33
|
+
report_unknown_cleaned
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
private
|
36
38
|
|
39
|
+
def known_tag?(value)
|
40
|
+
return false if clean_register_tags? && register_tag?(tag)
|
41
|
+
|
42
|
+
tag?(value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def archived_tag?(value)
|
46
|
+
return false if register_tag?(value)
|
47
|
+
|
48
|
+
archived_node?(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def clean_unkown_tags!(person)
|
52
|
+
person.filter_tags = person.filter_tags.select do |tag|
|
53
|
+
known_tag?(tag).tap do |known|
|
54
|
+
cleaned_unknown_tag!(tag) unless known
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# @note it only targets archived nodes
|
60
|
+
def clean_archived_nodes!(person)
|
61
|
+
person.filter_tags = person.filter_tags.reject do |tag|
|
62
|
+
archived_tag?(tag).tap do |known|
|
63
|
+
cleaned_archived_node!(tag) unless known
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def report_unknown_cleaned
|
69
|
+
report_cleaned(
|
70
|
+
cleaned_unknown_tags,
|
71
|
+
msg: 'Cleaned up the following non existing tags:'
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def report_archived_cleaned
|
76
|
+
report_cleaned(
|
77
|
+
cleaned_archived_nodes,
|
78
|
+
msg: 'Cleaned up the following archived nodes:'
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def clean_register_tags?
|
83
|
+
options.dig(:usecase, :clean_register_tags) || false
|
84
|
+
end
|
85
|
+
|
86
|
+
def clean_archived?
|
87
|
+
options.dig(:usecase, :clean_archived) || false
|
88
|
+
end
|
89
|
+
|
90
|
+
def report_cleaned(data, msg:)
|
91
|
+
return if data.empty?
|
92
|
+
|
93
|
+
cleaned_sorted = data.sort_by {|tag, count| [count * -1, tag]}
|
94
|
+
|
95
|
+
msg << "\n • "
|
96
|
+
msg += cleaned_sorted.map do |tag, count|
|
97
|
+
"'#{tag}' (#{count})"
|
98
|
+
end.join("\n • ")
|
99
|
+
|
100
|
+
log(:info) { msg }
|
101
|
+
data.clear
|
102
|
+
end
|
103
|
+
|
104
|
+
def cleaned_unknown_tag!(tag)
|
105
|
+
cleaned_unknown_tags[tag] ||= 0
|
106
|
+
cleaned_unknown_tags[tag] += 1
|
107
|
+
end
|
108
|
+
|
109
|
+
def cleaned_unknown_tags
|
110
|
+
@cleaned_unknown_tags ||= {}
|
111
|
+
end
|
112
|
+
|
113
|
+
def cleaned_archived_node!(tag)
|
114
|
+
cleaned_archived_nodes[tag] ||= 0
|
115
|
+
cleaned_archived_nodes[tag] += 1
|
116
|
+
end
|
117
|
+
|
118
|
+
def cleaned_archived_nodes
|
119
|
+
@cleaned_archived_nodes ||= {}
|
120
|
+
end
|
121
|
+
|
37
122
|
def default_tag(person)
|
38
123
|
return unless (account = person.account)
|
124
|
+
|
39
125
|
account.default_tag
|
40
126
|
end
|
41
127
|
|
42
|
-
def
|
43
|
-
|
128
|
+
def unknown_tag?(value)
|
129
|
+
!known_tag?(value)
|
44
130
|
end
|
45
131
|
|
46
|
-
def
|
47
|
-
|
132
|
+
def active_node?(value)
|
133
|
+
return false if value.nil?
|
134
|
+
return false unless tagtree.tag?(value)
|
135
|
+
|
136
|
+
!archived_node?(value)
|
48
137
|
end
|
49
138
|
|
50
|
-
def
|
51
|
-
|
139
|
+
def archived_node?(value)
|
140
|
+
return false unless (node = tagtree.node(value))
|
141
|
+
|
142
|
+
node.archived
|
52
143
|
end
|
53
144
|
|
54
145
|
def tag?(value)
|
55
146
|
return false if value.nil?
|
56
147
|
return true if tagtree.tag?(value)
|
57
|
-
|
148
|
+
|
58
149
|
register_tags.any? { |reg| value.upcase == reg }
|
59
150
|
end
|
60
151
|
|
152
|
+
def register_tag?(value)
|
153
|
+
register_tags.include?(value)
|
154
|
+
end
|
155
|
+
|
156
|
+
def register_tags
|
157
|
+
@register_tags ||= self.class::REGISTER_TAGS.compact.map(&:upcase)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Get all the location structures merged into a single one
|
61
161
|
def tagtree
|
62
|
-
@tagtree ||= session.tagtree(
|
162
|
+
@tagtree ||= session.tagtree(
|
163
|
+
live: true,
|
164
|
+
include_archived: true,
|
165
|
+
merge: true
|
166
|
+
)
|
63
167
|
end
|
64
168
|
|
65
|
-
def
|
66
|
-
options.
|
169
|
+
def tune_options!
|
170
|
+
# options.deep_merge!(include: {excluded: true})
|
171
|
+
options.deep_merge!(skip: {api_policies: true})
|
172
|
+
options.deep_merge!(skip: {batch_policy: true})
|
67
173
|
end
|
68
174
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags
|
2
|
+
class Cli < Eco::API::UseCases::Cli
|
3
|
+
str = 'Cleans from filter_tags those tags that are not present in the tagtree '
|
4
|
+
str << '(as per tagtree.json file). '
|
5
|
+
str << 'It will preserve standard register tags of most common registers (i.e. EVENT, RISK).'
|
6
|
+
desc str
|
7
|
+
|
8
|
+
add_option("-clean-register-tags", "Will also try to remove register tags") do |options|
|
9
|
+
options.deep_merge!(usecase: {clean_register_tags: true})
|
10
|
+
end
|
11
|
+
|
12
|
+
add_option("-clean-archived", "Will also try to remove archived tags") do |options|
|
13
|
+
options.deep_merge!(usecase: {clean_archived: true})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -152,7 +152,7 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
152
152
|
|
153
153
|
def cleared_unknown_tag!(tag)
|
154
154
|
cleared_unknown_tags[tag] ||= 0
|
155
|
-
cleared_unknown_tags[tag]
|
155
|
+
cleared_unknown_tags[tag] += 1
|
156
156
|
end
|
157
157
|
|
158
158
|
def cleared_unknown_tags
|
@@ -161,7 +161,7 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
161
161
|
|
162
162
|
def cleared_archived_node!(tag)
|
163
163
|
cleared_archived_nodes[tag] ||= 0
|
164
|
-
cleared_archived_nodes[tag]
|
164
|
+
cleared_archived_nodes[tag] += 1
|
165
165
|
end
|
166
166
|
|
167
167
|
def cleared_archived_nodes
|
@@ -210,6 +210,7 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
210
210
|
|
211
211
|
def default_tag(person)
|
212
212
|
return unless (account = person.account)
|
213
|
+
|
213
214
|
account.default_tag
|
214
215
|
end
|
215
216
|
|
@@ -228,23 +229,27 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
228
229
|
def archived_tag?(value)
|
229
230
|
return false if register_tag?(value)
|
230
231
|
return false unless (node = tagtree.node(value))
|
232
|
+
|
231
233
|
node.archived
|
232
234
|
end
|
233
235
|
|
234
236
|
def tag?(value)
|
235
237
|
return false if value.nil?
|
236
238
|
return true if tagtree.tag?(value)
|
239
|
+
|
237
240
|
register_tags.any? { |reg| value.upcase == reg }
|
238
241
|
end
|
239
242
|
|
240
243
|
def active_node?(value)
|
241
244
|
return false if value.nil?
|
242
245
|
return false unless tagtree.tag?(value)
|
246
|
+
|
243
247
|
!archived_node?(value)
|
244
248
|
end
|
245
249
|
|
246
250
|
def archived_node?(value)
|
247
251
|
return false unless (node = tagtree.node(value))
|
252
|
+
|
248
253
|
node.archived
|
249
254
|
end
|
250
255
|
|
@@ -263,7 +268,7 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
263
268
|
|
264
269
|
def tune_options!
|
265
270
|
# options.deep_merge!(include: {excluded: true})
|
266
|
-
options.deep_merge!(skip:
|
267
|
-
options.deep_merge!(skip:
|
271
|
+
options.deep_merge!(skip: {api_policies: true})
|
272
|
+
options.deep_merge!(skip: {batch_policy: true})
|
268
273
|
end
|
269
274
|
end
|
@@ -8,35 +8,46 @@ module Eco
|
|
8
8
|
attr_reader :options
|
9
9
|
|
10
10
|
def initialize(name, type:, root:, &block)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
invalid_type_err = InvalidType.new(
|
12
|
+
"Invalid type for '#{name}'.",
|
13
|
+
type: type,
|
14
|
+
types: self.class.types
|
15
|
+
)
|
16
|
+
raise invalid_type_err unless self.class.valid_type?(type)
|
17
|
+
|
18
|
+
super()
|
19
|
+
|
20
|
+
self.root = root
|
21
|
+
@callback = block
|
22
|
+
@name = name
|
23
|
+
@type = type
|
17
24
|
@times_launched = 0
|
18
25
|
end
|
19
26
|
|
20
27
|
def source_object
|
21
28
|
return nil unless callback_from_loader?
|
29
|
+
|
22
30
|
callback_self
|
23
31
|
end
|
24
32
|
|
25
33
|
def chainer
|
26
|
-
#
|
34
|
+
# @todo: root is a Eco::API::UseCases that will not point to this new case.
|
27
35
|
# => Moreover, the name and type will be the same as self
|
28
36
|
Eco::API::UseCases::UseCaseChain.new(usecase: self, root: @root)
|
29
37
|
end
|
30
38
|
|
31
39
|
def root=(value)
|
32
|
-
|
40
|
+
msg = "Root should be a Eco::API::UseCases. Given: #{value.class}"
|
41
|
+
raise ArgumentError, msg unless value.is_a?(Eco::API::UseCases)
|
42
|
+
|
33
43
|
@root = value
|
34
44
|
end
|
35
45
|
|
36
46
|
# Actual launch of the usecase
|
37
47
|
# @param io [Eco::API::UseCases::BaseIO] an input/output helper with the necessary parameters.
|
38
48
|
# @param kargs [Hash] hash with symbol keys.
|
39
|
-
# @option kargs [Eco::API::Common::People::Entries, Eco::API::Organization::People] :input
|
49
|
+
# @option kargs [Eco::API::Common::People::Entries, Eco::API::Organization::People] :input
|
50
|
+
# the input data of reference.
|
40
51
|
# @option kargs [Eco::API::Organization::People] :people object.
|
41
52
|
# @option kargs [Eco::API:Session] :session
|
42
53
|
# @option kargs [Hash] :options hash with symbol keys (i.e. behaviour modifiers, cli trackers, filters, etc.)
|
@@ -48,8 +59,10 @@ module Eco
|
|
48
59
|
UseCaseIO.new(**kargs).tap do |uio|
|
49
60
|
@options = uio.options
|
50
61
|
uio.session.logger.debug("#{self.class}: going to process '#{name}'")
|
62
|
+
|
51
63
|
set_session_n_options(uio) if callback_from_loader?
|
52
|
-
|
64
|
+
|
65
|
+
uio.output = callback.call(*uio.params)
|
53
66
|
@times_launched += 1
|
54
67
|
end
|
55
68
|
end
|
@@ -62,12 +75,10 @@ module Eco
|
|
62
75
|
|
63
76
|
protected
|
64
77
|
|
65
|
-
|
66
|
-
@callback
|
67
|
-
end
|
78
|
+
attr_reader :callback
|
68
79
|
|
69
80
|
def callback_self
|
70
|
-
eval("self", callback.binding)
|
81
|
+
eval("self", callback.binding, __FILE__, __LINE__)
|
71
82
|
end
|
72
83
|
|
73
84
|
def callback_from_loader?
|
@@ -78,33 +89,40 @@ module Eco
|
|
78
89
|
# in the use case definition
|
79
90
|
# @note this only works when the use case was defined
|
80
91
|
# via an children class of `Eco::API::Common::Loaders::Base`
|
81
|
-
def set_session_n_options(uio)
|
92
|
+
def set_session_n_options(uio) # rubocop:disable Naming/AccessorMethodName
|
82
93
|
return false unless callback_from_loader?
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
94
|
+
|
95
|
+
opts = uio.options || @options
|
96
|
+
sess = uio.session
|
97
|
+
peo = uio.people
|
98
|
+
ent = uio.input
|
87
99
|
use_case_self = self
|
88
100
|
|
89
101
|
callback_self.instance_eval do
|
90
102
|
@session = sess
|
91
103
|
@options = opts
|
104
|
+
|
92
105
|
if peo
|
93
106
|
@people = peo
|
94
|
-
|
107
|
+
singleton_class.attr_reader(:people) unless respond_to?(:people)
|
95
108
|
end
|
96
109
|
|
97
110
|
if ent # entries/input
|
98
111
|
@input = ent
|
99
|
-
|
112
|
+
singleton_class.attr_reader(:input) unless respond_to?(:input)
|
113
|
+
|
114
|
+
# Below problematic code... usage has cases where entries = (gets assigned)
|
115
|
+
# @entries = ent
|
116
|
+
# singleton_class.attr_reader(:entries) unless respond_to?(:entries)
|
100
117
|
end
|
101
118
|
|
102
119
|
# `self` is the use case itself (when used the Loader)
|
103
|
-
next unless
|
120
|
+
next unless is_a?(Eco::API::Common::Loaders::CaseBase)
|
104
121
|
|
105
122
|
@usecase = use_case_self
|
106
|
-
|
123
|
+
singleton_class.attr_reader(:usecase) unless respond_to?(:usecase)
|
107
124
|
end
|
125
|
+
|
108
126
|
true
|
109
127
|
end
|
110
128
|
end
|
@@ -88,13 +88,6 @@ ASSETS.cli.config do |cnf|
|
|
88
88
|
options.deep_merge!(source: {file: file})
|
89
89
|
end
|
90
90
|
|
91
|
-
desc = "Cleans from filter_tags those tags that are not present in the tagtree (as per tagtree.json file)."
|
92
|
-
desc += " It will preserve standard register tags of most common registers (i.e. EVENT, RISK)."
|
93
|
-
cases.add("-clean-unknown-tags", :transform, desc, case_name: "clean-unknown-tags")
|
94
|
-
.add_option("-clear-register-tags", "Will also try to remove register tags") do |options|
|
95
|
-
options.deep_merge!(usecase: {clear_register_tags: true})
|
96
|
-
end
|
97
|
-
|
98
91
|
desc = "Forces a change of email in the same org. It won't succeed if email taken by an org member user"
|
99
92
|
cases.add("-change-email-from", :sync, desc, case_name: "change-email")
|
100
93
|
|
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.7.
|
4
|
+
version: 2.7.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
@@ -705,6 +705,7 @@ files:
|
|
705
705
|
- lib/eco/api/usecases/default/people/amend.rb
|
706
706
|
- lib/eco/api/usecases/default/people/amend/clean_unknown_tags_case.rb
|
707
707
|
- lib/eco/api/usecases/default/people/amend/clear_abilities_case.rb
|
708
|
+
- lib/eco/api/usecases/default/people/amend/cli/clean_unknown_tags_cli.rb
|
708
709
|
- lib/eco/api/usecases/default/people/amend/refresh_case.rb
|
709
710
|
- lib/eco/api/usecases/default/people/amend/reinvite_sync_case.rb
|
710
711
|
- lib/eco/api/usecases/default/people/amend/reinvite_trans_case.rb
|