eco-helpers 1.5.14 → 1.5.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2627cbc4d42e91e131e891cc4248895660a62bab2c331b43ac8ad3cd28b9cdee
4
- data.tar.gz: fb2c29b13a67114ce8bbfbd16b271519896c201ec58cb9fd37b48db238abb014
3
+ metadata.gz: 71bf87e88b7a707a7684879b5462db11da003360d353d513005d169e77eaa033
4
+ data.tar.gz: 53fe5d42e0be580d0903ddd72e02b014ca113daafe8b37d073481a769deceb7f
5
5
  SHA512:
6
- metadata.gz: 6da008ea99e2e6e323afcfbc0be117dd56402b95be100a68d808d3b4e81537def757fb66418fc0028492ea2e12ac74def8d4c6c47a7d05589bac3814ce9e10d9
7
- data.tar.gz: 78af32b3b9f4725211baf6e458db91c064f49f25814bbda7177fe61af1b453597d658f1d734e155c8ebeb863aabdd36a0b6b81a9fcd972c6d92f2911f05ac11f
6
+ metadata.gz: 36db363c1aef9dac9f5fe0ca874c5d6e8dd39c89fbc7326fc66975ac12b5282288d6ba6c1449aea457c9831aacfbfe0529a53490389fc72f1f0ede956e35b9eb
7
+ data.tar.gz: 17ca4ae2ce8acde161e94f203eb643d405d33210972eec1bbbc3598f50f7b7015a94f9a81c50d64bafb0a42c9066464d421f6eb491e15a17c531753aa64ff59c
data/CHANGELOG.md CHANGED
@@ -1,7 +1,24 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [1.5.14] - 2021-02-xx
4
+ ## [1.5.15] - 2021-02-xx
5
+
6
+ ### Added
7
+ - `Eco::API::Common::ClassHelpers` added support for class methods inheritance
8
+ - this is key to be able to define usecase models to inherit from
9
+ - `Eco::API::UseCases::OozeSamples::OozeUpdateCase`: added this sample to inherit from (simplifying use cases code)
10
+ - `Eco::API::Common::ClassHelpers` added inheritable attribute values
11
+ - added benchmarking to people loaders:
12
+ - `Eco::API::MicroCases#people_load`
13
+ - `Eco::API::MicroCases#people_cache`
14
+ - `Eco::API::MicroCases#people_search`
15
+ - `Eco::API::MicroCases#refresh`
16
+
17
+ ### Changed
18
+ ### Fixed
19
+ - `Eco::API::Policies::DefaultPolicies::UserAccess` typos in default api policy
20
+
21
+ ## [1.5.14] - 2021-02-05
5
22
 
6
23
  ### Added
7
24
  - `Eco::API::Policies::DefaultPolicies` policies that are run always (after the custom policies)
@@ -3,7 +3,7 @@ module Eco
3
3
  module Common
4
4
  module ClassHelpers
5
5
 
6
- # Creates an class and instance object methods with name `name` to resolve `klass` name
6
+ # Creates a class and instance object methods with name `name` to resolve `klass` name
7
7
  def class_resolver(name, klass)
8
8
  define_singleton_method(name) { resolve_class(klass) }
9
9
  define_method(name) { self.class.resolve_class(klass) }
@@ -39,6 +39,15 @@ module Eco
39
39
  end.join("")
40
40
  end
41
41
 
42
+ # Helper to create an instance variable `name`
43
+ # @param [String, Symbol] the name of the variable
44
+ # @reutrn [String] the name of the created instance variable
45
+ def instance_variable_name(name)
46
+ str = name.to_s
47
+ str = "@#{str}" unless str.start_with?("@")
48
+ str
49
+ end
50
+
42
51
  # If the class for `name` exists, it returns it. Otherwise it generates it.
43
52
  # @param name [String, Symbol] the name of the new class
44
53
  # @param inherits [Class] the parent class to _inherit_ from
@@ -92,6 +101,41 @@ module Eco
92
101
  descendants(parent_class: parent_class, direct: direct).length > 0
93
102
  end
94
103
 
104
+ # Keeps track on class instance variables that should be inherited by child classes.
105
+ # @note
106
+ # - subclasses will inherit the value as is at that moment
107
+ # - any change afterwards will be only on the specific class (in line with class instance variables)
108
+ # - adapted from https://stackoverflow.com/a/10729812/4352306
109
+ # TODO: this separates the logic of the method to the instance var. Think if would be possible to join them somehow.
110
+ def inheritable_class_vars(*vars)
111
+ @inheritable_class_vars ||= [:inheritable_class_vars]
112
+ @inheritable_class_vars += vars
113
+ end
114
+
115
+ # Builds the attr_reader and attr_writer of `attrs` and registers the associated instance variable as inheritable.
116
+ def inheritable_attrs(*attrs)
117
+ attrs.each do |attr|
118
+ class_eval %(
119
+ class << self; attr_accessor :#{attr} end
120
+ )
121
+ end
122
+ inheritable_class_vars(*attrs)
123
+ end
124
+
125
+ # This callback method is called whenever a subclass of the current class is created.
126
+ # @note
127
+ # - values of the instance variables are copied as they are (no dups or clones)
128
+ # - the above means: avoid methods that change the state of the mutable object on it
129
+ # - mutating methods would reflect the changes on other classes as well
130
+ # - therefore, `freeze` will be called on the values that are inherited.
131
+ def inherited(subclass)
132
+ inheritable_class_vars.each do |var|
133
+ instance_var = instance_variable_name(var)
134
+ value = instance_variable_get(instance_var)
135
+ subclass.instance_variable_set(instance_var, value.freeze)
136
+ end
137
+ end
138
+
95
139
  end
96
140
  end
97
141
  end
@@ -16,6 +16,8 @@ module Eco
16
16
  end
17
17
  end
18
18
 
19
+ inheritable_class_vars :error
20
+
19
21
  def initialize(handlers)
20
22
  raise "Expected Eco::API::Policies. Given #{handlers.class}" unless handlers.is_a?(Eco::API::Error::Handlers)
21
23
  handlers.on(self.error, &self.method(:main))
@@ -60,6 +60,8 @@ module Eco
60
60
  end
61
61
  end
62
62
 
63
+ private
64
+
63
65
  # Helper to obtain the current internal named attributes of the data
64
66
  # @param source_data [Array<String>, Hash] if `Array` those are already the `keys`, if `Hash` it gets the `keys`
65
67
  # @return [Array<String>] `keys` of `source_data`
@@ -76,6 +78,8 @@ module Eco
76
78
 
77
79
  end
78
80
 
81
+ inheritable_class_vars :attribute
82
+
79
83
  def initialize(person_parser)
80
84
  raise "Expected Eco::API::Common::People::PersonParser. Given #{policies.class}" unless person_parser.is_a?(Eco::API::Common::People::PersonParser)
81
85
  person_parser.define_attribute(self.attribute, dependencies: self.class.dependencies) do |attr_parser|
@@ -14,6 +14,8 @@ module Eco
14
14
  end
15
15
  end
16
16
 
17
+ inheritable_class_vars :type
18
+
17
19
  def initialize(usecases)
18
20
  raise "Expected Eco::API::UseCases. Given #{usecases.class}" unless usecases.is_a?(Eco::API::UseCases)
19
21
  usecases.define(self.name, type: self.type, &self.method(:main))
@@ -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)")
@@ -10,8 +10,8 @@ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loader
10
10
  self.account_removed_count = 0
11
11
 
12
12
  people.each do |person|
13
- remove_account_when_no_email!(person) if person.email.to_s.empty?
14
- account.policy_group_ids = [defid] if no_policy_group_ids?(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
15
  refresh_abilities!(person.account)
16
16
  end
17
17
 
@@ -93,7 +93,7 @@ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loader
93
93
  session.config.people.default_usergroup
94
94
  end
95
95
 
96
- def pgs
96
+ def policy_groups
97
97
  session.policy_groups
98
98
  end
99
99
 
@@ -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
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "1.5.14"
2
+ VERSION = "1.5.15"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.14
4
+ version: 1.5.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -405,6 +405,8 @@ files:
405
405
  - lib/eco/api/usecases/default_cases/update_case.rb
406
406
  - lib/eco/api/usecases/default_cases/update_details_case.rb
407
407
  - lib/eco/api/usecases/default_cases/upsert_case.rb
408
+ - lib/eco/api/usecases/ooze_samples.rb
409
+ - lib/eco/api/usecases/ooze_samples/ooze_update_case.rb
408
410
  - lib/eco/api/usecases/use_case.rb
409
411
  - lib/eco/api/usecases/use_case_chain.rb
410
412
  - lib/eco/api/usecases/use_case_io.rb