eco-helpers 2.0.12 → 2.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -73
- data/eco-helpers.gemspec +6 -4
- data/lib/eco-helpers.rb +1 -0
- data/lib/eco/api/common/base_loader.rb +14 -0
- data/lib/eco/api/common/loaders/use_case.rb +1 -1
- 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/person_entry.rb +9 -2
- data/lib/eco/api/common/people/supervisor_helpers.rb +27 -0
- data/lib/eco/api/common/session/file_manager.rb +2 -2
- 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/error.rb +5 -3
- 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/organization.rb +1 -0
- data/lib/eco/api/organization/people.rb +7 -0
- data/lib/eco/api/organization/people_analytics.rb +60 -0
- data/lib/eco/api/organization/presets_factory.rb +116 -93
- data/lib/eco/api/organization/presets_integrity.json +58 -0
- data/lib/eco/api/organization/presets_values.json +5 -4
- data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +0 -30
- data/lib/eco/api/session.rb +1 -20
- data/lib/eco/api/session/batch.rb +42 -10
- data/lib/eco/api/session/batch/job.rb +3 -0
- data/lib/eco/api/session/config.rb +16 -15
- data/lib/eco/api/session/config/api.rb +4 -0
- data/lib/eco/api/session/config/apis.rb +14 -0
- data/lib/eco/api/session/config/files.rb +7 -0
- data/lib/eco/api/session/config/people.rb +3 -19
- data/lib/eco/api/usecases.rb +2 -0
- data/lib/eco/api/usecases/default_cases.rb +4 -1
- data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +161 -0
- data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +76 -0
- data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +2 -3
- data/lib/eco/api/usecases/default_cases/hris_case.rb +14 -8
- 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 +72 -0
- data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +59 -0
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +104 -26
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +62 -36
- data/lib/eco/cli.rb +0 -10
- data/lib/eco/cli/config/default/options.rb +19 -17
- data/lib/eco/cli/config/default/people_filters.rb +3 -3
- data/lib/eco/cli/config/default/usecases.rb +77 -25
- data/lib/eco/cli/config/default/workflow.rb +6 -1
- 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 +30 -3
- data/lib/eco/data.rb +1 -0
- data/lib/eco/data/crypto/encryption.rb +3 -3
- data/lib/eco/data/files/directory.rb +28 -20
- data/lib/eco/data/files/helpers.rb +6 -4
- data/lib/eco/data/fuzzy_match.rb +119 -0
- data/lib/eco/data/fuzzy_match/array_helpers.rb +75 -0
- data/lib/eco/data/fuzzy_match/chars_position_score.rb +37 -0
- data/lib/eco/data/fuzzy_match/ngrams_score.rb +73 -0
- data/lib/eco/data/fuzzy_match/pairing.rb +102 -0
- data/lib/eco/data/fuzzy_match/result.rb +67 -0
- data/lib/eco/data/fuzzy_match/results.rb +53 -0
- data/lib/eco/data/fuzzy_match/score.rb +44 -0
- data/lib/eco/data/fuzzy_match/stop_words.rb +35 -0
- data/lib/eco/data/fuzzy_match/string_helpers.rb +69 -0
- data/lib/eco/version.rb +1 -1
- metadata +86 -10
- 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
@@ -4,112 +4,58 @@ module Eco
|
|
4
4
|
|
5
5
|
class PresetsFactory
|
6
6
|
ABILITIES = File.join(__dir__, 'presets_values.json')
|
7
|
-
|
8
|
-
DEFAULT_MAP = 'presets_map.json'
|
7
|
+
INTEGRITY = File.join(__dir__, 'presets_integrity.json')
|
9
8
|
|
10
|
-
|
11
|
-
@abilities = JSON.load(File.open(ABILITIES))
|
12
|
-
@habilities = @abilities.map do |key, values|
|
13
|
-
h_values = values.map { |v| [v, true] }.to_h
|
14
|
-
[key, h_values]
|
15
|
-
end.to_h
|
9
|
+
class << self
|
16
10
|
|
17
|
-
|
18
|
-
|
11
|
+
def all_abilities(hash = {})
|
12
|
+
Hash[abilities.each_with_object(nil).to_a].merge(hash)
|
13
|
+
end
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
@policy_groups = policy_groups
|
23
|
-
else
|
24
|
-
@policy_groups = Eco::API::Organization::PolicyGroups.new(policy_groups)
|
15
|
+
def abilities_model
|
16
|
+
@abilities_model ||= JSON.load(File.open(ABILITIES))
|
25
17
|
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
def integrity_model
|
20
|
+
@integrity_model ||= JSON.load(File.open(INTEGRITY))
|
21
|
+
end
|
30
22
|
|
31
|
-
|
23
|
+
def abilities
|
24
|
+
@abilities ||= abilities_model.keys
|
25
|
+
end
|
32
26
|
|
33
|
-
|
34
|
-
@policy_groups.to_name(id_name)&.downcase
|
35
|
-
end.compact
|
27
|
+
end
|
36
28
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
compile(*preset_names)
|
29
|
+
def initialize(enviro: nil, policy_groups: nil)
|
30
|
+
fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
|
31
|
+
@enviro = enviro
|
32
|
+
@policy_groups = policy_groups
|
43
33
|
end
|
44
34
|
|
45
35
|
# @return [Array<String>] all the abilities
|
46
36
|
def keys
|
47
|
-
|
37
|
+
self.class.abilities
|
48
38
|
end
|
49
39
|
|
50
|
-
|
51
|
-
|
52
|
-
def init_custom(file = DEFAULT_CUSTOM)
|
53
|
-
@presets_custom = nil
|
54
|
-
|
55
|
-
return if !file
|
56
|
-
file = File.expand_path(file)
|
57
|
-
|
58
|
-
if File.exists?(file)
|
59
|
-
@presets_custom = JSON.load(File.open(file))
|
60
|
-
|
61
|
-
errors = @presets_custom.map do |key, preset|
|
62
|
-
(err = preset_errors(preset)) ? "{ '#{key}' preset -> #{err}}": nil
|
63
|
-
end.compact
|
64
|
-
|
65
|
-
fatal("File '#{file}' contains invalid presets:\n #{errors.join("\n ")}") if errors.length > 0
|
66
|
-
end
|
67
|
-
|
40
|
+
def valid?(preset)
|
41
|
+
validate(perset).length == 0
|
68
42
|
end
|
69
43
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
fatal("Maps file specified without custom presets file. Aborting!") if !@presets_custom
|
78
|
-
@presets_map = JSON.load(File.open(file))
|
79
|
-
|
80
|
-
errors = []
|
81
|
-
if @policy_groups.length > 0
|
82
|
-
errors = @policy_groups.map do |pg|
|
83
|
-
exists = @presets_map[pg.name.downcase] || @presets_custom[pg.name.downcase]
|
84
|
-
exists ? nil : "'#{pg.name}'"
|
85
|
-
end.compact
|
86
|
-
|
87
|
-
warn("No maps or no preset for policy group(s): #{errors.join(", ")}") if errors.length > 0
|
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}}"
|
88
51
|
end
|
89
|
-
|
90
|
-
errors = @presets_map.map do |source, dest|
|
91
|
-
@presets_custom[dest] ? nil : "'#{dest}'"
|
92
|
-
end.compact
|
93
|
-
|
94
|
-
warn("Unexisting mapped preset(s): #{errors.uniq.join(", ")}") if errors.length > 0
|
95
52
|
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
def fatal(msg)
|
100
|
-
raise msg if !@enviro
|
101
|
-
@enviro.logger.fatal(msg)
|
102
|
-
raise msg
|
103
53
|
end
|
104
54
|
|
105
|
-
|
106
|
-
raise msg if !@enviro
|
107
|
-
@enviro.logger.warn(msg)
|
108
|
-
end
|
55
|
+
private
|
109
56
|
|
110
|
-
def compile(*
|
111
|
-
|
112
|
-
@presets_custom.values_at(*preset_names).compact.reduce({}) do |p1, p2|
|
57
|
+
def compile(*presets)
|
58
|
+
presets.compact.reduce({}) do |p1, p2|
|
113
59
|
merge(p1, p2)
|
114
60
|
end
|
115
61
|
end
|
@@ -117,7 +63,7 @@ module Eco
|
|
117
63
|
def merge(preset1, preset2)
|
118
64
|
keys = preset1.keys | preset2.keys
|
119
65
|
|
120
|
-
|
66
|
+
abilities_model.each_with_object({}) do |(key, values), result|
|
121
67
|
next unless keys.include?(key)
|
122
68
|
idx = [
|
123
69
|
values.index(preset1[key]),
|
@@ -127,19 +73,96 @@ module Eco
|
|
127
73
|
end
|
128
74
|
end
|
129
75
|
|
130
|
-
# unsused: only play with the given abilities
|
131
|
-
def empty_model
|
132
|
-
JSON.parse(@abilities.to_json).transform_values {|v| nil }
|
133
|
-
end
|
134
|
-
|
135
76
|
def preset_errors(preset)
|
136
77
|
return "No preset given" if !preset
|
137
78
|
errors = preset.map do |k, v|
|
138
|
-
|
79
|
+
value_exists?(k, v) ? nil : "#{k}:#{v}"
|
139
80
|
end.compact
|
140
|
-
return "
|
81
|
+
return " Unknown: {#{errors.join(", ")}}" if errors.length > 0
|
141
82
|
nil
|
142
83
|
end
|
84
|
+
|
85
|
+
def preset_integrity(preset)
|
86
|
+
preset.each_with_object([]) do |(ability, value), errors|
|
87
|
+
next unless checks = integrity_model[ability]
|
88
|
+
|
89
|
+
suberrors = []
|
90
|
+
|
91
|
+
checks.each do |check|
|
92
|
+
next unless check["value"] == value
|
93
|
+
check["conditions"].each do |cond, targets|
|
94
|
+
case cond
|
95
|
+
when "at_least"
|
96
|
+
targets.each do |other, minimum|
|
97
|
+
unless (ability_value_idx(other, minimum) <= ability_value_idx(other, preset[other]))
|
98
|
+
suberrors << "'#{other}' should be at least '#{minimum}'"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
when "one_of"
|
102
|
+
unless targets.any? {|other, expected| preset[other] == expected}
|
103
|
+
suberrors << targets.each_with_object([]) do |(other, expected), out|
|
104
|
+
out << "'#{other}': '#{expected}'"
|
105
|
+
end.join(", ").yield_self do |msg|
|
106
|
+
"there should be at least one of: {#{msg}}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
warn("Unsuported integrity condition statement '#{cond}' in '#{ability}' with level '#{value}'")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
if suberrors.length > 0
|
116
|
+
errors << "Incorrect value '#{value}' for '#{ability}' - reasons: {#{suberrors.join(", ")}}"
|
117
|
+
end
|
118
|
+
end.yield_self do |errors|
|
119
|
+
" Integrity errors: { #{errors.join(", ")} }" if errors.length > 0
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def integrity_model
|
124
|
+
self.class.integrity_model
|
125
|
+
end
|
126
|
+
|
127
|
+
def value_exists?(ability, value)
|
128
|
+
abilities_model_inverted.dig(ability, value)
|
129
|
+
end
|
130
|
+
|
131
|
+
def abilities_model_inverted
|
132
|
+
@abilities_model_inverted ||= abilities_model.each_with_object({}) do |(key, values), out|
|
133
|
+
out[key] = values.each_with_object({}) {|v, h| h[v] = true }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def ability_value_idx(ability, value)
|
138
|
+
abilities_model[ability].index(value) || -1
|
139
|
+
end
|
140
|
+
|
141
|
+
def abilities_model
|
142
|
+
self.class.abilities_model
|
143
|
+
end
|
144
|
+
|
145
|
+
def policy_groups
|
146
|
+
return @policy_groups if @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
|
147
|
+
@policy_groups ||= @enviro&.api&.policy_groups.to_a
|
148
|
+
|
149
|
+
unless @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
|
150
|
+
@policy_groups = Eco::API::Organization::PolicyGroups.new(@policy_groups)
|
151
|
+
end
|
152
|
+
@policy_groups
|
153
|
+
end
|
154
|
+
|
155
|
+
def fatal(msg)
|
156
|
+
raise msg if !@enviro
|
157
|
+
@enviro.logger.fatal(msg)
|
158
|
+
raise msg
|
159
|
+
end
|
160
|
+
|
161
|
+
def warn(msg)
|
162
|
+
raise msg if !@enviro
|
163
|
+
@enviro.logger.warn(msg)
|
164
|
+
end
|
165
|
+
|
143
166
|
end
|
144
167
|
|
145
168
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"person_core_create": [
|
3
|
+
{ "value": "create", "conditions": {
|
4
|
+
"at_least": {"person_core": "view_people_manager"}
|
5
|
+
}
|
6
|
+
}
|
7
|
+
],
|
8
|
+
"person_core_edit": [
|
9
|
+
{ "value": "edit", "conditions": {
|
10
|
+
"at_least": {"person_core": "view_people_manager"}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
],
|
14
|
+
"person_details": [
|
15
|
+
{ "value": "view", "conditions": {
|
16
|
+
"at_least": {"person_core": "attach"}
|
17
|
+
}
|
18
|
+
},
|
19
|
+
{ "value": "edit_public", "conditions": {
|
20
|
+
"one_of": {
|
21
|
+
"person_core_edit": "edit",
|
22
|
+
"person_core_create": "create"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
},
|
26
|
+
{ "value": "view_private", "conditions": {
|
27
|
+
"at_least": {"person_core": "attach" }
|
28
|
+
}
|
29
|
+
},
|
30
|
+
{ "value": "edit_private", "conditions": {
|
31
|
+
"one_of": {
|
32
|
+
"person_core_edit": "edit",
|
33
|
+
"person_core_create": "create"
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
],
|
38
|
+
"person_account": [
|
39
|
+
{ "value": "view", "conditions": {
|
40
|
+
"at_least": {"person_core": "attach" }
|
41
|
+
}
|
42
|
+
},
|
43
|
+
{ "value": "create", "conditions": {
|
44
|
+
"at_least": {"person_core_create": "create"}
|
45
|
+
}
|
46
|
+
},
|
47
|
+
{ "value": "edit", "conditions": {
|
48
|
+
"at_least": {"person_core_edit": "edit"}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
],
|
52
|
+
"person_abilities": [
|
53
|
+
{ "value": "view", "conditions": {
|
54
|
+
"at_least": {"person_core_edit": "edit"}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
]
|
58
|
+
}
|
@@ -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
|
}
|
@@ -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,9 @@ 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
|
-
presets_custom: file_manager.dir.file(config.people.presets_custom, should_exist: true),
|
83
|
-
presets_map: file_manager.dir.file(config.people.presets_map, should_exist: true),
|
84
|
-
enviro: enviro
|
85
|
-
})
|
66
|
+
@presets_factory ||= Eco::API::Organization::PresetsFactory.new(enviro: enviro)
|
86
67
|
end
|
87
68
|
|
88
69
|
# Helper to obtain a EntryFactory
|
@@ -105,25 +105,57 @@ module Eco
|
|
105
105
|
iterations = (data.length.to_f / per_page).ceil
|
106
106
|
|
107
107
|
Eco::API::Session::Batch::Status.new(enviro, queue: data, method: method).tap do |status|
|
108
|
+
start_time = Time.now
|
109
|
+
start_slice = Time.now; slice = []
|
108
110
|
data.each_slice(per_page) do |slice|
|
109
|
-
msg
|
111
|
+
msg = "starting batch '#{method}' iteration #{iteration}/#{iterations},"
|
112
|
+
msg += " with #{slice.length} entries of #{data.length} -- #{done} done"
|
113
|
+
msg += " (last: #{str_stats(start_slice, slice.length)}; total: #{str_stats(start_time, done)})"
|
110
114
|
logger.info(msg) unless silent
|
111
115
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
start_slice = Time.now
|
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
|
117
124
|
end
|
118
|
-
end
|
119
|
-
end
|
125
|
+
end # end batch
|
126
|
+
end
|
120
127
|
|
121
|
-
iteration
|
122
|
-
done
|
128
|
+
iteration += 1
|
129
|
+
done += slice.length
|
123
130
|
end # next slice
|
124
131
|
end
|
125
132
|
end
|
126
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
|
+
print "Batch TimeOut. You have #{retries_left} retries left. Do you want to retry (y/N)? "
|
140
|
+
if (res = STDIN.gets.chomp) && res[0].downcase == "y"
|
141
|
+
offer_retry_on(error_type, retries_left - 1, &block)
|
142
|
+
else
|
143
|
+
raise
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def str_stats(start, count)
|
149
|
+
now = Time.now
|
150
|
+
secs = (now - start).round(3)
|
151
|
+
if secs > 0.0
|
152
|
+
per_sec = (count.to_f / secs).round(2)
|
153
|
+
"#{secs}s -> #{per_sec} people/s"
|
154
|
+
else
|
155
|
+
" -- "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
127
159
|
end
|
128
160
|
end
|
129
161
|
end
|