eco-helpers 0.6.0
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 +7 -0
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/README.md +20 -0
- data/eco-helpers.gemspec +34 -0
- data/lib/eco-helpers.rb +15 -0
- data/lib/eco/api.rb +13 -0
- data/lib/eco/api/common.rb +10 -0
- data/lib/eco/api/common/people.rb +17 -0
- data/lib/eco/api/common/people/base_parser.rb +16 -0
- data/lib/eco/api/common/people/default_parsers.rb +40 -0
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
- data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
- data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
- data/lib/eco/api/common/people/entries.rb +120 -0
- data/lib/eco/api/common/people/person_entry.rb +380 -0
- data/lib/eco/api/common/people/person_factory.rb +114 -0
- data/lib/eco/api/common/people/person_modifier.rb +62 -0
- data/lib/eco/api/common/people/person_parser.rb +140 -0
- data/lib/eco/api/common/people/types.rb +47 -0
- data/lib/eco/api/common/session.rb +15 -0
- data/lib/eco/api/common/session/base_session.rb +46 -0
- data/lib/eco/api/common/session/environment.rb +47 -0
- data/lib/eco/api/common/session/file_manager.rb +90 -0
- data/lib/eco/api/common/session/logger.rb +105 -0
- data/lib/eco/api/common/session/mailer.rb +92 -0
- data/lib/eco/api/common/session/s3_uploader.rb +110 -0
- data/lib/eco/api/common/version_patches.rb +11 -0
- data/lib/eco/api/common/version_patches/external_person.rb +11 -0
- data/lib/eco/api/eco_faker.rb +59 -0
- data/lib/eco/api/organization.rb +13 -0
- data/lib/eco/api/organization/account.rb +23 -0
- data/lib/eco/api/organization/people.rb +118 -0
- data/lib/eco/api/organization/policy_groups.rb +51 -0
- data/lib/eco/api/organization/preferences.rb +28 -0
- data/lib/eco/api/organization/preferences_reference.json +23 -0
- data/lib/eco/api/organization/presets.rb +138 -0
- data/lib/eco/api/organization/presets_backup.rb +220 -0
- data/lib/eco/api/organization/presets_values.json +10 -0
- data/lib/eco/api/organization/tag_tree.rb +134 -0
- data/lib/eco/api/organization_old.rb +73 -0
- data/lib/eco/api/session.rb +180 -0
- data/lib/eco/api/session/batch.rb +132 -0
- data/lib/eco/api/session/batch_job.rb +152 -0
- data/lib/eco/api/session/batch_jobs.rb +131 -0
- data/lib/eco/api/session/batch_status.rb +138 -0
- data/lib/eco/api/session/task.rb +92 -0
- data/lib/eco/api/session_config.rb +179 -0
- data/lib/eco/api/session_config/api.rb +47 -0
- data/lib/eco/api/session_config/apis.rb +78 -0
- data/lib/eco/api/session_config/files.rb +30 -0
- data/lib/eco/api/session_config/logger.rb +54 -0
- data/lib/eco/api/session_config/mailer.rb +65 -0
- data/lib/eco/api/session_config/people.rb +89 -0
- data/lib/eco/api/session_config/s3_bucket.rb +62 -0
- data/lib/eco/api/session_config/use_cases.rb +30 -0
- data/lib/eco/api/usecases.rb +12 -0
- data/lib/eco/api/usecases/base_case.rb +14 -0
- data/lib/eco/api/usecases/case_data.rb +13 -0
- data/lib/eco/api/usecases/default_cases.rb +53 -0
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
- data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
- data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
- data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
- data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
- data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
- data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
- data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
- data/lib/eco/api/usecases/use_case.rb +177 -0
- data/lib/eco/api/usecases/use_group.rb +104 -0
- data/lib/eco/cli.rb +9 -0
- data/lib/eco/cli/input.rb +109 -0
- data/lib/eco/cli/input_multi.rb +137 -0
- data/lib/eco/cli/root.rb +8 -0
- data/lib/eco/cli/session.rb +9 -0
- data/lib/eco/cli/session/batch.rb +9 -0
- data/lib/eco/common.rb +7 -0
- data/lib/eco/common/base_cli.rb +116 -0
- data/lib/eco/common/language.rb +9 -0
- data/lib/eco/data.rb +9 -0
- data/lib/eco/data/crypto.rb +7 -0
- data/lib/eco/data/crypto/encryption.rb +318 -0
- data/lib/eco/data/files.rb +10 -0
- data/lib/eco/data/files/directory.rb +93 -0
- data/lib/eco/data/files/file_pattern.rb +32 -0
- data/lib/eco/data/files/helpers.rb +90 -0
- data/lib/eco/data/mapper.rb +54 -0
- data/lib/eco/data/random.rb +10 -0
- data/lib/eco/data/random/distribution.rb +133 -0
- data/lib/eco/data/random/fake.rb +320 -0
- data/lib/eco/data/random/values.rb +80 -0
- data/lib/eco/language.rb +12 -0
- data/lib/eco/language/curry.rb +28 -0
- data/lib/eco/language/hash_transform.rb +68 -0
- data/lib/eco/language/hash_transform_modifier.rb +114 -0
- data/lib/eco/language/match.rb +30 -0
- data/lib/eco/language/match_modifier.rb +190 -0
- data/lib/eco/language/models.rb +11 -0
- data/lib/eco/language/models/attribute_parser.rb +38 -0
- data/lib/eco/language/models/collection.rb +181 -0
- data/lib/eco/language/models/modifier.rb +68 -0
- data/lib/eco/language/models/wrap.rb +114 -0
- data/lib/eco/language/values_at.rb +159 -0
- data/lib/eco/lexic/dictionary.rb +33 -0
- data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
- data/lib/eco/lexic/dictionary/tags.json +38 -0
- data/lib/eco/scripting.rb +30 -0
- data/lib/eco/scripting/README.md +11 -0
- data/lib/eco/scripting/arguments.rb +40 -0
- data/lib/eco/tester.rb +97 -0
- data/lib/eco/version.rb +3 -0
- metadata +325 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [null, "download", "upload", "browse", "administrate"],
|
|
3
|
+
"data": [null, "view", "update", "administrate", "implement"],
|
|
4
|
+
"reports": [null, "view", "edit", "administrate"],
|
|
5
|
+
"organization": [null, "view", "administrate", "implement"],
|
|
6
|
+
"people": [null, "attach", "view", "view_private", "edit"],
|
|
7
|
+
"pages": [null, "view", "update", "create", "administrate"],
|
|
8
|
+
"page_editor": [null, "basic", "intermediate", "advanced", "implement"],
|
|
9
|
+
"registers": [null, "view", "dashboard", "administrate", "implement"]
|
|
10
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
module Eco
|
|
2
|
+
module API
|
|
3
|
+
module Organization
|
|
4
|
+
|
|
5
|
+
class TagTree
|
|
6
|
+
attr_reader :tag, :nodes
|
|
7
|
+
attr_reader :depth, :path
|
|
8
|
+
|
|
9
|
+
def initialize(tagtree = [], depth: -1, path: [], enviro: nil)
|
|
10
|
+
case tagtree
|
|
11
|
+
when String
|
|
12
|
+
@source = JSON.parse(tagtree)
|
|
13
|
+
else
|
|
14
|
+
@source = tagtree
|
|
15
|
+
end
|
|
16
|
+
fatal("You are trying to initialize a TagTree with a null tagtree") if !@source
|
|
17
|
+
fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(API::Common::Session::Environment)
|
|
18
|
+
@enviro = enviro
|
|
19
|
+
|
|
20
|
+
@depth = depth
|
|
21
|
+
@tag = @source.is_a?(Array) ? nil : @source.dig('tag')&.upcase
|
|
22
|
+
|
|
23
|
+
@path = path || []
|
|
24
|
+
@path.push(@tag) unless !@tag
|
|
25
|
+
|
|
26
|
+
nodes = @source.is_a?(Array) ? @source : @source.dig('nodes') || []
|
|
27
|
+
@nodes = nodes.map {|node| TagTree.new(node, depth: @depth + 1, path: @path.dup, enviro: @enviro)}
|
|
28
|
+
|
|
29
|
+
init_hashes
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def tags
|
|
33
|
+
@hash_tags.keys
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def tag?(key)
|
|
37
|
+
@hash_tags.key?(key.upcase)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_node(key)
|
|
41
|
+
return nil unless tag?(key)
|
|
42
|
+
@hash_tags[key.upcase]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def filter_tags(list)
|
|
46
|
+
return [] unless list && list.is_a?(Array)
|
|
47
|
+
list.select {|str| tag?(str)}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def path(key = nil)
|
|
51
|
+
return @path if !key
|
|
52
|
+
@hash_paths[key.upcase]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def user_tags(initial: [], final: [], preserve_custom: true, add_custom: false)
|
|
56
|
+
initial ||= [initial].flatten.compact
|
|
57
|
+
final ||= [final].flatten.compact
|
|
58
|
+
raise "Expected Array for initial: and final:" unless initial.is_a?(Array) && final.is_a?(Array)
|
|
59
|
+
final = filter_tags(final) unless add_custom
|
|
60
|
+
custom = initial - filter_tags(initial)
|
|
61
|
+
final = final + custom if preserve_custom
|
|
62
|
+
new_tags = final - initial
|
|
63
|
+
# keep same order as they where
|
|
64
|
+
(initial & final) + new_tags
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# take the deepest tag (the one that is further down in the tree)
|
|
68
|
+
# different options (several nodes at the same depth):
|
|
69
|
+
# => take the common node between them (i.e. you have Hamilton and Auckland -> take New Zealand)
|
|
70
|
+
# => if there's no common node between them, take the `first` (unless they are at top level of the tree)
|
|
71
|
+
def default_tag(*values)
|
|
72
|
+
values = filter_tags(values)
|
|
73
|
+
nodes = []; depth = -1
|
|
74
|
+
values.each do |tag|
|
|
75
|
+
raise("Couldn't find the node of #{tag} in the tag-tree definition") unless node = get_node(tag)
|
|
76
|
+
|
|
77
|
+
if node.depth > depth
|
|
78
|
+
nodes = [node]
|
|
79
|
+
depth = node.depth
|
|
80
|
+
elsif node.depth == depth
|
|
81
|
+
nodes.push(node)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
default_tag = nil
|
|
86
|
+
if nodes.length > 1
|
|
87
|
+
common = nodes.reduce(self.tags.reverse) {|com, node| com & node.path.reverse}
|
|
88
|
+
default_tag = common.first if common.length > 0 && depth > 0
|
|
89
|
+
end
|
|
90
|
+
default_tag = nodes.first&.tag if !default_tag && depth > 0
|
|
91
|
+
default_tag
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
protected
|
|
95
|
+
|
|
96
|
+
def hash
|
|
97
|
+
@hash_tags
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def hash_paths
|
|
101
|
+
@hash_paths
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
def init_hashes
|
|
107
|
+
@hash_tags = {}
|
|
108
|
+
@hash_tags[@tag] = self unless !@tag
|
|
109
|
+
@hash_tags = @nodes.reduce(@hash_tags) do |h,n|
|
|
110
|
+
h.merge(n.hash)
|
|
111
|
+
end
|
|
112
|
+
@hash_paths = {}
|
|
113
|
+
@hash_paths[@tag] = @path
|
|
114
|
+
@hash_paths = @nodes.reduce(@hash_paths) do |h,n|
|
|
115
|
+
h.merge(n.hash_paths)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def fatal(msg)
|
|
120
|
+
raise msg if !@enviro
|
|
121
|
+
@enviro.logger.fatal(msg)
|
|
122
|
+
exit
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def warn(msg)
|
|
126
|
+
raise msg if !@enviro
|
|
127
|
+
@enviro.logger.warn(msg)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Eco
|
|
2
|
+
module API
|
|
3
|
+
#TODO move as part of API::Session and inherit from < API::Common::Session::BaseModel
|
|
4
|
+
#TODO boost autoconfiguration (via file <- FileManager.dir)
|
|
5
|
+
class Organization
|
|
6
|
+
|
|
7
|
+
DUMMY_USER_EXTERNAL_ID = 'dummy'
|
|
8
|
+
|
|
9
|
+
attr_reader :tag_tree, :policy_groups, :person_schemas
|
|
10
|
+
attr_reader :default_person, :default_schema, :default_schema_id
|
|
11
|
+
attr_reader :default_policy_group_ids, :default_filter_tags, :default_login_provider_ids
|
|
12
|
+
attr_reader :login_providers
|
|
13
|
+
attr_reader :account_presets, :account_preferences
|
|
14
|
+
|
|
15
|
+
def initialize(init = {})
|
|
16
|
+
api = init.fetch('api', nil)
|
|
17
|
+
@@api = api&.instance_of?(Ecoportal::API::Internal) && api
|
|
18
|
+
# todo: maps { 'policy_group' : 'preset'}
|
|
19
|
+
set_settings(init, override: true)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def set_settings(init = {}, override: false)
|
|
23
|
+
set_defaults(init)
|
|
24
|
+
@login_providers = init['login_providers'] || @@api&.login_providers&.to_a || \
|
|
25
|
+
@login_providers || [] if (!@login_providers || :override)
|
|
26
|
+
@tag_tree = init['tag_tree'] || @default_filter_tags || @tag_tree || [] if (!@tag_tree || :override)
|
|
27
|
+
@policy_groups = init['policy_groups'] || @@api&.policy_groups&.to_a || \
|
|
28
|
+
@policy_groups || [] if (!@policy_groups || :override)
|
|
29
|
+
|
|
30
|
+
@person_schemas = init['person_schemas'] || @@api&.person_schemas&.to_a || @person_schemas || \
|
|
31
|
+
[@default_schema] || [] if (!@person_schemas || :override)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def default_schema=(value)
|
|
35
|
+
@default_schema = value || @person_schemas&.first
|
|
36
|
+
self.default_schema_id = @default_schema&.id || @default_schema&.schema_id || @default_schema_id
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def default_schema_id=(value)
|
|
40
|
+
@default_schema_id = value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def set_defaults(init = {})
|
|
46
|
+
@account_presets = Account::Presets.new(init.fetch('presets', nil))
|
|
47
|
+
@account_preferences = Account::Preferences.new
|
|
48
|
+
|
|
49
|
+
@default_person = get_default_person(init)
|
|
50
|
+
@default_policy_group_ids = init['default_policy_group_ids'] || @default_person&.account&.policy_group_ids || []
|
|
51
|
+
@default_filter_tags = init['default_filter_tags'] || @default_person&.account&.filter_tags || []
|
|
52
|
+
@default_login_provider_ids = init['default_login_provider_ids'] || @default_person&.account&.login_provider_ids || []
|
|
53
|
+
default_schema = get_schema_from_person(@default_person)
|
|
54
|
+
self.default_schema = init['default_schema'] || default_schema
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def get_default_person(init = {})
|
|
58
|
+
return nil if !@@api
|
|
59
|
+
return init.fetch('default_person', (@@api && @@api.people.get(DUMMY_USER_EXTERNAL_ID)).result || nil)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def get_schema_from_person(person)
|
|
63
|
+
return nil if !person
|
|
64
|
+
doc = person.details.doc
|
|
65
|
+
doc['id'] = doc['schema_id']
|
|
66
|
+
doc.delete('schema_id')
|
|
67
|
+
schema = Ecoportal::API::Internal::PersonSchema.new(doc)
|
|
68
|
+
return schema
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
module Eco
|
|
2
|
+
module API
|
|
3
|
+
class Session < Common::Session::BaseSession
|
|
4
|
+
|
|
5
|
+
attr_reader :batch, :policy_groups
|
|
6
|
+
attr_accessor :schema, :schemas_hash
|
|
7
|
+
attr_reader :tagtree
|
|
8
|
+
attr_reader :job_groups
|
|
9
|
+
|
|
10
|
+
#attr_reader :organization
|
|
11
|
+
#alias_method :org, :organization
|
|
12
|
+
|
|
13
|
+
def initialize(init = {})
|
|
14
|
+
super(init)
|
|
15
|
+
logger.debug("LINE COMMAND: #{$0} #{ARGV.join(" ")}")
|
|
16
|
+
|
|
17
|
+
@batch = Batch.new(enviro)
|
|
18
|
+
@task = Task.new(self, enviro)
|
|
19
|
+
@job_groups = JobGroups.new(session: self)
|
|
20
|
+
|
|
21
|
+
@use_cases = Eco::API::UseCases::DefaultCases.new.merge(config.usecases.use_group)
|
|
22
|
+
|
|
23
|
+
@schemas = api&.person_schemas.to_a
|
|
24
|
+
@schemas_hash = @schemas.map do |sch|
|
|
25
|
+
[[sch.id, sch], [sch.name.downcase, sch]]
|
|
26
|
+
end.flatten(1).to_h
|
|
27
|
+
|
|
28
|
+
self.schema = config.people.default_schema || @schemas.first
|
|
29
|
+
@policy_groups = nil
|
|
30
|
+
|
|
31
|
+
@tagtree = nil
|
|
32
|
+
if tree_file = config.dig('org', 'tagtree')
|
|
33
|
+
tree = file_manager.load_json(tree_file) unless !tree_file
|
|
34
|
+
@tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
presets_custom_file = config.people.presets_custom
|
|
38
|
+
presets_map_file = config.people.presets_map
|
|
39
|
+
|
|
40
|
+
@presets_factory = Eco::API::Organization::PresetsFactory.new({
|
|
41
|
+
#policy_groups: @policy_groups,
|
|
42
|
+
presets_custom: file_manager.dir.file(presets_custom_file, should_exist: true),
|
|
43
|
+
presets_map: file_manager.dir.file(presets_map_file, should_exist: true),
|
|
44
|
+
enviro: enviro
|
|
45
|
+
})
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.configure
|
|
49
|
+
#SessionConfig.new.tap
|
|
50
|
+
conf = SessionConfig.new
|
|
51
|
+
yield(conf) if block_given?
|
|
52
|
+
conf
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def config
|
|
56
|
+
enviro.config
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# TASKS & JOBS
|
|
60
|
+
def do
|
|
61
|
+
@task
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def mail_to(**kargs)
|
|
65
|
+
@mailer ||= Eco::API::Common::Session::Mailer.new(enviro: enviro)
|
|
66
|
+
@mailer.mail(**kargs)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def s3upload(content: nil, file: nil, directory: nil)
|
|
70
|
+
@s3uploader ||= Eco::API::Common::Session::S3Uploader.new(enviro: enviro)
|
|
71
|
+
if content && file
|
|
72
|
+
@s3uploader.upload(file, content)
|
|
73
|
+
elsif file
|
|
74
|
+
@s3uploader.upload_file(file)
|
|
75
|
+
elsif directory
|
|
76
|
+
@s3uploader.upload_directory(directory)
|
|
77
|
+
else
|
|
78
|
+
logger.error("To use Session.s3upload, you must specify either directory, file or content and file name")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def job_group(name, order: :last)
|
|
83
|
+
case
|
|
84
|
+
when job_groups.exists?(name)
|
|
85
|
+
job_groups[name]
|
|
86
|
+
else
|
|
87
|
+
job_groups.new(name, order: order)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def jobs_launch(simulate: false)
|
|
92
|
+
job_groups.launch(simulate: simulate)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def policy_groups
|
|
96
|
+
@policy_groups ||= config.policy_groups
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def schema=(value)
|
|
100
|
+
case value
|
|
101
|
+
when String
|
|
102
|
+
sch = @schemas_hash[value.downcase]
|
|
103
|
+
raise "The schema with id or name '#{value}' does not exist" if !sch
|
|
104
|
+
@schema = sch
|
|
105
|
+
when Ecoportal::API::V1::PersonSchema
|
|
106
|
+
@schema = value
|
|
107
|
+
else
|
|
108
|
+
logger.error("Session: Missuse of 'schema=' method. Given: #{value}")
|
|
109
|
+
return
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
@person_factory = Eco::API::Common::People::PersonFactory.new(schema: @schema)
|
|
113
|
+
|
|
114
|
+
fields_mapper_file = config.people.fields_mapper
|
|
115
|
+
fields_mapper = Eco::Data::Mapper.new(file_manager.load_json(fields_mapper_file))
|
|
116
|
+
@entry_factory = Eco::API::Common::People::EntryFactory.new({
|
|
117
|
+
schema: @schema,
|
|
118
|
+
person_parser: config.people.parser,
|
|
119
|
+
fields_mapper: fields_mapper,
|
|
120
|
+
logger: logger
|
|
121
|
+
})
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def new_preset(input)
|
|
125
|
+
case input
|
|
126
|
+
when Ecoportal::API::Internal::Person
|
|
127
|
+
@presets_factory.new(*input&.account&.policy_group_ids)
|
|
128
|
+
when Array
|
|
129
|
+
@presets_factory.new(*input)
|
|
130
|
+
else
|
|
131
|
+
@presets_factory.new(input)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def new_person(**keyed_args)
|
|
136
|
+
@person_factory.new(**keyed_args)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def new_entry(data, dependencies: {})
|
|
140
|
+
@entry_factory.new(data, dependencies: dependencies)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def csv_entries(file)
|
|
144
|
+
rows = []
|
|
145
|
+
if Eco::API::Common::Session::FileManager.file_exists?(file)
|
|
146
|
+
CSV.foreach(file, headers: true, encoding: Eco::API::Common::Session::FileManager.encoding(file)).with_index do |row, i|
|
|
147
|
+
rows.push(row)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
@entry_factory.entries(rows)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def discarded_entries
|
|
154
|
+
file = config.people.discarded_file
|
|
155
|
+
file = file_manager.dir.file(file)
|
|
156
|
+
csv_entries(file)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def process_case(name, type: nil, **params)
|
|
160
|
+
args = { session: self }.merge(params)
|
|
161
|
+
fatal("Undefined usecase '#{name}' of type '#{type.to_s}'") if !@use_cases.defined?(name, type: type)
|
|
162
|
+
@use_cases.case(name, type: type).process(**args)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
def fatal(msg)
|
|
168
|
+
logger.fatal(msg)
|
|
169
|
+
raise msg
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
require_relative 'session/batch'
|
|
177
|
+
require_relative 'session/batch_status'
|
|
178
|
+
require_relative 'session/task'
|
|
179
|
+
require_relative 'session/batch_job'
|
|
180
|
+
require_relative 'session/batch_jobs'
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
module Eco
|
|
2
|
+
module API
|
|
3
|
+
class Session
|
|
4
|
+
# important! the handler should probably only create logs and save the update with same timestamp
|
|
5
|
+
class Batch < Common::Session::BaseSession
|
|
6
|
+
|
|
7
|
+
DEFAULT_BATCH_BLOCK = 100
|
|
8
|
+
VALID_METHODS = ['get', 'create', 'update', 'upsert', 'delete']
|
|
9
|
+
|
|
10
|
+
# people can be: empty, an api object, a people object, or an array with id's or persons
|
|
11
|
+
def get_people(people = nil, api: nil, params: {per_page: DEFAULT_BATCH_BLOCK})
|
|
12
|
+
api = api || self.api
|
|
13
|
+
return batch_from(people, 'get', api, params: params) if people.is_a?(Array)
|
|
14
|
+
return batch_get(api, params: params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def launch(people = nil, method:, api: nil, params: {per_page: DEFAULT_BATCH_BLOCK})
|
|
18
|
+
if !valid_method?(method)
|
|
19
|
+
msg = "Invalid batch method: #{method}."
|
|
20
|
+
logger.fatal(msg)
|
|
21
|
+
raise msg
|
|
22
|
+
end
|
|
23
|
+
return nil if !people || !people.is_a?(Array)
|
|
24
|
+
batch_from(people, method, api || self.api, params: params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def valid_methods
|
|
28
|
+
VALID_METHODS
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def valid_method?(value)
|
|
32
|
+
VALID_METHODS.include?(value)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def new_status(queue, method)
|
|
39
|
+
BatchStatus.new(enviro, queue: queue, method: method)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def batch_get(api, params: {})
|
|
43
|
+
unless people_api = api&.people
|
|
44
|
+
msg = "cannot batch get without api connnection, please provide a valid api connection!"
|
|
45
|
+
logger.fatal(msg)
|
|
46
|
+
raise msg
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params)
|
|
50
|
+
client = people_api.client
|
|
51
|
+
people = [];
|
|
52
|
+
if (page = params.fetch(:page, false))
|
|
53
|
+
res, response = get(client, params: params)
|
|
54
|
+
people +=res
|
|
55
|
+
logger.info("page number: #{page}, got num people #{people.length}")
|
|
56
|
+
else
|
|
57
|
+
page = 1
|
|
58
|
+
loop do
|
|
59
|
+
params = params.merge({page: page})
|
|
60
|
+
people_res, response = get(client, params: params)
|
|
61
|
+
people += people_res
|
|
62
|
+
|
|
63
|
+
total_pages = response.body["total_pages"]
|
|
64
|
+
logger.info("page number: #{page}/#{total_pages}, got num people #{people_res.length}, with total #{people.length} people got")
|
|
65
|
+
break if page >= total_pages
|
|
66
|
+
page += 1
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
return people
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def get(client, params:)
|
|
73
|
+
response = client.get("/people", params: params)
|
|
74
|
+
unless response.success?
|
|
75
|
+
msg = "Request failed - params: #{params}"
|
|
76
|
+
msg += "\n Error message: - Status #{response.status}: #{response.body}"
|
|
77
|
+
logger.fatal(msg)
|
|
78
|
+
raise msg
|
|
79
|
+
end
|
|
80
|
+
people = []
|
|
81
|
+
response.body["results"].each do |person_hash|
|
|
82
|
+
person = INTERNAL::Person.new(person_hash)
|
|
83
|
+
yield person if block_given?
|
|
84
|
+
people.push(person)
|
|
85
|
+
end
|
|
86
|
+
[people, response]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def batch_from(people, method, api, params: {})
|
|
90
|
+
return nil if !people || !people.is_a?(Array)
|
|
91
|
+
unless people_api = api&.people
|
|
92
|
+
msg = "cannot batch #{method} without api connnection, please provide a valid api connection!"
|
|
93
|
+
logger.fatal(msg)
|
|
94
|
+
raise msg
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# batch Status
|
|
98
|
+
status = new_status(people, method)
|
|
99
|
+
|
|
100
|
+
# param q does not make sense here, even for GET method
|
|
101
|
+
params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params)
|
|
102
|
+
per_page = params.fetch(:per_page)
|
|
103
|
+
|
|
104
|
+
iteration = 1; done = 0
|
|
105
|
+
|
|
106
|
+
people.each_slice(per_page) do |slice|
|
|
107
|
+
msg = "starting batch '#{method}' iteration #{iteration}, which has #{slice.length} entries of #{people.length} -- #{done} done"
|
|
108
|
+
logger.info(msg)
|
|
109
|
+
|
|
110
|
+
people_api.batch do |batch|
|
|
111
|
+
slice.each do |person|
|
|
112
|
+
# valid method checked before
|
|
113
|
+
batch.public_send(method, person) do |response|
|
|
114
|
+
status[person] = response
|
|
115
|
+
#status.print_error(person)
|
|
116
|
+
end # current person
|
|
117
|
+
end # next person
|
|
118
|
+
end # next batch
|
|
119
|
+
|
|
120
|
+
iteration += 1
|
|
121
|
+
done += slice.length
|
|
122
|
+
end # next slice
|
|
123
|
+
|
|
124
|
+
status.print_errors
|
|
125
|
+
|
|
126
|
+
return status
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|