eco-helpers 2.7.12 → 2.7.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -2
- data/Gemfile +2 -0
- data/eco-helpers.gemspec +17 -15
- data/lib/eco/api/common/session/logger.rb +12 -8
- data/lib/eco/api/session/batch/jobs.rb +10 -9
- data/lib/eco/api/usecases/default/people/migrate/cli/remap_tags_cli.rb +23 -0
- data/lib/eco/api/usecases/default/people/migrate/remap_tags_case.rb +269 -0
- data/lib/eco/api/usecases/default/people/migrate.rb +6 -0
- data/lib/eco/api/usecases/default/people.rb +1 -1
- data/lib/eco/api/usecases/default/utils/cli/split_csv_cli.rb +15 -0
- data/lib/eco/api/usecases/default/utils/split_csv_case.rb +34 -0
- data/lib/eco/api/usecases/default/utils.rb +12 -0
- data/lib/eco/api/usecases/default.rb +1 -0
- data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +1 -2
- data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +3 -3
- data/lib/eco/csv/split.rb +114 -0
- data/lib/eco/csv/stream.rb +66 -0
- data/lib/eco/csv.rb +14 -0
- data/lib/eco/language/basic_logger.rb +7 -6
- data/lib/eco/version.rb +1 -1
- metadata +141 -105
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 260621a685a9d1426362308eb8fc12d479f7dc3c5b9702844fcd2c9d6aac90fd
|
4
|
+
data.tar.gz: 62283e9e29d539cc2f475acd4294292efb147c7f6bef2ecfb8e6841f156199e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a45aee37bc0e81dbb89d5bfe9cf6cff2b380797b5c6f115975625206dc444be5096ee9d03a22aa7e7491132290bbc879cd4e246ae2a3eb4430bdcc058e780574
|
7
|
+
data.tar.gz: 1c0e6ab8b9f09bd34ae920945c9d99e2fdbaa3e8be2856ca2edd5f9468368e8d7ff2f4d4c4a799511b4a5cfa83eb5dfddea227e7d7f63394dba09fbc8cc8bb26
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
|
5
|
-
## [2.7.13] - 2024-05-xx
|
4
|
+
## [2.7.13] - 2024-06-13
|
6
5
|
|
7
6
|
### Added
|
7
|
+
- Case `-split-csv`
|
8
|
+
- Case `-remap-tags` on people case
|
9
|
+
|
8
10
|
### Changed
|
11
|
+
- `close_handling_tags_remap_csv` will display table on dry-run too
|
12
|
+
- See `Eco::API::UseCases::GraphQL::Samples::Location::Command::TrackChangedIds`
|
13
|
+
|
9
14
|
### Fixed
|
10
15
|
|
11
16
|
## [2.7.12] - 2024-05-30
|
data/Gemfile
CHANGED
data/eco-helpers.gemspec
CHANGED
@@ -10,13 +10,13 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ["Oscar Segura"]
|
11
11
|
spec.email = ["oscar@ecoportal.co.nz"]
|
12
12
|
spec.date = %q{2018-09-05}
|
13
|
-
spec.summary = %q
|
13
|
+
spec.summary = %q(eco-helpers to manage people api cases)
|
14
14
|
spec.homepage = "https://www.ecoportal.com"
|
15
15
|
spec.licenses = %w[MIT]
|
16
16
|
|
17
17
|
spec.required_ruby_version = '>= 2.7.2'
|
18
18
|
|
19
|
-
spec.files
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
20
|
f.match(%r{^(test|spec|features)/})
|
21
21
|
end
|
22
22
|
|
@@ -25,29 +25,31 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
27
|
spec.add_development_dependency "bundler", ">= 2.4.12", "< 3"
|
28
|
-
spec.add_development_dependency "rspec", ">= 3.12.0", "< 4"
|
29
28
|
spec.add_development_dependency "rake", ">= 13.0.3", "< 14"
|
30
|
-
spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
|
31
29
|
spec.add_development_dependency "redcarpet", ">= 3.6.0", "< 4"
|
30
|
+
spec.add_development_dependency "rspec", ">= 3.12.0", "< 4"
|
31
|
+
spec.add_development_dependency "rubocop", "~> 1"
|
32
|
+
spec.add_development_dependency "rubocop-rake", "~> 0"
|
33
|
+
spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
|
32
34
|
|
33
|
-
spec.add_dependency '
|
34
|
-
spec.add_dependency 'ecoportal-api-v2', '>= 1.1.8', '< 1.2'
|
35
|
-
spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.18', '< 0.4'
|
36
|
-
spec.add_dependency 'ed25519', '>= 1.2'
|
37
|
-
spec.add_dependency 'bcrypt_pbkdf', '>= 1.0'
|
35
|
+
spec.add_dependency 'amatch', '>= 0.4.1', '< 0.5'
|
38
36
|
spec.add_dependency 'aws-sdk-s3', '>= 1.142.0', '< 2'
|
39
37
|
spec.add_dependency 'aws-sdk-ses', '>= 1.58.0', '< 2'
|
38
|
+
spec.add_dependency 'bcrypt_pbkdf', '>= 1.0'
|
39
|
+
spec.add_dependency 'docx', '>= 0.8.0', '< 0.9'
|
40
40
|
spec.add_dependency 'dotenv', '>= 2.8.1', '< 3'
|
41
|
-
spec.add_dependency '
|
42
|
-
spec.add_dependency '
|
43
|
-
spec.add_dependency '
|
41
|
+
spec.add_dependency 'ecoportal-api', '>= 0.9.8', '< 0.10'
|
42
|
+
spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.18', '< 0.4'
|
43
|
+
spec.add_dependency 'ecoportal-api-v2', '>= 1.1.8', '< 1.2'
|
44
|
+
spec.add_dependency 'ed25519', '>= 1.2'
|
45
|
+
spec.add_dependency 'fast_excel', '>= 0.5.0', '< 0.6'
|
44
46
|
spec.add_dependency 'fuzzy_match', '>= 2.1.0', '< 2.2'
|
45
|
-
spec.add_dependency '
|
47
|
+
spec.add_dependency 'hashdiff', '>= 1.1.0', '< 1.2'
|
46
48
|
spec.add_dependency 'jaro_winkler', '>= 1.5.6', '< 1.6'
|
49
|
+
spec.add_dependency 'net-sftp', '>= 4.0.0', '< 5'
|
50
|
+
spec.add_dependency 'net-ssh', '>= 7.2.1', '< 8'
|
47
51
|
spec.add_dependency 'nokogiri', '>= 1.13', '< 1.17'
|
48
52
|
spec.add_dependency 'roo', '>= 2.10.1', '< 2.11'
|
49
53
|
spec.add_dependency 'roo-xls', '>= 1.2.0', '< 1.3'
|
50
|
-
spec.add_dependency 'fast_excel', '>= 0.5.0', '< 0.6'
|
51
|
-
spec.add_dependency 'docx', '>= 0.8.0', '< 0.9'
|
52
54
|
spec.add_dependency 'rubyzip', '>= 2.3.2', '< 2.4'
|
53
55
|
end
|
@@ -3,17 +3,20 @@ module Eco
|
|
3
3
|
module Common
|
4
4
|
module Session
|
5
5
|
class Logger < Eco::Language::BasicLogger
|
6
|
-
TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
|
6
|
+
TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'.freeze
|
7
7
|
|
8
8
|
attr_reader :cache
|
9
9
|
|
10
10
|
def initialize(file_level: ::Logger::DEBUG, log_file: nil, enviro: nil, **kargs)
|
11
11
|
super(**kargs)
|
12
|
-
|
12
|
+
|
13
|
+
msg = "Required Environment object (enviro:). Given: #{enviro.class}"
|
14
|
+
raise ArgumentError, msg if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
|
15
|
+
|
13
16
|
@enviro = enviro
|
14
17
|
@cache = Logger::Cache.new
|
15
18
|
|
16
|
-
if log_file = fetch_log_file(log_file)
|
19
|
+
if (log_file = fetch_log_file(log_file))
|
17
20
|
loggers[:file] = ::Logger.new(log_file).tap do |logger|
|
18
21
|
logger.formatter = format_proc(console: false) do |severity, datetime, msg, formatted_msg|
|
19
22
|
cache.add(severity, datetime, msg, formatted_msg)
|
@@ -34,15 +37,16 @@ module Eco
|
|
34
37
|
private
|
35
38
|
|
36
39
|
def config(attr)
|
37
|
-
return
|
40
|
+
return unless (cnf = @enviro&.config&.logger)
|
41
|
+
|
38
42
|
cnf.send(attr) if cnf.respond_to?(attr)
|
39
43
|
end
|
40
44
|
|
41
45
|
def if_config(attr)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
return if (value = config(attr)).nil?
|
47
|
+
|
48
|
+
yield(value) if block_given?
|
49
|
+
value
|
46
50
|
end
|
47
51
|
|
48
52
|
def fetch_log_file(log_file)
|
@@ -24,7 +24,7 @@ module Eco
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def empty?
|
27
|
-
count
|
27
|
+
count.zero?
|
28
28
|
end
|
29
29
|
|
30
30
|
def each(&block)
|
@@ -90,15 +90,16 @@ module Eco
|
|
90
90
|
# @return [Hash<Eco::API::Session::Batch::Job, Eco::API::Session::Batch::Status>]
|
91
91
|
def launch(simulate: false)
|
92
92
|
each_with_index do |job, idx|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
93
|
+
next unless job.pending?
|
94
|
+
|
95
|
+
status[job] = job_status = job.launch(simulate: simulate)
|
96
|
+
callback = @callbacks[job]
|
97
|
+
callback&.call(job, job_status)
|
98
|
+
Eco::API::Session::Batch::JobsGroups.counter(delay_between_jobs) if !simulate && idx < length - 1
|
99
99
|
end
|
100
100
|
launch(simulate: simulate) if pending?
|
101
|
-
|
101
|
+
|
102
|
+
status
|
102
103
|
end
|
103
104
|
|
104
105
|
def find_jobs(type:)
|
@@ -113,7 +114,7 @@ module Eco
|
|
113
114
|
yield(job, job_status)
|
114
115
|
end
|
115
116
|
self
|
116
|
-
else
|
117
|
+
else # rubocop:disable Naming/MemoizedInstanceVariableName
|
117
118
|
@jobs_status ||= {}
|
118
119
|
end
|
119
120
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Eco::API::UseCases::Default::People::Migrate::RemapTags
|
2
|
+
class Cli < Eco::API::UseCases::Cli
|
3
|
+
desc 'Maps filter_tags and default_tag based on input file'
|
4
|
+
|
5
|
+
callback do |_people, _session, options, _usecase|
|
6
|
+
if (file = SCR.get_file('-remap-tags', required: true, should_exist: true))
|
7
|
+
options.deep_merge!(input: {file: {name: file}})
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
add_option('-remove-source-tag', 'Whether source mapped tags should be removed') do |options|
|
12
|
+
options.deep_merge!(usecase: {remove_source_tag: true})
|
13
|
+
end
|
14
|
+
|
15
|
+
add_option('-clear-unknown-tag', 'Whether unknown tags should be cleared') do |options|
|
16
|
+
options.deep_merge!(usecase: {clear_unknown_tags: true})
|
17
|
+
end
|
18
|
+
|
19
|
+
add_option('-clear-archived-nodes', 'Whether archived nodes should be cleared') do |options|
|
20
|
+
options.deep_merge!(usecase: {clear_archived_nodes: true})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common::Loaders::UseCase
|
2
|
+
name 'remap-tags'
|
3
|
+
type :transform
|
4
|
+
|
5
|
+
require_relative 'cli/remap_tags_cli'
|
6
|
+
|
7
|
+
REGISTER_TAGS = %w[
|
8
|
+
EVENT INJURY RISK CONTRACTOR PERMIT
|
9
|
+
AUDIT JSEA
|
10
|
+
TRAINING INDUCTION
|
11
|
+
MEETING PPE CHEMICAL
|
12
|
+
PLANT ASSET
|
13
|
+
POLICY IDEA REPORTS
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
def main(*_args)
|
17
|
+
tune_options!
|
18
|
+
|
19
|
+
people.each do |person|
|
20
|
+
update_job.add(person)
|
21
|
+
|
22
|
+
update_filter_tags!(person)
|
23
|
+
update_default_tag!(person)
|
24
|
+
clear_unkown_tags!(person) if clear_unknown_tags?
|
25
|
+
clear_archived_nodes!(person) if clear_archived_nodes?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_job
|
30
|
+
@update_job ||= session.new_job('main', 'update', :update, usecase) do |_job, _job_status|
|
31
|
+
report_removed_src_tags
|
32
|
+
report_archived_cleared
|
33
|
+
report_unknown_cleared
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# If the map on `value` exists, it returns the new value,
|
40
|
+
# otherwise mirrors the `value` (to prevent data loss)
|
41
|
+
def apply_map(value)
|
42
|
+
case value
|
43
|
+
when Array
|
44
|
+
value.map {|val| apply_map(val)}
|
45
|
+
when String
|
46
|
+
if (new_tag = id_maps[value])
|
47
|
+
new_tag
|
48
|
+
else
|
49
|
+
value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_filter_tags!(person)
|
55
|
+
mapped_tags = apply_map(person.filter_tags)
|
56
|
+
|
57
|
+
if remove_source_tag?
|
58
|
+
removed = person.filter_tags - mapped_tags
|
59
|
+
removed_src_tag!(*removed)
|
60
|
+
person.filter_tags = mapped_tags
|
61
|
+
else
|
62
|
+
person.filter_tags |= mapped_tags
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# We always map the default_tag
|
67
|
+
def update_default_tag!(person)
|
68
|
+
return unless (account = person.account)
|
69
|
+
|
70
|
+
default_tag = apply_map(account.default_tag)
|
71
|
+
return unless default_tag.nil? || active_node?(default_tag)
|
72
|
+
|
73
|
+
account.default_tag = default_tag
|
74
|
+
end
|
75
|
+
|
76
|
+
# @note it still keeps archived nodes
|
77
|
+
def clear_unkown_tags!(person)
|
78
|
+
person.filter_tags = person.filter_tags.select do |tag|
|
79
|
+
known_tag?(tag).tap do |known|
|
80
|
+
cleared_unknown_tag!(tag) unless known
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @note it only targets archived nodes
|
86
|
+
def clear_archived_nodes!(person)
|
87
|
+
person.filter_tags = person.filter_tags.reject do |tag|
|
88
|
+
archived_node?(tag).tap do |known|
|
89
|
+
cleared_archived_node!(tag) unless known
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def report_removed_src_tags
|
95
|
+
return if removed_src_tags.empty?
|
96
|
+
|
97
|
+
log(:info) {
|
98
|
+
msg = "Here list of the #{removed_src_tags.count} removed source-mapped tags..."
|
99
|
+
msg << "\n • "
|
100
|
+
msg << removed_src_tags.sort.join("\n • ")
|
101
|
+
msg
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
# Clean OLD Tags
|
106
|
+
def report_unknown_cleared
|
107
|
+
report_cleared(cleared_unknown_tags, msg: 'Cleared up the following non existing tags:')
|
108
|
+
end
|
109
|
+
|
110
|
+
def report_archived_cleared
|
111
|
+
report_cleared(cleared_archived_nodes, msg: 'Cleared up the following archived nodes:')
|
112
|
+
end
|
113
|
+
|
114
|
+
# Whether it should remove the original tag
|
115
|
+
# @note we might want to preserve it at the moment, and remove them
|
116
|
+
# at a later stage (i.e. after migrating the pages)
|
117
|
+
def remove_source_tag?
|
118
|
+
options.dig(:usecase, :remove_source_tag) || false
|
119
|
+
end
|
120
|
+
|
121
|
+
# Whether it should clear out any unkonwn tag
|
122
|
+
def clear_unknown_tags?
|
123
|
+
options.dig(:usecase, :clear_unknown_tags) || false
|
124
|
+
end
|
125
|
+
|
126
|
+
# Whether it should clear out any archived node
|
127
|
+
def clear_archived_nodes?
|
128
|
+
options.dig(:usecase, :clear_archived_nodes) || false
|
129
|
+
end
|
130
|
+
|
131
|
+
def report_cleared(data, msg:)
|
132
|
+
return if data.empty?
|
133
|
+
|
134
|
+
cleared_sorted = data.sort_by {|tag, count| [count * -1, tag]}
|
135
|
+
|
136
|
+
msg << "\n • "
|
137
|
+
msg += cleared_sorted.map do |tag, count|
|
138
|
+
"'#{tag}' (#{count})"
|
139
|
+
end.join("\n • ")
|
140
|
+
|
141
|
+
log(:info) { msg }
|
142
|
+
data.clear
|
143
|
+
end
|
144
|
+
|
145
|
+
def removed_src_tag!(*tags)
|
146
|
+
@removed_src_tags = removed_src_tags | tags
|
147
|
+
end
|
148
|
+
|
149
|
+
def removed_src_tags
|
150
|
+
@removed_src_tags ||= []
|
151
|
+
end
|
152
|
+
|
153
|
+
def cleared_unknown_tag!(tag)
|
154
|
+
cleared_unknown_tags[tag] ||= 0
|
155
|
+
cleared_unknown_tags[tag] += 1
|
156
|
+
end
|
157
|
+
|
158
|
+
def cleared_unknown_tags
|
159
|
+
@cleared_unknown_tags ||= {}
|
160
|
+
end
|
161
|
+
|
162
|
+
def cleared_archived_node!(tag)
|
163
|
+
cleared_archived_nodes[tag] ||= 0
|
164
|
+
cleared_archived_nodes[tag] += 1
|
165
|
+
end
|
166
|
+
|
167
|
+
def cleared_archived_nodes
|
168
|
+
@cleared_archived_nodes ||= {}
|
169
|
+
end
|
170
|
+
|
171
|
+
# @note validations on src -> dst location ids isn't done because
|
172
|
+
# we might be in a case where we are moving from old locations to
|
173
|
+
# location ids, but it might be a case where we are mapping an actual
|
174
|
+
# location id to a custom tag as well... so trying to keep this standard.
|
175
|
+
def id_maps
|
176
|
+
@id_maps ||= input_csv.each.with_object({}) do |row, out|
|
177
|
+
from, to = row.fields.to_a.first(2)
|
178
|
+
froms = from.split('|').map(&:strip).map(&:upcase).reject(&:empty?)
|
179
|
+
tos = to.split('|').map(&:strip).map(&:upcase).reject(&:empty?)
|
180
|
+
from = froms.first
|
181
|
+
to = tos.first
|
182
|
+
next if from == to
|
183
|
+
next unless from && to
|
184
|
+
|
185
|
+
out[from] = to
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def input_csv
|
190
|
+
@input_csv ||= Eco::CSV.read(input_file, encoding: input_encoding)
|
191
|
+
end
|
192
|
+
|
193
|
+
def input_encoding
|
194
|
+
options.dig(:input, :file, :encoding) || 'utf-8'
|
195
|
+
end
|
196
|
+
|
197
|
+
def input_file
|
198
|
+
@input_file ||= options.dig(:input, :file, :name).tap do |file|
|
199
|
+
if file.nil?
|
200
|
+
log(:warn) { "No input file specified" }
|
201
|
+
exit(1)
|
202
|
+
elsif File.exist?(file)
|
203
|
+
log(:info) { "Using input file '#{file}'" }
|
204
|
+
else
|
205
|
+
log(:error) { "File not found '#{file}'" }
|
206
|
+
exit(1)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def default_tag(person)
|
212
|
+
return unless (account = person.account)
|
213
|
+
account.default_tag
|
214
|
+
end
|
215
|
+
|
216
|
+
def known_tag?(value)
|
217
|
+
register_tag?(value) || tag?(value)
|
218
|
+
end
|
219
|
+
|
220
|
+
def unknown_tag?(value)
|
221
|
+
!known_tag?(value)
|
222
|
+
end
|
223
|
+
|
224
|
+
def register_tag?(value)
|
225
|
+
register_tags.include?(value)
|
226
|
+
end
|
227
|
+
|
228
|
+
def archived_tag?(value)
|
229
|
+
return false if register_tag?(value)
|
230
|
+
return false unless (node = tagtree.node(value))
|
231
|
+
node.archived
|
232
|
+
end
|
233
|
+
|
234
|
+
def tag?(value)
|
235
|
+
return false if value.nil?
|
236
|
+
return true if tagtree.tag?(value)
|
237
|
+
register_tags.any? { |reg| value.upcase == reg }
|
238
|
+
end
|
239
|
+
|
240
|
+
def active_node?(value)
|
241
|
+
return false if value.nil?
|
242
|
+
return false unless tagtree.tag?(value)
|
243
|
+
!archived_node?(value)
|
244
|
+
end
|
245
|
+
|
246
|
+
def archived_node?(value)
|
247
|
+
return false unless (node = tagtree.node(value))
|
248
|
+
node.archived
|
249
|
+
end
|
250
|
+
|
251
|
+
# Get all the location structures merged into a single one
|
252
|
+
def tagtree
|
253
|
+
@tagtree ||= session.tagtree(
|
254
|
+
live: true,
|
255
|
+
include_archived: true,
|
256
|
+
merge: true
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
def register_tags
|
261
|
+
@register_tags ||= self.class::REGISTER_TAGS.compact.map(&:upcase)
|
262
|
+
end
|
263
|
+
|
264
|
+
def tune_options!
|
265
|
+
# options.deep_merge!(include: {excluded: true})
|
266
|
+
options.deep_merge!(skip: {api_policies: true})
|
267
|
+
options.deep_merge!(skip: {batch_policy: true})
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Eco::API::UseCases::Default::People::Utils::SplitCsv
|
2
|
+
class Cli < Eco::API::UseCases::Cli
|
3
|
+
desc "Splits an input file into multiple ones"
|
4
|
+
|
5
|
+
callback do |_sess, options, _case|
|
6
|
+
file = SCR.get_file(cli_name, required: true, should_exist: true)
|
7
|
+
options.deep_merge!(source: {file: file})
|
8
|
+
end
|
9
|
+
|
10
|
+
add_option("-max-rows", "The max count of rows of the output files") do |options|
|
11
|
+
count = SCR.get_arg("-max-rows", with_param: true)
|
12
|
+
options.deep_merge!(output: {file: {max_rows: count}})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Eco::API::UseCases::Default::People::Utils::SplitCsv < Eco::API::Common::Loaders::UseCase
|
2
|
+
require_relative 'cli/split_csv_cli'
|
3
|
+
|
4
|
+
MAX_ROWS = 15_000
|
5
|
+
|
6
|
+
name "split-csv"
|
7
|
+
type :other
|
8
|
+
|
9
|
+
def main(*_args)
|
10
|
+
Eco::CSV.split(input_file, max_rows: max_rows).each do |file|
|
11
|
+
log(:info) {
|
12
|
+
"Generated file '#{file}'"
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def input_file
|
20
|
+
options.dig(:source, :file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def max_rows
|
24
|
+
max_rows_options || self.class::MAX_ROWS
|
25
|
+
end
|
26
|
+
|
27
|
+
def max_rows_options
|
28
|
+
return nil unless (num = options.dig(:output, :file, :max_rows))
|
29
|
+
|
30
|
+
num = num.to_i
|
31
|
+
num = nil if num.zero?
|
32
|
+
num
|
33
|
+
end
|
34
|
+
end
|
@@ -69,8 +69,7 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
69
69
|
end
|
70
70
|
|
71
71
|
# Generates the file and pushes to the SFTP folder
|
72
|
-
# @note
|
73
|
-
# This is only possible using a draft, which is not that desired.
|
72
|
+
# @note it also displays the mappings on screen
|
74
73
|
# @note the SFTP push only happens if `remote_subfolder` is defined, via:
|
75
74
|
# 1. `options.dig(:sftp, :remote_subfolder)`
|
76
75
|
# 2. `REMOTE_FOLDER` const
|
@@ -25,10 +25,10 @@ class Eco::API::UseCases::GraphQL::Samples::Location
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# Generates the file
|
28
|
-
# @note this method
|
29
|
-
#
|
28
|
+
# @note this method used to only work if we could run cummulative dry-runs to the back-end.
|
29
|
+
# However, after RS P3, as mappings are one-to-one (not many-to-many per row),
|
30
|
+
# we can just display the mappings in dry-run as well.
|
30
31
|
def close_handling_tags_remap_csv
|
31
|
-
return false if simulate?
|
32
32
|
if tags_remap_table.any?
|
33
33
|
puts "REMAP LOC IDs CSV (content):"
|
34
34
|
puts tags_remap_table
|