module Eco module API class Session < Common::Session::BaseSession attr_reader :batch attr_accessor :schema # Class to manage the current session. # Central helper of resources. # # @attr_reader batch [Eco::API::Session::Batch] provides helper to launch batch operations. # @attr_reader schema [Ecoportal::API::V1::PersonSchema] currently active schema. def initialize(init = {}) e = init msg = "Expected object Eco::API::Session::Config or Eco::API::Common::Session::Environment. Given: #{init}" raise msg unless e.is_a?(Session::Config) || e.is_a?(Eco::API::Common::Session::Environment) e = Eco::API::Common::Session::Environment.new(init, session: self) if !e.is_a?(Eco::API::Common::Session::Environment) super(e) logger.debug("LINE COMMAND: #{$0} #{ARGV.join(" ")}") @batch = Batch.new(enviro) @task = Task.new(enviro) self.schema = config.people.default_schema || schemas.first presets_custom_file = config.people.presets_custom presets_map_file = config.people.presets_map @presets_factory = Eco::API::Organization::PresetsFactory.new({ presets_custom: file_manager.dir.file(presets_custom_file, should_exist: true), presets_map: file_manager.dir.file(presets_map_file, should_exist: true), enviro: enviro }) end # Helper to perform multiple operations in one go. # @return [Eco::API::Session::Task] provides shortcuts to manage certain kind of operations. def do @task end def mail_to(**kargs) @mailer ||= Eco::API::Common::Session::Mailer.new(enviro: enviro) @mailer.mail(**kargs) end def s3upload(content: nil, file: nil, directory: nil) @s3uploader ||= Eco::API::Common::Session::S3Uploader.new(enviro: enviro) if content && file @s3uploader.upload(file, content) elsif file @s3uploader.upload_file(file) elsif directory @s3uploader.upload_directory(directory) else logger.error("To use Session.s3upload, you must specify either directory, file or content and file name") end end # @see Eco::API::Session::Config#policy_groups def policy_groups config.policy_groups end # @see Eco::API::Session::Config#tagtree def tagtree config.tagtree(enviro: enviro) end # @see Eco::API::Session::Config#schemas def schemas config.schemas end # Sets the current target `PersonSchema` of this session. # @note observe that it is essential for the parsers/serialisers to identify target/present attributes. # @param schema [String, Ecoportal::API::V1::PersonSchema] where `String` can be the _name_ or the _id_ of the schema. def schema=(value) case value when String unless @schema = schemas.schema(value) fatal "The schema with id or name '#{value}' does not exist" end when Ecoportal::API::V1::PersonSchema @schema = value else logger.error("Session: Missuse of 'schema=' method. Given: #{value}") return end @person_factory = Eco::API::Common::People::PersonFactory.new(schema: @schema) # TODO: check PersonEntry#to_internal and #to_external in init_attr_trackers # => when attr_map is avoided, it doesn't work as it should if map_file = config.people.fields_mapper mappings = map_file ? file_manager.load_json(map_file) : [] else mappings = [] end attr_map = Eco::Data::Mapper.new(mappings) @entry_factory = Eco::API::Common::People::EntryFactory.new({ schema: @schema, person_parser: config.people.parser, attr_map: attr_map, logger: logger }) self end # Builds the presets using the usergroup ids of the input. # @note for each flag/ability it will take the highest among those mapped for the present usergroups. # @param [Ecoportal::API::Internal::Person, Array] the array should be of usegroup names or ids. # @return [Hash] with custom presets. def new_preset(input) case input when Ecoportal::API::Internal::Person @presets_factory.new(*input&.account&.policy_group_ids) when Array @presets_factory.new(*input) else @presets_factory.new(input) end end def export(*args) @entry_factory.export(*args) end # @see Eco::API::Common::People::EntryFactory#new # @return [Ecoportal::API::Internal::Person] def new_person(**keyed_args) @person_factory.new(**keyed_args) end # Builds the entry for the given data. # @see Eco::API::Common::People::EntryFactory#new # @return [Eco::API::Common::People::PersonEntry] parsed entry. def new_entry(data, dependencies: {}) @entry_factory.new(data, dependencies: dependencies) end # @see Eco::API::Common::People::EntryFactory#entries # @return [Eco::API::Common::People::Entries] collection of entries. def entries(*args) @entry_factory.entries(*args).tap do |collection| logger.info("Loaded #{collection.length} input entries.") end end # Generates an entries collection from a csv input file. # @see Eco::API::Common::People::EntryFactory#entries # @param file [String] file to generate the entries from. # @return [Eco::API::Common::People::Entries] collection of entries. def csv_entries(file) return entries(file: file, format: :csv) end # Generates the collection of entries that should be discarded from an update. # @note requires `session.config.people.discarded_file` to be defined. # @return [Eco::API::Common::People::Entries] collection of entries. def discarded_entries return @discarded_entries if instance_variable_defined?(:@discarded_entries) file = config.people.discarded_file file = file_manager.dir.file(file) @discarded_entries = csv_entries(file) end def workflow(io:) config.workflow.tap do |wf| yield(wf, io) if block_given? end end def usecases @usecases ||= Eco::API::UseCases::DefaultCases.new.merge(config.usecases) end def post_launch @post_launch ||= config.post_launch.select(usecases) end def process_case(name, io: nil, type: nil, **params) args = { session: self }.merge(params) usecases.case(name, type: type).launch(io: io, **args) end def job_groups @job_groups ||= Batch::JobsGroups.new(enviro) end def job_group(name, order: :last) case when job_groups.exists?(name) job_groups[name] else job_groups.new(name, order: order) end end def jobs_launch(simulate: false) job_groups.launch(simulate: simulate) end end end end require_relative 'session/config' require_relative 'session/batch' require_relative 'session/task'