eco-helpers 1.5.12 → 2.0.2

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -1
  3. data/eco-helpers.gemspec +31 -29
  4. data/lib/eco/api.rb +1 -1
  5. data/lib/eco/api/common/class_helpers.rb +45 -1
  6. data/lib/eco/api/common/loaders/error_handler.rb +2 -0
  7. data/lib/eco/api/common/loaders/parser.rb +4 -0
  8. data/lib/eco/api/common/loaders/use_case.rb +2 -0
  9. data/lib/eco/api/common/people/person_entry.rb +15 -3
  10. data/lib/eco/api/common/session/logger.rb +9 -1
  11. data/lib/eco/api/common/session/logger/cache.rb +91 -0
  12. data/lib/eco/api/common/session/logger/log.rb +48 -0
  13. data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +9 -0
  14. data/lib/eco/api/microcases/people_cache.rb +7 -0
  15. data/lib/eco/api/microcases/people_load.rb +29 -21
  16. data/lib/eco/api/microcases/people_refresh.rb +6 -0
  17. data/lib/eco/api/microcases/people_search.rb +33 -8
  18. data/lib/eco/api/policies.rb +1 -0
  19. data/lib/eco/api/policies/default_policies.rb +12 -0
  20. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +100 -0
  21. data/lib/eco/api/session.rb +13 -0
  22. data/lib/eco/api/session/batch.rb +0 -3
  23. data/lib/eco/api/session/batch/job.rb +17 -7
  24. data/lib/eco/api/session/config/api.rb +1 -1
  25. data/lib/eco/api/usecases.rb +1 -0
  26. data/lib/eco/api/usecases/ooze_samples.rb +11 -0
  27. data/lib/eco/api/usecases/ooze_samples/ooze_update_case.rb +85 -0
  28. data/lib/eco/version.rb +1 -1
  29. metadata +42 -47
  30. data/lib/eco/api/usecases/backup/append_usergroups_case.rb +0 -36
  31. data/lib/eco/api/usecases/backup/create_case.rb +0 -104
  32. data/lib/eco/api/usecases/backup/create_details_case.rb +0 -31
  33. data/lib/eco/api/usecases/backup/create_details_with_supervisor_case.rb +0 -48
  34. data/lib/eco/api/usecases/backup/hris_case.rb +0 -124
  35. data/lib/eco/api/usecases/backup/set_default_tag_case.rb +0 -49
  36. data/lib/eco/api/usecases/backup/set_supervisor_case.rb +0 -41
  37. data/lib/eco/api/usecases/backup/transfer_account_case.rb +0 -90
  38. data/lib/eco/api/usecases/backup/update_case.rb +0 -112
  39. data/lib/eco/api/usecases/backup/update_details_case.rb +0 -64
  40. data/lib/eco/api/usecases/backup/upsert_case.rb +0 -114
@@ -13,6 +13,15 @@ module Ecoportal
13
13
  original_doc["details"] = JSON.parse(doc["details"])
14
14
  end
15
15
 
16
+ def identify
17
+ if entry
18
+ entry.to_s(:identify)
19
+ else
20
+ str_id = id ? "id: '#{id}'; " : ""
21
+ "#{name}' (#{str_id}ext_id: '#{external_id}'; email: '#{email}')"
22
+ end
23
+ end
24
+
16
25
  end
17
26
  end
18
27
  end
@@ -6,7 +6,14 @@ module Eco
6
6
  # @return [Eco::API::Organization::People] the `People` object with the data.
7
7
  def people_cache(filename = enviro.config.people.cache)
8
8
  logger.info("Going to get all the people via API")
9
+
10
+ start = Time.now
9
11
  people = session.batch.get_people
12
+ secs = Time.now - start
13
+ cnt = people.count
14
+ per_sec = (cnt.to_f / secs).floor
15
+ logger.info("Loaded #{cnt} people in #{secs} seconds (#{per_sec} people/sec)")
16
+
10
17
  file = file_manager.save_json(people, filename, :timestamp)
11
18
  logger.info("#{people.length} people loaded and saved locally to #{file}.")
12
19
  Eco::API::Organization::People.new(people)
@@ -18,27 +18,35 @@ module Eco
18
18
  def people_load(filename = enviro.config.people.cache, modifier: [:newest, :api])
19
19
  modifier = [modifier].flatten
20
20
  load_file = [:file, :newest].any? {|flag| modifier.include?(flag)}
21
- people = case
22
- when filename && load_file
23
- if file = people_load_filename(filename, newest: modifier.include?(:newest))
24
- file_manager.load_json(file).tap do |people|
25
- logger.info("#{people&.length} people loaded from file #{file}") if people.is_a?(Array)
26
- end
27
- else
28
- logger.error("could not find the file #{file_manager.dir.file(filename)}")
29
- exit unless modifier.include?(:api)
30
- people_load(modifier: modifier - [:newest, :file])
31
- end
32
- when modifier.include?(:api)
33
- logger.info("Going to get all the people via API")
34
- session.batch.get_people.tap do |people|
35
- if modifier.include?(:save) && people && people.length > 0
36
- file = file_manager.save_json(people, filename, :timestamp)
37
- logger.info("#{people.length } people saved to file #{file}.")
38
- end
39
- end
40
- end
41
- Eco::API::Organization::People.new(people)
21
+ case
22
+ when filename && load_file
23
+ if file = people_load_filename(filename, newest: modifier.include?(:newest))
24
+ file_manager.load_json(file).tap do |people|
25
+ logger.info("#{people&.length} people loaded from file #{file}") if people.is_a?(Array)
26
+ end
27
+ else
28
+ logger.error("could not find the file #{file_manager.dir.file(filename)}")
29
+ exit unless modifier.include?(:api)
30
+ people_load(modifier: modifier - [:newest, :file])
31
+ end
32
+ when modifier.include?(:api)
33
+ logger.info("Going to get all the people via API")
34
+
35
+ start = Time.now
36
+ session.batch.get_people.tap do |people|
37
+ secs = Time.now - start
38
+ cnt = people.count
39
+ per_sec = (cnt.to_f / secs).floor
40
+ logger.info("Loaded #{cnt} people in #{secs} seconds (#{per_sec} people/sec)")
41
+
42
+ if modifier.include?(:save) && people && people.length > 0
43
+ file = file_manager.save_json(people, filename, :timestamp)
44
+ logger.info("#{people.length } people saved to file #{file}.")
45
+ end
46
+ end
47
+ end.yield_self do |people|
48
+ Eco::API::Organization::People.new(people)
49
+ end
42
50
  end
43
51
 
44
52
  private
@@ -18,7 +18,13 @@ module Eco
18
18
  msg = "Going to refresh #{people.length} people with server data"
19
19
  msg += " (including #{created} that were created)" if created > 0
20
20
  logger.info(msg)
21
+
22
+ start = Time.now
21
23
  entries = session.batch.get_people(people, silent: true)
24
+ secs = Time.now - start
25
+ cnt = entries.count
26
+ per_sec = (cnt.to_f / secs).floor
27
+ logger.info("Re-loaded #{cnt} people (out of #{people.length}) in #{secs} seconds (#{per_sec} people/sec)")
22
28
 
23
29
  missing = people.length - entries.length
24
30
  logger.error("Missed to obtain #{missing} people during the refresh") if missing > 0
@@ -11,24 +11,49 @@ module Eco
11
11
  # @return [Eco::API::Organization::People] the `People` object with the found persons.
12
12
  def people_search(data, options: {}, silent: true)
13
13
  session.logger.info("Going to api get #{data.length} entries...")
14
- status = session.batch.search(data, silent: silent)
15
- people = Eco::API::Organization::People.new(status.people)
16
- session.logger.info("... could get #{people.length} people (out of #{data.length} entries)")
14
+
15
+ start = Time.now
16
+ people = session.batch.search(data, silent: silent).yield_self do |status|
17
+ secs = Time.now - start
18
+ Eco::API::Organization::People.new(status.people).tap do |people|
19
+ cnt = people.count
20
+ per_sec = (cnt.to_f / secs).floor
21
+ msg = "... could get #{cnt} people (out of #{data.length} entries) in #{secs} seconds (#{per_sec} people/sec)"
22
+ session.logger.info(msg)
23
+ end
24
+ end
17
25
 
18
26
  # get the supervisors of found people (current supervisors)
19
27
  supers = people_search_prepare_supers_request(people)
20
28
  if supers.length > 0
21
29
  session.logger.info(" Going to api get #{supers.length} current supervisors...")
22
- status = session.batch.search(supers, silent: silent)
23
- people = people.merge(status.people, strict: micro.strict_search?(options))
30
+ start = Time.now
31
+ people = session.batch.search(supers, silent: silent).yield_self do |status|
32
+ secs = Time.now - start
33
+ found = status.people
34
+ cnt = found.count
35
+ per_sec = (cnt.to_f / secs).floor
36
+ msg = "... could find #{cnt} current supers (out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)"
37
+ session.logger.info(msg)
38
+ people.merge(found, strict: micro.strict_search?(options))
39
+ end
24
40
  end
25
41
 
26
42
  # get the supervisors referred in the input data (future supervisors)
27
43
  supers = people_search_prepare_supers_request(data, people)
28
44
  if supers.length > 0
29
- session.logger.info(" Going to api get #{supers.length} supervisors as per entries...")
30
- status = session.batch.search(supers, silent: silent)
31
- people = people.merge(status.people, strict: micro.strict_search?(options))
45
+ session.logger.info(" Going to api get #{supers.length} supervisors as per input entries...")
46
+ start = Time.now
47
+
48
+ people = session.batch.search(supers, silent: silent).yield_self do |status|
49
+ secs = Time.now - start
50
+ found = status.people
51
+ cnt = found.count
52
+ per_sec = (cnt.to_f / secs).floor
53
+ msg = "... could find #{cnt} input supers (out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)"
54
+ session.logger.info(msg)
55
+ people.merge(found, strict: micro.strict_search?(options))
56
+ end
32
57
  end
33
58
 
34
59
  session.logger.info("Finally got #{people.length} people (out of #{data.length} entries)")
@@ -36,3 +36,4 @@ module Eco
36
36
  end
37
37
 
38
38
  require_relative 'policies/policy'
39
+ require_relative 'policies/default_policies'
@@ -0,0 +1,12 @@
1
+ module Eco
2
+ module API
3
+ class Policies
4
+ class DefaultPolicies < Eco::API::Policies
5
+ autoloads_children_of "Eco::API::Common::Loaders::Policy"
6
+ autoload_namespace "Eco::API::Policies::DefaultPolicies"
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ require_relative 'default_policies/99_user_access_policy'
@@ -0,0 +1,100 @@
1
+ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loaders::Policy
2
+ name "default-user-access"
3
+
4
+ attr_reader :session, :options
5
+ attr_accessor :account_removed_count
6
+
7
+ def main(people, session, options, policy, job)
8
+ @session = session; @options = options
9
+
10
+ self.account_removed_count = 0
11
+
12
+ people.each do |person|
13
+ remove_account_when_no_email!(person) if person.email.to_s.empty?
14
+ person.account.policy_group_ids = [defid] if no_policy_group_ids?(person)
15
+ refresh_abilities!(person.account)
16
+ end
17
+
18
+ warn_account_removal!
19
+ end
20
+
21
+ private
22
+
23
+ def warn_account_removal!
24
+ if account_removed_count > 0
25
+ msg = "Removed account to #{account_removed_count} people"
26
+ session.logger.warn(msg)
27
+ end
28
+ end
29
+
30
+ def remove_account_when_no_email!(person)
31
+ if person.account
32
+ account_removed_count += 1 if had_account?(person)
33
+ person.account = nil
34
+ end
35
+ end
36
+
37
+ def had_account?(person)
38
+ return false if person.new?
39
+ return false if person.account_added?
40
+ return !!person.original_doc["account"]
41
+ end
42
+
43
+ def provision_basic_level!(person)
44
+ if account = person.account
45
+
46
+ unless options.dig(:exclude, :abilities)
47
+ account.permissions_custom = session.new_preset(person)
48
+
49
+ if no_abilities?(person)
50
+ account.permissions_custom = min_abilities
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ def refresh_abilities!(account)
58
+ return nil unless account
59
+
60
+ end
61
+
62
+ def no_policy_group_ids?(person)
63
+ (account = person.account) && account.policy_group_ids.empty?
64
+ end
65
+
66
+ def no_abilities?(person)
67
+ person.account.permissions_custom &&
68
+ person.account.permissions_custom.values.all?(&:nil?)
69
+ end
70
+
71
+ def min_abilities
72
+ {
73
+ "files" => "upload",
74
+ "data" => nil,
75
+ "reports" => nil,
76
+ "pages" => "create",
77
+ "page_editor" => "basic",
78
+ "registers" => "view",
79
+ "organization" => nil,
80
+ "person_core" => "attach",
81
+ "person_core_edit" => nil,
82
+ "person_core_create" => nil,
83
+ "person_details" => "view",
84
+ "person_account" => nil
85
+ }
86
+ end
87
+
88
+ def defid
89
+ @defid ||= policy_groups.to_id(default_group)
90
+ end
91
+
92
+ def default_group
93
+ session.config.people.default_usergroup
94
+ end
95
+
96
+ def policy_groups
97
+ session.policy_groups
98
+ end
99
+
100
+ end
@@ -187,6 +187,8 @@ module Eco
187
187
  end
188
188
 
189
189
  # Does merge `Eco::API::UseCases::DefaultCases` with the custom cases.
190
+ # @note
191
+ # - the order matters, as a default usecase can be redefined by a custom one with same name
190
192
  # @return [Eco::API::UseCases]
191
193
  def usecases
192
194
  @usecases ||= config.usecases.dup.tap do |cases|
@@ -195,6 +197,17 @@ module Eco
195
197
  end
196
198
  end
197
199
 
200
+ # Does merge `Eco::API::Policies::DefaultPolicies` with the custom policies.
201
+ # @note
202
+ # - the default policies are added at the end (meaning they will run after the custom policies)
203
+ # @return [Eco::API::Policies]
204
+ def policies
205
+ @policies ||= config.policies.dup.tap do |policies|
206
+ default_policies = Eco::API::Policies::DefaultPolicies.new
207
+ policies.merge(default_policies)
208
+ end
209
+ end
210
+
198
211
  # Set of helpers to simplify your code
199
212
  # @see Eco::API::MicroCases
200
213
  # @return [Eco::API::MicroCases]
@@ -88,10 +88,7 @@ module Eco
88
88
 
89
89
  def get(params: {}, silent: false)
90
90
  fatal "cannot batch get without api connnection, please provide a valid api connection!" unless people_api = api&.people
91
-
92
91
  params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params)
93
- client = people_api.client
94
-
95
92
  return people_api.get_all(params: params, silent: silent)
96
93
  end
97
94
 
@@ -71,12 +71,6 @@ module Eco
71
71
  @subjobs ||= Eco::API::Session::Batch::Jobs.new(enviro, name: "childs-of:#{self.name}")
72
72
  end
73
73
 
74
- def subjobs_add(name = "ad-hoc:job-from:#{self.name}", usecase: self.usecase, &block)
75
- dup(name, usecase: usecase).tap do |subjob|
76
- subjobs.add(subjob, &block)
77
- end
78
- end
79
-
80
74
  # @return [Boolean] `true` if the current batch job is a result of an error_handler
81
75
  def error_handler?
82
76
  usecase? && usecase.is_a?(Eco::API::Error::Handler)
@@ -211,6 +205,7 @@ module Eco
211
205
  end
212
206
 
213
207
  msg << status.errors.message unless !status
208
+ msg << subjobs_summary
214
209
  end
215
210
  end.join("\n")
216
211
  end
@@ -238,7 +233,7 @@ module Eco
238
233
  # Applies the changes introduced by api policies
239
234
  def apply_policies(pre_queue)
240
235
  people(pre_queue).tap do |entries|
241
- policies = session.config.policies
236
+ policies = session.policies
242
237
  unless policies.empty? || options.dig(:skip, :api_policies)
243
238
  policies.launch(people: entries, session: session, options: options, job: self)
244
239
  end
@@ -307,6 +302,21 @@ module Eco
307
302
  file_manager.save_json(requests, file, :timestamp)
308
303
  end
309
304
 
305
+ # Adds a job tied to the current job
306
+ # Used with error handlers that need their own job to run
307
+ def subjobs_add(name = "ad-hoc:job-from:#{self.name}", usecase: self.usecase, &block)
308
+ dup(name, usecase: usecase).tap do |subjob|
309
+ subjobs.add(subjob, &block)
310
+ end
311
+ end
312
+
313
+ def subjobs_summary
314
+ return "" unless subjobs.count > 0
315
+ [].tap do |msg|
316
+ subjobs.map {|subjob| msg << subjob.summary}
317
+ end.join("\n")
318
+ end
319
+
310
320
  end
311
321
  end
312
322
  end
@@ -142,7 +142,7 @@ module Eco
142
142
  when :v1
143
143
  klass.new(external_key, host: host, logger: logger)
144
144
  when :v2
145
- klass.new(user_key: user_key, org_key: external_key, logger: logger)
145
+ klass.new(user_key: user_key, org_key: external_key, host: host, logger: logger)
146
146
  end.tap do |api|
147
147
  unless !api || log_connection?
148
148
  @logger.info("Created api#{self.version(version)} connection on '#{name}' enviro, pointing to '#{host}' in '#{mode}' mode")
@@ -160,3 +160,4 @@ require_relative 'usecases/use_case_chain'
160
160
  require_relative 'usecases/base_io'
161
161
  require_relative 'usecases/use_case_io'
162
162
  require_relative 'usecases/default_cases'
163
+ require_relative 'usecases/ooze_samples'
@@ -0,0 +1,11 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ require_relative 'ooze_samples/ooze_update_case'
@@ -0,0 +1,85 @@
1
+ class Eco::API::UseCases::OozeSamples::OozeUpdateCase < Eco::API::Common::Loaders::UseCase
2
+ name "single-ooze-case"
3
+ type :other
4
+
5
+ attr_reader :session, :options, :usecase
6
+
7
+ SAVE_PATCH = "ooze_patch_update.json"
8
+
9
+ def main(session, options, usecase)
10
+ @session = session; @options = options; @usecase = usecase
11
+ yield
12
+ end_script!
13
+ end
14
+
15
+ private
16
+
17
+ def end_script!
18
+ exit_if_no_changes!
19
+ backup_patch!
20
+ launch_request unless options[:simulate]
21
+ exit(0)
22
+ end
23
+
24
+ def ooze_id
25
+ options.dig(:source, :ooze_id)
26
+ end
27
+
28
+ def ooze
29
+ @ooze ||= apiv2.pages.get(ooze_id).tap do |ooze|
30
+ if ooze
31
+ logger.info("Got ooze '#{ooze_id}': '#{ooze.name}'")
32
+ else
33
+ logger.error("Could not get ooze '#{ooze_id}'")
34
+ exit(1)
35
+ end
36
+ end
37
+ end
38
+
39
+ def launch_request
40
+ prompt_to_confirm!
41
+
42
+ apiv2.pages.update(ooze).tap do |response|
43
+ if response.success?
44
+ logger.info("All went OK")
45
+ else
46
+ logger.error(response.body)
47
+ end
48
+ end
49
+ end
50
+
51
+ def exit_if_no_changes!
52
+ unless changes = !!patch_doc["page"]
53
+ logger.warn "No Changes!!"
54
+ exit(0)
55
+ end
56
+ end
57
+
58
+ def apiv2
59
+ @apiv2 ||= session.api(version: :oozes)
60
+ end
61
+
62
+ def patch_doc(renew: false)
63
+ return @patch_doc if @patch_doc && !renew
64
+ @patch_doc = apiv2.pages.get_body(ooze)
65
+ end
66
+
67
+ def backup_patch!
68
+ # store the request
69
+ File.open(SAVE_PATCH, "w") do |file|
70
+ #file << (patch_doc || {}).to_json
71
+ file << JSON.pretty_generate(patch_doc || {})
72
+ end
73
+ puts "Saved patch at: #{File.expand_path(SAVE_PATCH)}"
74
+ end
75
+
76
+ def logger
77
+ session.logger
78
+ end
79
+
80
+ def prompt_to_confirm!
81
+ print "\nDo you want to proceed (y/N)? "
82
+ exit(1) unless $stdin.gets.chomp.to_s.downcase == "y"
83
+ end
84
+
85
+ end