eco-helpers 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/eco/api.rb +1 -0
- data/lib/eco/api/common.rb +1 -0
- data/lib/eco/api/common/class_helpers.rb +33 -0
- data/lib/eco/api/common/people.rb +1 -0
- data/lib/eco/api/common/people/person_attribute_parser.rb +52 -0
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +2 -2
- data/lib/eco/api/common/people/person_parser.rb +16 -10
- data/lib/eco/api/common/version_patches.rb +2 -3
- data/lib/eco/api/common/version_patches/ecoportal_api.rb +4 -0
- data/lib/eco/api/common/version_patches/{base_model.rb → ecoportal_api/base_model.rb} +0 -0
- data/lib/eco/api/common/version_patches/{external_person.rb → ecoportal_api/external_person.rb} +0 -0
- data/lib/eco/api/common/version_patches/{internal_person.rb → ecoportal_api/internal_person.rb} +0 -0
- data/lib/eco/api/common/version_patches/hash.rb +2 -0
- data/lib/eco/api/common/version_patches/hash/deep_merge.rb +34 -0
- data/lib/eco/api/error.rb +133 -0
- data/lib/eco/api/error/handler.rb +19 -0
- data/lib/eco/api/error/handlers.rb +22 -0
- data/lib/eco/api/organization/people.rb +11 -11
- data/lib/eco/api/organization/policy_groups.rb +8 -0
- data/lib/eco/api/policies.rb +26 -3
- data/lib/eco/api/policies/policy.rb +4 -5
- data/lib/eco/api/session.rb +27 -18
- data/lib/eco/api/session/batch.rb +12 -6
- data/lib/eco/api/session/batch/errors.rb +134 -0
- data/lib/eco/api/session/batch/job.rb +213 -0
- data/lib/eco/api/session/batch/jobs.rb +72 -0
- data/lib/eco/api/session/batch/jobs_groups.rb +85 -0
- data/lib/eco/api/session/batch/status.rb +133 -0
- data/lib/eco/api/session/config.rb +36 -14
- data/lib/eco/api/session/config/base_config.rb +2 -0
- data/lib/eco/api/session/config/people.rb +8 -0
- data/lib/eco/api/session/config/post_launch.rb +58 -0
- data/lib/eco/api/session/config/workflow.rb +189 -0
- data/lib/eco/api/session/task.rb +49 -6
- data/lib/eco/api/usecases.rb +137 -2
- data/lib/eco/api/usecases/base_case.rb +20 -8
- data/lib/eco/api/usecases/base_io.rb +97 -0
- data/lib/eco/api/usecases/default_case.rb +19 -0
- data/lib/eco/api/usecases/default_cases.rb +2 -2
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/create_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/delete_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/hris_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/recover_db_case.rb +11 -8
- data/lib/eco/api/usecases/default_cases/refresh_presets_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/reinvite_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/switch_supervisor_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +4 -4
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +3 -3
- data/lib/eco/api/usecases/default_cases/update_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/upsert_case.rb +2 -2
- data/lib/eco/api/usecases/use_case.rb +23 -36
- data/lib/eco/api/usecases/use_case_chain.rb +14 -24
- data/lib/eco/api/usecases/use_case_io.rb +23 -75
- data/lib/eco/assets.rb +11 -11
- data/lib/eco/cli.rb +37 -0
- data/lib/eco/cli/config.rb +63 -1
- data/lib/eco/cli/config/default.rb +15 -0
- data/lib/eco/cli/config/default/filters.rb +69 -0
- data/lib/eco/cli/config/default/input.rb +21 -0
- data/lib/eco/cli/config/default/options.rb +47 -0
- data/lib/eco/cli/config/default/people.rb +39 -0
- data/lib/eco/cli/config/default/usecases.rb +63 -0
- data/lib/eco/cli/config/default/workflow.rb +86 -0
- data/lib/eco/cli/config/input.rb +40 -0
- data/lib/eco/cli/config/options_set.rb +35 -0
- data/lib/eco/cli/config/people_filters.rb +38 -0
- data/lib/eco/cli/config/use_cases.rb +87 -0
- data/lib/eco/cli/scripting/args_helpers.rb +10 -4
- data/lib/eco/cli/scripting/argument.rb +6 -0
- data/lib/eco/language/models/collection.rb +1 -0
- data/lib/eco/version.rb +1 -1
- metadata +32 -12
- data/lib/eco/api/policies/base_policy.rb +0 -14
- data/lib/eco/api/policies/used_policies.rb +0 -37
- data/lib/eco/api/session/batch_job.rb +0 -215
- data/lib/eco/api/session/batch_jobs.rb +0 -62
- data/lib/eco/api/session/batch_status.rb +0 -205
- data/lib/eco/api/session/job_groups.rb +0 -75
- data/lib/eco/api/usecases/use_group.rb +0 -124
- data/lib/eco/cli/config/options.rb +0 -11
@@ -0,0 +1,189 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
class Session
|
4
|
+
class Config
|
5
|
+
class Workflow
|
6
|
+
extend Eco::API::Common::ClassHelpers
|
7
|
+
|
8
|
+
@workflow = {
|
9
|
+
load: {input: nil, people: {get: nil, filter: nil}},
|
10
|
+
usecases: nil,
|
11
|
+
launch_jobs: nil,
|
12
|
+
post_launch: {usecases: nil, launch_jobs: nil},
|
13
|
+
end: nil
|
14
|
+
}
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def stages
|
18
|
+
@stages ||= (@workflow || {}).keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate_stage(stage)
|
22
|
+
"Unknown Workflow stage '#{stage}'. Should be any of #{stages}" unless stages.include?(stage)
|
23
|
+
end
|
24
|
+
|
25
|
+
def titleize(key)
|
26
|
+
str_name = key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
|
27
|
+
str.slice(0).upcase + str.slice(1..-1).downcase
|
28
|
+
end.join("")
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_model(key)
|
32
|
+
raise "Expected Symbol. Given: #{key.class}" unless key.is_a?(Symbol)
|
33
|
+
workflow = @workflow[key]
|
34
|
+
raise "Expected Array. Given #{model.class}" unless !workflow || workflow.is_a?(Hash)
|
35
|
+
|
36
|
+
class_name = titleize(key.to_s)
|
37
|
+
full_class_name = "#{self}::#{class_name}"
|
38
|
+
|
39
|
+
if target_class = resolve_class(full_class_name, exception: false)
|
40
|
+
else
|
41
|
+
target_class = Class.new(Eco::API::Session::Config::Workflow) do
|
42
|
+
@workflow = workflow
|
43
|
+
end
|
44
|
+
self.const_set class_name, target_class
|
45
|
+
end
|
46
|
+
|
47
|
+
target_class
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :config
|
53
|
+
attr_reader :name
|
54
|
+
|
55
|
+
def initialize(name = nil, _parent: self, config:)
|
56
|
+
@config = config
|
57
|
+
@name = name
|
58
|
+
|
59
|
+
@stages = {}
|
60
|
+
@_parent = _parent
|
61
|
+
|
62
|
+
@pending = true
|
63
|
+
# moments
|
64
|
+
@on = nil
|
65
|
+
@before = []
|
66
|
+
@after = []
|
67
|
+
end
|
68
|
+
|
69
|
+
def pending?
|
70
|
+
@pending
|
71
|
+
end
|
72
|
+
|
73
|
+
def skip!
|
74
|
+
@skip = true
|
75
|
+
@pending = false
|
76
|
+
end
|
77
|
+
|
78
|
+
def skip?
|
79
|
+
return @skip if instance_variable_defined?(:@skip)
|
80
|
+
return false if root?
|
81
|
+
@_parent.skip?
|
82
|
+
end
|
83
|
+
|
84
|
+
def for(key = nil)
|
85
|
+
raise "A block should be given." unless block_given?
|
86
|
+
if !key
|
87
|
+
yield(self)
|
88
|
+
else
|
89
|
+
stage(key).for(&Proc.new)
|
90
|
+
end
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
def on(key = nil, &block)
|
95
|
+
raise "A block should be given." unless block
|
96
|
+
if !key
|
97
|
+
@on = block
|
98
|
+
else
|
99
|
+
stage(key).on(&block)
|
100
|
+
end
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
def before(key = nil, &block)
|
105
|
+
raise "A block should be given." unless block
|
106
|
+
if !key
|
107
|
+
@before.push(block)
|
108
|
+
else
|
109
|
+
stage(key).before(&block)
|
110
|
+
end
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
def after(key = nil, &block)
|
115
|
+
raise "A block should be given." unless block
|
116
|
+
if !key
|
117
|
+
@after.push(block)
|
118
|
+
else
|
119
|
+
stage(key).after(&block)
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
def run(key = nil, io:, &block)
|
125
|
+
if key
|
126
|
+
io = stage(key).run(io: io, &block)
|
127
|
+
elsif pending?
|
128
|
+
@before.each {|c| io = c.call(self, io)}
|
129
|
+
|
130
|
+
unless skip?
|
131
|
+
io.session.logger.debug("(Workflow: #{path}) running now")
|
132
|
+
if block
|
133
|
+
io = block.call(self, io)
|
134
|
+
else
|
135
|
+
existing_stages.each {|stg| io = stg.run(io: io)}
|
136
|
+
|
137
|
+
unless ready?
|
138
|
+
msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
|
139
|
+
io.session.logger.debug(msg)
|
140
|
+
end
|
141
|
+
io = @on.call(self, io) if ready?
|
142
|
+
end
|
143
|
+
@pending = false
|
144
|
+
end
|
145
|
+
|
146
|
+
@after.each {|c| io = c.call(self, io)}
|
147
|
+
end
|
148
|
+
io
|
149
|
+
end
|
150
|
+
|
151
|
+
protected
|
152
|
+
|
153
|
+
def path
|
154
|
+
return name if root?
|
155
|
+
"#{@_parent.path}:#{name}"
|
156
|
+
end
|
157
|
+
|
158
|
+
def root?
|
159
|
+
@_parent == self
|
160
|
+
end
|
161
|
+
|
162
|
+
def ready?
|
163
|
+
!!@on
|
164
|
+
end
|
165
|
+
|
166
|
+
def existing_stages
|
167
|
+
# sort defined stages by stage order
|
168
|
+
sorted_keys = self.class.stages & @stages.keys
|
169
|
+
sorted_keys.map {|k| stage(k)}
|
170
|
+
end
|
171
|
+
|
172
|
+
def ready_stages
|
173
|
+
exiting_stages.select {|s| s.ready?}
|
174
|
+
end
|
175
|
+
|
176
|
+
def stages_ready?
|
177
|
+
existing_stages.all? {|s| s.ready?}
|
178
|
+
end
|
179
|
+
|
180
|
+
def stage(key)
|
181
|
+
self.class.validate_stage(key)
|
182
|
+
@stages[key] ||= self.class.get_model(key).new(key, _parent: self, config: config)
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/lib/eco/api/session/task.rb
CHANGED
@@ -15,21 +15,64 @@ module Eco
|
|
15
15
|
Eco::API::Organization::People.new(people)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def people_refresh(people:, include_created: true)
|
19
|
+
ini = people.length
|
20
|
+
if include_created
|
21
|
+
session.job_groups.find_jobs(type: :create).map do |job|
|
22
|
+
people = people.merge(job.people)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
created = people.length - ini
|
27
|
+
msg = "Going to refresh #{people.length} people with server data"
|
28
|
+
msg += " (including #{created} that were created)" if created > 0
|
29
|
+
session.logger.info(msg)
|
30
|
+
status = session.batch.get_people(people, silent: true)
|
31
|
+
entries = status.people
|
32
|
+
|
33
|
+
missing = people.length - entries.length
|
34
|
+
session.logger.error("Missed to obtain #{missing} people during the refresh") if missing > 0
|
35
|
+
|
36
|
+
Eco::API::Organization::People.new(status.people)
|
37
|
+
end
|
38
|
+
|
39
|
+
def search(data, options: {}, silent: true)
|
40
|
+
strict_search = session.config.people.strict_search? && (!options[:search]&.key?(:strict) || options.dig(:search, :strict))
|
41
|
+
|
19
42
|
# to scope people to be fresh data got via api
|
20
|
-
session.logger.info("going to api get entries...")
|
43
|
+
session.logger.info("going to api get #{data.length} entries...")
|
44
|
+
|
21
45
|
status = session.batch.search(data, silent: silent)
|
22
46
|
people = Eco::API::Organization::People.new(status.people)
|
47
|
+
|
23
48
|
# get the supervisors
|
24
|
-
|
49
|
+
supers = people.each_with_object([]) do |person, sup|
|
50
|
+
if sup_id = person.supervisor_id
|
51
|
+
spr = {"id" => sup_id}
|
52
|
+
sup.push(spr) unless sup.include?(spr) || people.person(id: sup_id, external_id: sup_id)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if supers.length > 0
|
57
|
+
session.logger.info("going to api get #{supers.length} current supervisors...")
|
58
|
+
status = session.batch.search(supers, silent: silent)
|
59
|
+
people = people.merge(status.people, strict: strict_search)
|
60
|
+
end
|
61
|
+
|
25
62
|
supers = data.each_with_object([]) do |entry, sup|
|
26
63
|
if entry.respond_to?(:supervisor_id) && !entry.supervisor_id.to_s.strip.empty?
|
64
|
+
sup_id = entry.supervisor_id
|
27
65
|
spr = {"id" => entry.supervisor_id}
|
28
|
-
sup.push(spr) unless sup.include?(spr)
|
66
|
+
sup.push(spr) unless sup.include?(spr) || people.person(id: sup_id, external_id: sup_id)
|
29
67
|
end
|
30
68
|
end
|
31
|
-
|
32
|
-
|
69
|
+
|
70
|
+
if supers.length > 0
|
71
|
+
session.logger.info("going to api get #{supers.length} supervisors as per entries...")
|
72
|
+
status = session.batch.search(supers, silent: silent)
|
73
|
+
people = people.merge(status.people, strict: strict_search)
|
74
|
+
end
|
75
|
+
|
33
76
|
session.logger.info("could get #{people.length} people (out of #{data.length} entries)")
|
34
77
|
people
|
35
78
|
end
|
data/lib/eco/api/usecases.rb
CHANGED
@@ -1,13 +1,148 @@
|
|
1
1
|
module Eco
|
2
2
|
module API
|
3
|
-
|
3
|
+
class UseCases
|
4
|
+
class UnkownCase < Exception
|
5
|
+
def initialize(msg = nil, case_name: nil, type: nil)
|
6
|
+
msg ||= "Unkown case"
|
7
|
+
msg += ". Case name '#{case_name}'" if case_name
|
8
|
+
msg += ". Case type '#{type}'" if type
|
9
|
+
super(msg)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class AmbiguousCaseReference < Exception
|
14
|
+
def initialize(msg = nil, case_name: nil)
|
15
|
+
msg ||= "You must specify type when there are multiple cases with same name"
|
16
|
+
msg += ". Case name '#{case_name}'" if case_name
|
17
|
+
super(msg)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
include Enumerable
|
23
|
+
|
24
|
+
def initialize()
|
25
|
+
@usecases = {}
|
26
|
+
@cache_init = false
|
27
|
+
@cases_by_name = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def length
|
31
|
+
count
|
32
|
+
end
|
33
|
+
|
34
|
+
def empty?
|
35
|
+
count == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def each(params: {}, &block)
|
39
|
+
return to_enum(:each) unless block
|
40
|
+
items.each(&block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def items
|
44
|
+
@usecases.values
|
45
|
+
end
|
46
|
+
|
47
|
+
def add(usecase)
|
48
|
+
raise "Expected Eco::API::UseCases::UseCase object. Given: #{usecase}" if !usecase || !usecase.is_a?(Eco::API::UseCases::UseCase)
|
49
|
+
name = usecase.name
|
50
|
+
type = usecase.type
|
51
|
+
puts "Warning: overriding '#{type.to_s}' case #{name}" if self.defined?(name, type: type)
|
52
|
+
@cache_init = false
|
53
|
+
@usecases[key(name, type)] = usecase
|
54
|
+
usecase
|
55
|
+
end
|
56
|
+
|
57
|
+
def define(name, type:, &block)
|
58
|
+
Eco::API::UseCases::UseCase.new(name, type: type, root: self, &block).tap do |usecase|
|
59
|
+
add(usecase)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def defined?(name, type: nil)
|
64
|
+
return @usecases.key?(key(name, type)) if type
|
65
|
+
name?(name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def name?(name)
|
69
|
+
!!by_name[name]
|
70
|
+
end
|
71
|
+
|
72
|
+
def names
|
73
|
+
by_name.keys
|
74
|
+
end
|
75
|
+
|
76
|
+
def types(name)
|
77
|
+
return nil if !name?(name)
|
78
|
+
by_name[name].map { |usecase| usecase.type }
|
79
|
+
end
|
80
|
+
|
81
|
+
def case(name, type: nil)
|
82
|
+
if type && target_case = @usecases[key(name, type)]
|
83
|
+
return target_case
|
84
|
+
elsif type
|
85
|
+
raise UseCases::UnkownCase.new(case_name: name, type: type)
|
86
|
+
end
|
87
|
+
raise UseCases::UnkownCase.new(case_name: name, type: type) unless cases = by_name[name]
|
88
|
+
raise UseCases::AmbiguousCaseReference.new(case_name: name) if cases.length > 1
|
89
|
+
cases.first
|
90
|
+
end
|
91
|
+
|
92
|
+
# merges cases overriding self for exisint parsers
|
93
|
+
def merge(cases)
|
94
|
+
return self if !cases
|
95
|
+
raise "Expected a Eco::API::UseCases object. Given #{cases.class}" if !cases.is_a?(Eco::API::UseCases)
|
96
|
+
cases_hash = cases.to_h
|
97
|
+
|
98
|
+
@usecases.merge!(cases_hash)
|
99
|
+
|
100
|
+
cases_hash.transform_values do |usecase|
|
101
|
+
usecase.root = self
|
102
|
+
end
|
103
|
+
|
104
|
+
@cache_init = false
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
|
110
|
+
def to_h
|
111
|
+
@usecases
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def by_name
|
117
|
+
init_caches
|
118
|
+
@by_name
|
119
|
+
end
|
120
|
+
|
121
|
+
def init_caches
|
122
|
+
return true if @cache_init
|
123
|
+
@cache_init = true
|
124
|
+
@by_name = @usecases.values.group_by { |usecase| usecase.name }
|
125
|
+
end
|
126
|
+
|
127
|
+
def key(name, type)
|
128
|
+
name.to_s + type.to_s
|
129
|
+
end
|
130
|
+
|
131
|
+
def name(key)
|
132
|
+
key.to_s.split(":").first
|
133
|
+
end
|
134
|
+
|
135
|
+
def type
|
136
|
+
key.to_s.split(":").last&.to_sym
|
137
|
+
end
|
4
138
|
end
|
5
139
|
end
|
6
140
|
end
|
7
141
|
|
8
142
|
require_relative 'usecases/base_case'
|
143
|
+
require_relative 'usecases/default_case'
|
9
144
|
require_relative 'usecases/use_case'
|
10
145
|
require_relative 'usecases/use_case_chain'
|
146
|
+
require_relative 'usecases/base_io'
|
11
147
|
require_relative 'usecases/use_case_io'
|
12
|
-
require_relative 'usecases/use_group'
|
13
148
|
require_relative 'usecases/default_cases'
|
@@ -1,16 +1,28 @@
|
|
1
1
|
module Eco
|
2
2
|
module API
|
3
|
-
|
3
|
+
class UseCases
|
4
4
|
class BaseCase
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
|
6
|
+
class InvalidType < Exception
|
7
|
+
def initialize(msg = nil, type:, types:)
|
8
|
+
msg ||= "Invalid type."
|
9
|
+
msg = "Given type '#{type}'. Valid types: #{types}"
|
10
|
+
super(msg)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
@types = [:import, :filter, :transform, :sync, :export]
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_reader :types
|
18
|
+
|
19
|
+
def valid_type?(type)
|
20
|
+
types.include?(type)
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_type(type)
|
24
|
+
raise InvalidType.new(type: type, types: types) unless valid_type?(type)
|
25
|
+
end
|
14
26
|
end
|
15
27
|
|
16
28
|
end
|