lib/eco/api/common/people/entry_factory.rb in eco-helpers-0.6.17 vs lib/eco/api/common/people/entry_factory.rb in eco-helpers-0.7.1
- old
+ new
@@ -1,33 +1,121 @@
module Eco
module API
module Common
module People
+ # @attr_reader person_parser [Eco::API::Common::People::PersonParser] set of attribute, type and format parsers/serializers.
class EntryFactory
attr_reader :person_parser
- def initialize(schema:, person_parser: nil, fields_mapper: nil, logger: ::Logger.new(IO::NULL))
- raise "Constructor needs a PersonSchema. Given: #{schema}" if !schema.is_a?(Ecoportal::API::V1::PersonSchema)
- raise "Expecting PersonParser. Given: #{person_parser}" if person_parser && !person_parser.is_a?(Eco::API::Common::People::PersonParser)
- raise "Expecting Mapper object. Given: #{fields_mapper}" if fields_mapper && !fields_mapper.is_a?(Eco::Data::Mapper)
+ # @param schema [Ecoportal::API::V1::PersonSchema] schema of person details that the parser will be based upon.
+ # @param person_parser [nil, Eco::API::Common::People::PersonParser] set of attribute, type and format parsers/serializers.
+ # @param attr_map [nil, Eco::Data::Mapper] attribute names mapper to translate external names into internal ones and _vice versa_.
+ # @param logger [Common::Session::Logger, ::Logger] object to manage logs.
+ def initialize(schema:, person_parser: nil, attr_map: nil, logger: ::Logger.new(IO::NULL))
+ fatal "Constructor needs a PersonSchema. Given: #{schema}" if !schema.is_a?(Ecoportal::API::V1::PersonSchema)
+ fatal "Expecting PersonParser. Given: #{person_parser}" if person_parser && !person_parser.is_a?(Eco::API::Common::People::PersonParser)
+ fatal "Expecting Mapper object. Given: #{fields_mapper}" if attr_map && !attr_map.is_a?(Eco::Data::Mapper)
@logger = logger
@schema = Ecoportal::API::V1::PersonSchema.new(JSON.parse(schema.doc.to_json))
default_parser = Eco::API::Common::People::DefaultParsers.new(schema: @schema)
- @parser = default_parser.merge(person_parser)
+ @person_parser = default_parser.merge(person_parser)
- @fields_mapper = fields_mapper
+ @attr_map = attr_map
end
+ # key method to generate objects of `PersonEntry` that share dependencies via this `EntryFactory` environment.
+ # @note this method is necessary to make the factory object work as a if it was a class `PersonEntry` you can call `new` on.
+ # @param data [Array<Hash>] data to be parsed. The external hashed entry.
+ # @return [Eco::API::Common::People::PersonEntry]
def new(data, dependencies: {})
- PersonEntry.new(data, parser: @parser, mapper: @fields_mapper, dependencies: dependencies, logger: @logger)
+ PersonEntry.new(
+ data,
+ person_parser: @person_parser,
+ attr_map: @attr_map,
+ dependencies: dependencies,
+ logger: @logger
+ )
end
- def entries(data)
- Entries.new(data, klass: PersonEntry, factory: self)
+ # Helper that provides a collection of `Entries`, which in turn provides with further helpers to find and exclude entries.
+ # It accepts a `file:` and `format:` or `data:` but not both options together.
+ # @raise Exception
+ # - if you try to provide `data:` and `file:` at the same time.
+ # - if you provide `file:` but omit `format:`.
+ # - if the `format:` you provide is not a `Symbol`.
+ # - if there is no _parser/serializer_ defined for `format:`.
+ # @param data [Array<Hash>] data to be parsed. It cannot be used alongside with `file:`
+ # @param file [String] absolute or relative path to the input file. It cannot be used alongside with `data:`.
+ # @param format [Symbol] it must be used when you use the option `file:` (i.e. `:xml`, `:csv`), as it specifies the format of the input `file:`.
+ # @param encoding [String] optional parameter to read `file:` by expecting certain encoding.
+ # @return [Eco::API::Common::People::Entries] collection of `Eco::API::Common::People::PersonEntry`.
+ def entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil), encoding: nil)
+ fatal("You should at least use data: or file:, but not both") if no_data == no_file
+ fatal("You must specify a valid format: (symbol) when you use file.") if file && no_format
+ fatal("Format should be a Symbol. Given '#{format}'") if format && !format.is_a?(Symbol)
+ fatal("There is no parser/serializer for format ':#{format.to_s}'") unless no_format || @person_parser.defined?(format)
+
+ if file
+ arr_hash = []
+ if Eco::API::Common::Session::FileManager.file_exists?(file)
+ encoding ||= Eco::API::Common::Session::FileManager.encoding(file)
+ file_content = File.read(file, encoding: encoding)
+ arr_hash = @person_parser.parse(format, file_content)
+ end
+ entries(data: arr_hash)
+ else
+ Entries.new(data, klass: PersonEntry, factory: self)
+ end
end
+
+ # Helper that generates a file out of `data:`.
+ # @raise Exception
+ # - if you try to provide `data:` in the wrong format.
+ # - if you `file:` is empty.
+ # - if the `format:` you provide is not a `Symbol`.
+ # - if there is no _parser/serializer_ defined for `format:`.
+ # @param data [Eco::API::Organization::People] data to be parsed.
+ # @param file [String] absolute or relative path to the ouput file.
+ # @param format [Symbol] it specifies the format of the output `file:` (i.e. `:xml`, `:csv`). There must be a parser/serializer defined for it.
+ # @param encoding [String] optional parameter to geneate `file:` content by unsing certain encoding.
+ # @return [Void].
+ def export(data:, file: "export", format: :csv, encoding: "utf-8")
+ fatal("data: Expected Eco::API::Organization::People object. Given: #{data.class}") unless data.is_a?(Eco::API::Organization::People)
+ fatal("A file should be specified.") unless !file.to_s.strip.empty?
+ fatal("Format should be a Symbol. Given '#{format}'") if format && !format.is_a?(Symbol)
+ fatal("There is no parser/serializer for format ':#{format.to_s}'") unless @person_parser.defined?(format)
+
+ run = true
+ if Eco::API::Common::Session::FileManager.file_exists?(file)
+ print "The file '#{file}' already exists. Do you want to overwrite it? (Y/n): "
+ res = STDIN.gets.strip
+ run = ["y", "Y", ""].include?(res)
+ end
+
+ if run
+ deps = {"supervisor_id" => {people: data}}
+
+ data_entries = data.map do |person|
+ self.new(person, dependencies: deps).to_hash
+ end
+
+ File.open(file, "w", enconding: encoding) do |fd|
+ fd.write(@person_parser.serialize(format, data_entries))
+ end
+ end
+
+ end
+
+ private
+
+ def fatal(msg)
+ @logger.fatal(msg)
+ raise msg
+ end
+
end
end
end
end