Class: Eco::API::Common::People::EntryFactory
- Inherits:
-
Session::BaseSession
- Object
- Session::BaseSession
- Eco::API::Common::People::EntryFactory
- Defined in:
- lib/eco/api/common/people/entry_factory.rb
Overview
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).
Instance Attribute Summary collapse
-
#person_parser ⇒ Eco::API::Common::People::PersonParser
readonly
provides with a Eco::API::Common::People::PersonParser object (collection of attribute parsers).
-
#schema ⇒ Ecoportal::API::V1::PersonSchema
readonly
person schema to be used in this entry factory.
Attributes inherited from Session::BaseSession
#api, #config, #environment, #file_manager, #logger, #session
Instance Method Summary collapse
-
#entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil), **options) ⇒ Eco::API::Common::People::Entries
Helper that provides a collection of
Entries
, which in turn provides with further helpers to find and exclude entries. -
#export(data:, file: "export", format: :csv, encoding: "utf-8", internal_names: false) ⇒ Void
Helper that generates a file out of
data:
. -
#initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil) ⇒ EntryFactory
constructor
A new instance of EntryFactory.
-
#new(data, dependencies: {}) ⇒ Eco::API::Common::People::PersonEntry
key method to generate objects of
PersonEntry
that share dependencies via thisEntryFactory
environment. - #newFactory(schema: nil) ⇒ Object
- #to_array_of_hashes(**kargs) ⇒ Object
Methods inherited from Session::BaseSession
#enviro=, #fm, #mailer, #mailer?, #s3uploader, #s3uploader?, #sftp, #sftp?
Constructor Details
#initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil) ⇒ EntryFactory
Returns a new instance of EntryFactory.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 19 def initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil) 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) super(e) @schema = Ecoportal::API::V1::PersonSchema.new(JSON.parse(schema.doc.to_json)) @source_person_parser = person_parser # load default parser + custom parsers @default_parser = default_parser&.new(schema: @schema) || Eco::API::Common::People::DefaultParsers.new(schema: @schema) base_parser = @default_parser.merge(@source_person_parser) # new parser with linked schema @person_parser = @source_person_parser.new(schema: @schema).merge(base_parser) @person_parser_patch_version = @source_person_parser.patch_version @attr_map = attr_map end |
Instance Attribute Details
#person_parser ⇒ Eco::API::Common::People::PersonParser (readonly)
if the custom person parser has changed, it updates the copy of this EntryFactory instance
provides with a Eco::API::Common::People::PersonParser object (collection of attribute parsers)
51 52 53 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 51 def person_parser @person_parser end |
#schema ⇒ Ecoportal::API::V1::PersonSchema (readonly)
person schema to be used in this entry factory
11 12 13 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 11 def schema @schema end |
Instance Method Details
#entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil), **options) ⇒ Eco::API::Common::People::Entries
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.
87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 87 def entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; 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) .merge!(content: data) unless no_data .merge!(file: file) unless no_file .merge!(format: format) unless no_format Entries.new(to_array_of_hashes(**), klass: PersonEntry, factory: self) end |
#export(data:, file: "export", format: :csv, encoding: "utf-8", internal_names: false) ⇒ Void
Helper that generates a file out of data:
.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 160 def export(data:, file: "export", format: :csv, encoding: "utf-8", internal_names: false) 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) prompt_user("Do you want to overwrite it? (Y/n):", explanation: "The file '#{file}' already exists.", default: "Y") do |response| run = (response == "") || response.upcase.start_with?("Y") end end if run deps = {"supervisor_id" => {people: data}} data_entries = data.map do |person| self.new(person, dependencies: deps).yield_self do |entry| internal_names ? entry.mapped_entry : entry.external_entry end end File.open(file, "w", enconding: encoding) do |fd| fd.write(person_parser.serialize(format, data_entries)) end end end |
#new(data, dependencies: {}) ⇒ Eco::API::Common::People::PersonEntry
this method is necessary to make the factory object work as a if it was a class PersonEntry
you can call new
on.
key method to generate objects of PersonEntry
that share dependencies via this EntryFactory
environment.
63 64 65 66 67 68 69 70 71 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 63 def new(data, dependencies: {}) PersonEntry.new( data, person_parser: person_parser, attr_map: @attr_map, dependencies: dependencies, logger: logger ) end |
#newFactory(schema: nil) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 37 def newFactory(schema: nil) self.class.new( environment, schema: schema, person_parser: @source_person_parser, default_parser: @default_parser, attr_map: @attr_map ) end |
#to_array_of_hashes(**kargs) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 100 def to_array_of_hashes(**kargs) data = [] content, file, encoding, format = kargs.values_at(:content, :file, :encoding, :format) # Support for multiple file if file.is_a?(Array) return file.each_with_object([]) do |f, out| logger.info("Parsing file '#{f}'") curr = to_array_of_hashes(**kargs.merge(file: f)) out.concat(curr) end end # Get content only when it's not :xls # note: even if content was provided, file takes precedence content = get_file_content(file, format, encoding) if (format != :xls) && file case content when Hash logger.error("Input data as 'Hash' not supported. Expecting 'Enumerable' or 'String'") exit(1) when String deps = {check_headers: true} if kargs[:check_headers] to_array_of_hashes(content: person_parser.parse(format, content, deps: deps || {})) 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.error("Input content 'Array' of '#{sample.class}' is not supported.") end else if file && format == :xls person_parser.parse(format, file) else logger.error("Could not obtain any data out of these: #{kargs}. Given content: '#{content.class}'") exit(1) end end.tap do |out_array| start_from_two = (format == :csv) || format == :xls out_array.each_with_index do |entry_hash, i| entry_hash["idx"] = start_from_two ? i + 2 : i + 1 entry_hash["source_file"] = file end end end |