eco-helpers 2.0.12 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|