lib/eco/api/session.rb in eco-helpers-1.0.13 vs lib/eco/api/session.rb in eco-helpers-1.0.14

- old
+ new

@@ -1,61 +1,34 @@ module Eco module API + # Class to manage the current session. + # Central helper of resources. 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. + #@param init [Eco::API::Session::Config, Eco::API::Common::Session::Environment] object to ini the session 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(" ")}") + @entry_factories = {} + @person_factories = {} - @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 - }) + logger.debug("LINE COMMAND: #{$0} #{ARGV.join(" ")}") 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 + @task ||= Task.new(enviro) end - def mail_to(**kargs) - mail.mail(**kargs) + # @return [Eco::API::Session::Batch] provides helper to launch batch operations. + def batch + @batch ||= Batch.new(enviro) end - - def s3upload(content: nil, file: nil, directory: nil) - 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 @@ -73,93 +46,105 @@ # @see Eco::API::Session::Config#schemas def schemas config.schemas end + # @return [String, Ecoportal::API::V1::PersonSchema] current active session's schema + def schema + self.schema = config.people.default_schema || schemas.first unless @schema + @schema + 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 + @schema = to_schema(value) + 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<String>] 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 - logger.error("Session: Missuse of 'schema=' method. Given: #{value}") - return + presets_factory.new(input) end + end - @person_factory = Eco::API::Common::People::PersonFactory.new(schema: @schema) + # Helper to obtain a EntryFactory + # @param schema [String, Ecoportal::API::V1::PersonSchema] `schema` to which associate the EntryFactory, + # where `String` can be the _name_ or the _id_ of the schema. + # @return [Eco::API::Common::People::EntryFactory] associated to `schema`. + # If `schema` is `nil` or not provided it uses the currently associated to the `session` + def entry_factory(schema: nil) + schema = to_schema(schema) || self.schema + return @entry_factories[schema&.id] if @entry_factories.key?(schema&.id) # TODO: check PersonEntry#to_internal and #to_external in init_attr_trackers # => when attr_map is avoided, it doesn't work as it should + mappings = [] 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, + @entry_factories[schema&.id] = Eco::API::Common::People::EntryFactory.new({ + schema: schema, person_parser: config.people.parser, - attr_map: attr_map, + attr_map: Eco::Data::Mapper.new(mappings), logger: logger }) - self end + # Helper to obtain a PersonFactory + # @param schema [String, Ecoportal::API::V1::PersonSchema] `schema` to which associate the PersonFactory, + # where `String` can be the _name_ or the _id_ of the schema. + # @return [Eco::API::Common::People::PersonFactory] associated to `schema`. + # If `schema` is `nil` or not provided it uses the currently associated to the `session` + def person_factory(schema: nil) + schema = to_schema(schema) || self.schema + @person_factories[schema&.id] ||= Eco::API::Common::People::PersonFactory.new(schema: schema) + end + # Allows to use the defined parsers # @note the use of these method requires to know which is the expected format of `source` # @param attr [String] type (`Symbol`) or attribute (`String`) to target a specific parser. # @param source [Any] source value to be parsed. def parse_attribute(attr, source) - unless parsers = @entry_factory.person_parser + unless parsers = entry_factory.person_parser raise "There are no parsers defined" end parsers.parse(attr, source) 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<String>] 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) + 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) + 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) + 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| + 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. @@ -212,9 +197,69 @@ end end def jobs_launch(simulate: false) job_groups.launch(simulate: simulate) + end + + # Sends an email + # @see Eco::API::Common::Session::Mailer#mail + def mail_to(**kargs) + mail.mail(**kargs) + end + + # Uploads content into a file, a file or a directory to S3 + # @see Eco::API::Common::Session::S3Uploader#upload + # @see Eco::API::Common::Session::S3Uploader#upload_file + # @see Eco::API::Common::Session::S3Uploader#upload_directory + # @param content [String] content to be uploaded (requires `file`) + # @param file [String] name of the file to be uploaded + # @param directory [String] name of source directory to be uploaded + def s3upload(content: nil, file: nil, directory: nil) + 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 + + private + + # Helper to state the abilities that a person should have with given their usergroups + def presets_factory + @presets_factory ||= Eco::API::Organization::PresetsFactory.new({ + presets_custom: file_manager.dir.file(config.people.presets_custom, should_exist: true), + presets_map: file_manager.dir.file(config.people.presets_map, should_exist: true), + enviro: enviro + }) + end + + # Comparer to state if 2 schemas are different + def same_schema? (schema1, schema2) + eq = schema1&.id == schema2&.id + eq ||= schema1&.name&.downcase == schema2&.name&.downcase + schema1 && schema2 && eq + end + + # from schema `id` or `name` to a PersonSchema object + def to_schema(value) + return nil unless value + sch = nil + case value + when String + unless sch = schemas.schema(value) + fatal "The schema with id or name '#{value}' does not exist." + end + when Ecoportal::API::V1::PersonSchema + sch = value + else + fatal "Required String or Ecoportal::API::V1::PersonSchema. Given: #{value}" + end + sch end end end end