eco-helpers 2.0.16 → 2.0.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 +125 -6
- data/eco-helpers.gemspec +10 -5
- data/lib/eco-helpers.rb +2 -0
- data/lib/eco/api/common/base_loader.rb +18 -0
- data/lib/eco/api/common/loaders/parser.rb +1 -0
- data/lib/eco/api/common/people/default_parsers.rb +1 -0
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +11 -1
- data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +1 -1
- data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +11 -11
- data/lib/eco/api/common/people/default_parsers/xls_parser.rb +53 -0
- data/lib/eco/api/common/people/entries.rb +1 -0
- data/lib/eco/api/common/people/entry_factory.rb +88 -23
- data/lib/eco/api/common/people/person_entry.rb +5 -2
- data/lib/eco/api/common/people/person_parser.rb +1 -1
- data/lib/eco/api/common/session.rb +1 -0
- data/lib/eco/api/common/session/base_session.rb +2 -0
- data/lib/eco/api/common/session/helpers.rb +30 -0
- data/lib/eco/api/common/session/helpers/prompt_user.rb +34 -0
- data/lib/eco/api/common/session/mailer.rb +0 -1
- data/lib/eco/api/common/session/s3_uploader.rb +0 -1
- data/lib/eco/api/common/session/sftp.rb +0 -1
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +1 -1
- data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +7 -4
- data/lib/eco/api/common/version_patches/exception.rb +11 -4
- data/lib/eco/api/microcases.rb +3 -1
- data/lib/eco/api/microcases/append_usergroups.rb +0 -1
- data/lib/eco/api/microcases/people_cache.rb +2 -2
- data/lib/eco/api/microcases/people_load.rb +2 -2
- data/lib/eco/api/microcases/people_refresh.rb +2 -2
- data/lib/eco/api/microcases/people_search.rb +6 -6
- data/lib/eco/api/microcases/preserve_default_tag.rb +23 -0
- data/lib/eco/api/microcases/preserve_filter_tags.rb +28 -0
- data/lib/eco/api/microcases/preserve_policy_groups.rb +30 -0
- data/lib/eco/api/microcases/set_account.rb +0 -1
- data/lib/eco/api/microcases/with_each.rb +67 -6
- data/lib/eco/api/microcases/with_each_present.rb +4 -2
- data/lib/eco/api/microcases/with_each_starter.rb +4 -2
- data/lib/eco/api/organization.rb +1 -0
- data/lib/eco/api/organization/people.rb +98 -22
- data/lib/eco/api/organization/people_similarity.rb +272 -0
- data/lib/eco/api/organization/person_schemas.rb +5 -1
- data/lib/eco/api/organization/policy_groups.rb +5 -1
- data/lib/eco/api/organization/presets_factory.rb +22 -83
- data/lib/eco/api/organization/presets_integrity.json +6 -0
- data/lib/eco/api/organization/presets_values.json +5 -4
- data/lib/eco/api/organization/tag_tree.rb +33 -0
- data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +0 -30
- data/lib/eco/api/session.rb +20 -28
- data/lib/eco/api/session/batch.rb +25 -7
- data/lib/eco/api/session/config.rb +0 -10
- data/lib/eco/api/session/config/apis.rb +80 -14
- data/lib/eco/api/session/config/people.rb +1 -17
- data/lib/eco/api/usecases.rb +2 -2
- data/lib/eco/api/usecases/base_case.rb +2 -2
- data/lib/eco/api/usecases/base_io.rb +17 -4
- data/lib/eco/api/usecases/default_cases.rb +2 -1
- data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +4 -4
- data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +223 -0
- data/lib/eco/api/usecases/default_cases/clean_unknown_tags_case.rb +37 -0
- data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +2 -3
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +11 -1
- data/lib/eco/api/usecases/default_cases/restore_db_case.rb +1 -2
- data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +1 -1
- data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +1 -1
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +132 -29
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +61 -36
- data/lib/eco/api/usecases/ooze_samples/ooze_update_case.rb +3 -2
- data/lib/eco/cli/config/default/input.rb +61 -8
- data/lib/eco/cli/config/default/options.rb +48 -17
- data/lib/eco/cli/config/default/people.rb +18 -24
- data/lib/eco/cli/config/default/people_filters.rb +3 -3
- data/lib/eco/cli/config/default/usecases.rb +97 -32
- data/lib/eco/cli/config/default/workflow.rb +22 -13
- data/lib/eco/cli/config/help.rb +1 -0
- data/lib/eco/cli/config/options_set.rb +106 -13
- data/lib/eco/cli/config/use_cases.rb +33 -33
- data/lib/eco/cli/scripting/args_helpers.rb +32 -5
- data/lib/eco/csv.rb +4 -2
- data/lib/eco/csv/table.rb +121 -21
- data/lib/eco/data.rb +1 -0
- data/lib/eco/data/crypto/encryption.rb +3 -3
- data/lib/eco/data/files/helpers.rb +6 -4
- data/lib/eco/data/fuzzy_match.rb +201 -0
- data/lib/eco/data/fuzzy_match/array_helpers.rb +75 -0
- data/lib/eco/data/fuzzy_match/chars_position_score.rb +38 -0
- data/lib/eco/data/fuzzy_match/ngrams_score.rb +82 -0
- data/lib/eco/data/fuzzy_match/pairing.rb +95 -0
- data/lib/eco/data/fuzzy_match/result.rb +87 -0
- data/lib/eco/data/fuzzy_match/results.rb +77 -0
- data/lib/eco/data/fuzzy_match/score.rb +49 -0
- data/lib/eco/data/fuzzy_match/stop_words.rb +35 -0
- data/lib/eco/data/fuzzy_match/string_helpers.rb +82 -0
- data/lib/eco/version.rb +1 -1
- metadata +147 -11
- data/lib/eco/api/microcases/refresh_abilities.rb +0 -19
- data/lib/eco/api/organization/presets_reference.json +0 -59
- data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +0 -30
@@ -44,7 +44,11 @@ module Eco
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def policy_group(id_name)
|
47
|
-
|
47
|
+
self[id_name]
|
48
|
+
end
|
49
|
+
|
50
|
+
def [](id_name)
|
51
|
+
@by_id[policy_group_id(id_name)]
|
48
52
|
end
|
49
53
|
|
50
54
|
def user_pg_ids(initial: [], final: [], non_custom: (non_custom_not_used = true; []), preserve_custom: true)
|
@@ -3,6 +3,8 @@ module Eco
|
|
3
3
|
module Organization
|
4
4
|
|
5
5
|
class PresetsFactory
|
6
|
+
ABILITIES = File.join(__dir__, 'presets_values.json')
|
7
|
+
INTEGRITY = File.join(__dir__, 'presets_integrity.json')
|
6
8
|
|
7
9
|
class << self
|
8
10
|
|
@@ -24,44 +26,36 @@ module Eco
|
|
24
26
|
|
25
27
|
end
|
26
28
|
|
27
|
-
|
28
|
-
INTEGRITY = File.join(__dir__, 'presets_integrity.json')
|
29
|
-
DEFAULT_CUSTOM = 'presets_custom.json'
|
30
|
-
DEFAULT_MAP = 'presets_map.json'
|
31
|
-
|
32
|
-
def initialize(presets_custom: DEFAULT_CUSTOM, presets_map: DEFAULT_MAP, enviro: nil, policy_groups: nil)
|
29
|
+
def initialize(enviro: nil, policy_groups: nil)
|
33
30
|
fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
|
34
31
|
@enviro = enviro
|
35
|
-
|
36
|
-
@policy_groups = policy_groups
|
37
|
-
@presets_custom_file = presets_custom || DEFAULT_CUSTOM
|
38
|
-
@presets_map_file = presets_map || DEFAULT_MAP
|
32
|
+
@policy_groups = policy_groups
|
39
33
|
end
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end.compact
|
35
|
+
# @return [Array<String>] all the abilities
|
36
|
+
def keys
|
37
|
+
self.class.abilities
|
38
|
+
end
|
46
39
|
|
47
|
-
|
48
|
-
|
49
|
-
else # option to do not use preset mapping (so just the policy group name)
|
50
|
-
preset_names = names
|
51
|
-
end
|
52
|
-
compile(*preset_names)
|
40
|
+
def valid?(preset)
|
41
|
+
validate(perset).length == 0
|
53
42
|
end
|
54
43
|
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
def validate(preset)
|
45
|
+
[].tap do |errors|
|
46
|
+
if err = preset_errors(preset)
|
47
|
+
errors << "{ '#{key}' preset -> #{err}}"
|
48
|
+
end
|
49
|
+
if err = preset_integrity(preset)
|
50
|
+
errors << "{ '#{key}' preset -> #{err}}"
|
51
|
+
end
|
52
|
+
end
|
58
53
|
end
|
59
54
|
|
60
55
|
private
|
61
56
|
|
62
|
-
def compile(*
|
63
|
-
|
64
|
-
@presets_custom.values_at(*preset_names).compact.reduce({}) do |p1, p2|
|
57
|
+
def compile(*presets)
|
58
|
+
presets.compact.reduce({}) do |p1, p2|
|
65
59
|
merge(p1, p2)
|
66
60
|
end
|
67
61
|
end
|
@@ -79,11 +73,6 @@ module Eco
|
|
79
73
|
end
|
80
74
|
end
|
81
75
|
|
82
|
-
# unsused: only play with the given abilities
|
83
|
-
def empty_model
|
84
|
-
JSON.parse(abilities_model.to_json).transform_values {|v| nil }
|
85
|
-
end
|
86
|
-
|
87
76
|
def preset_errors(preset)
|
88
77
|
return "No preset given" if !preset
|
89
78
|
errors = preset.map do |k, v|
|
@@ -146,7 +135,7 @@ module Eco
|
|
146
135
|
end
|
147
136
|
|
148
137
|
def ability_value_idx(ability, value)
|
149
|
-
abilities_model[ability].index(value)
|
138
|
+
abilities_model[ability].index(value) || -1
|
150
139
|
end
|
151
140
|
|
152
141
|
def abilities_model
|
@@ -163,56 +152,6 @@ module Eco
|
|
163
152
|
@policy_groups
|
164
153
|
end
|
165
154
|
|
166
|
-
def presets_custom
|
167
|
-
return @presets_custom if instance_variable_defined?(:@presets_custom)
|
168
|
-
@presets_custom = nil
|
169
|
-
if @presets_custom_file
|
170
|
-
if (file = File.expand_path(@presets_custom_file)) && File.exists?(file)
|
171
|
-
@presets_custom = JSON.load(File.open(file)).tap do |custom_presets|
|
172
|
-
errors = custom_presets.each_with_object([]) do |(key, preset), errors|
|
173
|
-
if err = preset_errors(preset)
|
174
|
-
errors << "{ '#{key}' preset -> #{err}}"
|
175
|
-
end
|
176
|
-
if err = preset_integrity(preset)
|
177
|
-
errors << "{ '#{key}' preset -> #{err}}"
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
fatal("File '#{file}' contains invalid presets:\n #{errors.join("\n ")}") if errors.length > 0
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def presets_map
|
188
|
-
return @presets_map if instance_variable_defined?(:@presets_map)
|
189
|
-
@presets_map = nil
|
190
|
-
if @presets_map_file
|
191
|
-
if (file = File.expand_path(@presets_map_file)) && File.exists?(file)
|
192
|
-
fatal("Maps file specified without 'presets_custom.json' file. Aborting!") if !presets_custom
|
193
|
-
@presets_map = JSON.load(File.open(file)).tap do |map_presets|
|
194
|
-
|
195
|
-
errors = []
|
196
|
-
if policy_groups.length > 0
|
197
|
-
errors = policy_groups.map do |pg|
|
198
|
-
exists = map_presets[pg.name.downcase] || presets_custom[pg.name.downcase]
|
199
|
-
exists ? nil : "'#{pg.name}'"
|
200
|
-
end.compact
|
201
|
-
|
202
|
-
warn("No maps or no preset for policy group(s): #{errors.join(", ")}") if errors.length > 0
|
203
|
-
end
|
204
|
-
|
205
|
-
errors = map_presets.map do |source, dest|
|
206
|
-
presets_custom[dest] ? nil : "'#{dest}'"
|
207
|
-
end.compact
|
208
|
-
|
209
|
-
warn("Unexisting mapped preset(s): #{errors.uniq.join(", ")}") if errors.length > 0
|
210
|
-
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
155
|
def fatal(msg)
|
217
156
|
raise msg if !@enviro
|
218
157
|
@enviro.logger.fatal(msg)
|
@@ -2,14 +2,15 @@
|
|
2
2
|
"files": [null, "download", "upload", "browse", "administrate"],
|
3
3
|
"data": [null, "view", "update", "administrate", "implement"],
|
4
4
|
"reports": [null, "view", "edit", "administrate"],
|
5
|
+
"pages": [null, "view", "update", "create", "administrate"],
|
6
|
+
"page_editor": [null, "basic", "intermediate", "advanced", "implement"],
|
7
|
+
"registers": [null, "view", "dashboard", "administrate", "implement"],
|
5
8
|
"tasks": [null, "reassign_self", "reassign", "administrate"],
|
6
9
|
"organization": [null, "view", "administrate", "implement"],
|
7
10
|
"person_core": [null, "attach", "view_people_manager", "dashboard"],
|
8
11
|
"person_core_create": [null, "create"],
|
9
12
|
"person_core_edit": [null, "edit"],
|
10
|
-
"person_account": [null, "view", "create", "edit"],
|
11
13
|
"person_details": [null, "view", "edit_public", "view_private", "edit_private"],
|
12
|
-
"
|
13
|
-
"
|
14
|
-
"registers": [null, "view", "dashboard", "administrate", "implement"]
|
14
|
+
"person_account": [null, "view", "create", "edit"],
|
15
|
+
"person_abilities": [null, "view", "edit"]
|
15
16
|
}
|
@@ -42,6 +42,39 @@ module Eco
|
|
42
42
|
init_hashes
|
43
43
|
end
|
44
44
|
|
45
|
+
# Updates the tag of the current tree
|
46
|
+
def tag=(value)
|
47
|
+
@tag = value
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Eco::API::Organization::TagTree]
|
51
|
+
def dup
|
52
|
+
self.class.new(as_json)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Array] with the differences
|
56
|
+
def diff(tagtree, differences: {}, level: 0, **options)
|
57
|
+
require 'hashdiff'
|
58
|
+
Hashdiff.diff(self.as_json, tagtree.as_json, **options.slice(:array_path, :similarity, :use_lcs))
|
59
|
+
end
|
60
|
+
|
61
|
+
def top?
|
62
|
+
depth == -1
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Array[Hash]] where `Hash` is a `node` `{"tag" => TAG, "nodes": Array[Hash]}`
|
66
|
+
def as_json
|
67
|
+
nodes_json = nodes.map {|node| node.as_json}
|
68
|
+
if top?
|
69
|
+
nodes_json
|
70
|
+
else
|
71
|
+
{
|
72
|
+
"tag" => tag,
|
73
|
+
"nodes" => nodes_json
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
45
78
|
# @return [Boolean] `true` if there are tags in the node, `false` otherwise.
|
46
79
|
def empty?
|
47
80
|
@has_tags.empty?
|
@@ -12,7 +12,6 @@ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loader
|
|
12
12
|
people.each do |person|
|
13
13
|
remove_account_when_no_email!(person) if person.email.to_s.empty?
|
14
14
|
person.account.policy_group_ids = defid if no_policy_group_ids?(person)
|
15
|
-
refresh_abilities!(person)
|
16
15
|
end
|
17
16
|
|
18
17
|
warn_account_removal!
|
@@ -40,39 +39,10 @@ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loader
|
|
40
39
|
return !!person.original_doc["account"]
|
41
40
|
end
|
42
41
|
|
43
|
-
def refresh_abilities!(person)
|
44
|
-
return nil if options.dig(:exclude, :abilities)
|
45
|
-
return nil unless account = person.account
|
46
|
-
account.permissions_custom = session.new_preset(person)
|
47
|
-
account.permissions_custom = min_abilities if no_abilities?(person)
|
48
|
-
end
|
49
|
-
|
50
42
|
def no_policy_group_ids?(person)
|
51
43
|
(account = person.account) && account.policy_group_ids.empty?
|
52
44
|
end
|
53
45
|
|
54
|
-
def no_abilities?(person)
|
55
|
-
return true unless account = person.account
|
56
|
-
account.permissions_custom && account.permissions_custom.values.all?(&:nil?)
|
57
|
-
end
|
58
|
-
|
59
|
-
def min_abilities
|
60
|
-
{
|
61
|
-
"files" => "upload",
|
62
|
-
"data" => nil,
|
63
|
-
"reports" => nil,
|
64
|
-
"pages" => "create",
|
65
|
-
"page_editor" => "basic",
|
66
|
-
"registers" => "view",
|
67
|
-
"organization" => nil,
|
68
|
-
"person_core" => "attach",
|
69
|
-
"person_core_edit" => nil,
|
70
|
-
"person_core_create" => nil,
|
71
|
-
"person_details" => "view",
|
72
|
-
"person_account" => nil
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
46
|
def defid
|
77
47
|
@defid ||= policy_groups.to_id([default_group]).compact
|
78
48
|
end
|
data/lib/eco/api/session.rb
CHANGED
@@ -61,28 +61,19 @@ module Eco
|
|
61
61
|
self
|
62
62
|
end
|
63
63
|
|
64
|
-
# Builds the presets using the usergroup ids of the input.
|
65
|
-
# @note for each flag/ability it will take the highest among those mapped for the present usergroups.
|
66
|
-
# @param input [Ecoportal::API::Internal::Person, Array<String>] the array should be of usegroup names or ids.
|
67
|
-
# @return [Hash] with custom presets.
|
68
|
-
def new_preset(input)
|
69
|
-
case input
|
70
|
-
when Ecoportal::API::Internal::Person
|
71
|
-
presets_factory.new(*input&.account&.policy_group_ids)
|
72
|
-
when Array
|
73
|
-
presets_factory.new(*input)
|
74
|
-
else
|
75
|
-
presets_factory.new(input)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
64
|
# Helper to state the abilities that a person should have with given their usergroups
|
80
65
|
def presets_factory
|
81
|
-
@presets_factory ||= Eco::API::Organization::PresetsFactory.new(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
66
|
+
@presets_factory ||= Eco::API::Organization::PresetsFactory.new(enviro: enviro)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Eco::Data::Mapper] the mappings between the internal and external attribute/property names.
|
70
|
+
def fields_mapper
|
71
|
+
return @fields_mapper if instance_variable_defined?(:@fields_mapper)
|
72
|
+
mappings = []
|
73
|
+
if map_file = config.people.fields_mapper
|
74
|
+
mappings = map_file ? file_manager.load_json(map_file) : []
|
75
|
+
end
|
76
|
+
@fields_mapper = Eco::Data::Mapper.new(mappings)
|
86
77
|
end
|
87
78
|
|
88
79
|
# Helper to obtain a EntryFactory
|
@@ -93,17 +84,16 @@ module Eco
|
|
93
84
|
def entry_factory(schema: nil)
|
94
85
|
schema = to_schema(schema) || self.schema
|
95
86
|
return @entry_factories[schema&.id] if @entry_factories.key?(schema&.id)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
mappings = map_file ? file_manager.load_json(map_file) : []
|
87
|
+
unless @entry_factories.empty?
|
88
|
+
@entry_factories[schema&.id] = @entry_factories.values.first.newFactory(schema: schema)
|
89
|
+
return @entry_factories[schema&.id]
|
100
90
|
end
|
101
91
|
|
102
92
|
@entry_factories[schema&.id] = Eco::API::Common::People::EntryFactory.new(
|
103
93
|
enviro,
|
104
94
|
schema: schema,
|
105
95
|
person_parser: config.people.parser,
|
106
|
-
attr_map:
|
96
|
+
attr_map: fields_mapper
|
107
97
|
)
|
108
98
|
end
|
109
99
|
|
@@ -122,11 +112,13 @@ module Eco
|
|
122
112
|
# @param attr [String] type (`Symbol`) or attribute (`String`) to target a specific parser.
|
123
113
|
# @param source [Any] source value to be parsed.
|
124
114
|
# @param phase [Symbol] the phase when this parser should be active.
|
125
|
-
|
115
|
+
# @param phase [Symbol] the phase when this parser should be active.
|
116
|
+
# @return [Object] the parsed attribute.
|
117
|
+
def parse_attribute(attr, source, phase = :internal, deps: {})
|
126
118
|
unless parsers = entry_factory.person_parser
|
127
119
|
raise "There are no parsers defined"
|
128
120
|
end
|
129
|
-
parsers.parse(attr, source, phase)
|
121
|
+
parsers.parse(attr, source, phase, deps: deps)
|
130
122
|
end
|
131
123
|
|
132
124
|
# @see Eco::API::Common::People::EntryFactory#export
|
@@ -146,7 +138,7 @@ module Eco
|
|
146
138
|
# @see Eco::API::Common::People::EntryFactory#new
|
147
139
|
# @return [Eco::API::Common::People::PersonEntry] parsed entry.
|
148
140
|
def new_entry(data, dependencies: {})
|
149
|
-
entry_factory.new(data, dependencies: dependencies)
|
141
|
+
entry_factory(schema: data&.details&.schema_id).new(data, dependencies: dependencies)
|
150
142
|
end
|
151
143
|
|
152
144
|
# @see Eco::API::Common::People::EntryFactory#entries
|
@@ -114,14 +114,16 @@ module Eco
|
|
114
114
|
logger.info(msg) unless silent
|
115
115
|
|
116
116
|
start_slice = Time.now
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
117
|
+
offer_retry_on(Ecoportal::API::Errors::TimeOut) do
|
118
|
+
people_api.batch do |batch|
|
119
|
+
slice.each do |person|
|
120
|
+
batch.public_send(method, person) do |response|
|
121
|
+
faltal("Request with no response") unless !!response
|
122
|
+
status[person] = response
|
123
|
+
end
|
122
124
|
end
|
123
|
-
end
|
124
|
-
end
|
125
|
+
end # end batch
|
126
|
+
end
|
125
127
|
|
126
128
|
iteration += 1
|
127
129
|
done += slice.length
|
@@ -129,6 +131,22 @@ module Eco
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
134
|
+
def offer_retry_on(error_type, retries_left = 3, &block)
|
135
|
+
begin
|
136
|
+
block.call
|
137
|
+
rescue error_type => e
|
138
|
+
raise unless retries_left > 0
|
139
|
+
explanation = "Batch TimeOut. You have #{retries_left} retries left."
|
140
|
+
prompt_user("Do you want to retry (y/N)?", explanation, default: "Y", timeout: 10) do |response|
|
141
|
+
if response.upcase.start_with?("Y")
|
142
|
+
offer_retry_on(error_type, retries_left - 1, &block)
|
143
|
+
else
|
144
|
+
raise
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
132
150
|
def str_stats(start, count)
|
133
151
|
now = Time.now
|
134
152
|
secs = (now - start).round(3)
|
@@ -297,16 +297,6 @@ module Eco
|
|
297
297
|
people.default_schema = name
|
298
298
|
end
|
299
299
|
|
300
|
-
# Specify the file with the account custom abilities presets
|
301
|
-
def presets_custom=(file)
|
302
|
-
people.presets_custom = file
|
303
|
-
end
|
304
|
-
|
305
|
-
# Specify the file with the usergroup to custom presets mapping
|
306
|
-
def presets_map=(file)
|
307
|
-
people.presets_map = file
|
308
|
-
end
|
309
|
-
|
310
300
|
# @see Eco::API::Session::Config::People
|
311
301
|
# @param (see Eco::API::Session::Config::People)
|
312
302
|
# @return [Eco::API::Common::People::PersonParser] parser/serializer for the defined `format`.
|