lib/eco/api/common/people/entry_factory.rb in eco-helpers-2.0.19 vs lib/eco/api/common/people/entry_factory.rb in eco-helpers-2.0.21

- old
+ new

@@ -1,10 +1,10 @@ module Eco module API module Common module People - # TODO: EntryFactory should suppport multiple schemas itself + # TODO: EntryFactory should suppport multiple schemas itself (rather that being done on `Session`) # => currently, it's through session.entry_factory(schema: id), but this is wrong # => This way, Entries and PersonEntry will be able to refer to attr_map and person_parser linked to schema_id # => "schema_id" should be an optional column in the input file, or parsable via a custom parser to scope the schema # Helper factory class to generate entries (input entries). # @attr_reader schema [Ecoportal::API::V1::PersonSchema] person schema to be used in this entry factory @@ -86,30 +86,53 @@ 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) - encoding = (encoding != "utf-8")? "#{encoding}|utf-8": encoding - file_content = File.read(file, encoding: encoding) - arr_hash = person_parser.parse(format, file_content).map.each_with_index do |entry_hash, i| - j = (format == :csv)? i + 2 : i + 1 - entry_hash.tap {|hash| hash["idx"] = j} - end + kargs = {} + kargs.merge!(content: data) unless no_data + kargs.merge!(file: file) unless no_file + kargs.merge!(format: format) unless no_format + kargs.merge!(encoding: encoding) if encoding + + Entries.new(to_array_of_hashes(**kargs), klass: PersonEntry, factory: self) + end + + def to_array_of_hashes(**kargs) + data = [] + content, file, encoding, format = kargs.values_at(:content, :file, :encoding, :format) + + content = get_file_content(file, format, encoding) if file + + case content + when !content + logger.error("Could not obtain any data out of these: #{kargs}") + exit(1) + when Hash + logger.error("Input data as 'Hash' not supported. Expecting 'Enumerable' or 'String'") + exit(1) + when String + data = person_parser.parse(format, content).map.each_with_index do |entry_hash, i| + j = (format == :csv)? i + 2 : i + 1 + entry_hash.tap {|hash| hash["idx"] = j} + end + to_array_of_hashes(content: data) + when Enumerable + sample = content.to_a.first + case sample + when Hash, Array, ::CSV::Row + Eco::CSV::Table.new(content).to_array_of_hashes else - logger.warn("File does not exist: #{file}") + logger.error("Input 'Array' of '#{sample.class}' is not supported.") end - - entries(data: arr_hash) else - Entries.new(data, klass: PersonEntry, factory: self) + logger.error("Could not obtain any data out of content: '#{content.class}'") + exit(1) 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`. @@ -147,9 +170,20 @@ end end private + + def get_file_content(file, format, encoding) + unless Eco::API::Common::Session::FileManager.file_exists?(file) + logger.error("File does not exist: #{file}") + exit(1) + end + ext = File.extname(file) + encoding ||= Eco::API::Common::Session::FileManager.encoding(file) + encoding = (encoding != "utf-8")? "#{encoding}|utf-8": encoding + content = File.read(file, encoding: encoding) + end def fatal(msg) logger.fatal(msg) raise msg end