Class: Eco::API::Common::People::EntryFactory
- Inherits:
-
Session::BaseSession
- Object
- Session::BaseSession
- Eco::API::Common::People::EntryFactory
- Includes:
- Data::Files
- 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).
Constant Summary
Constants included from Data::Files
Data::Files::DEFAULT_TIMESTAMP_PATTERN
Constants included from Data::Files::Encoding
Data::Files::Encoding::BOM_BYTES
Instance Attribute Summary collapse
-
#schema ⇒ Ecoportal::API::V1::PersonSchema
readonly
person schema to be used in this entry factory.
Attributes included from Language::AuxiliarLogger
Attributes inherited from Session::BaseSession
#config, #environment, #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
rubocop:disable Naming/MethodName.
-
#person_parser ⇒ Eco::API::Common::People::PersonParser
provides with a Eco::API::Common::People::PersonParser object (collection of attribute parsers).
-
#to_array_of_hashes(**kargs) ⇒ Object
rubocop:disable Metrics/AbcSize.
Methods included from Data::Files::ClassMethods
#copy_file, #create_directory, #csv_files, #dir_exists?, #file_basename, #file_empty?, #file_exists?, #file_fullpath, #file_name, #folder_files, #script_subfolder, #split, #timestamp, #timestamp_file
Methods included from Data::Files::Encoding
#encoding, #file_empty?, #file_exists?, #get_file_content_with_encoding, #has_bom?, #remove_bom, #scoped_encoding
Methods included from Language::AuxiliarLogger
Methods included from Data::Files::InstanceMethods
#get_file_content, #read_with_tolerance
Methods inherited from Session::BaseSession
#api, #api?, #file_manager, #logger, #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.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 29 def initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil) super(e) msg = "Constructor needs a PersonSchema. Given: #{schema.class}" fatal msg unless schema.is_a?(Ecoportal::API::V1::PersonSchema) msg = "Expecting PersonParser. Given: #{person_parser.class}" fatal msg if person_parser && !person_parser.is_a?(Eco::API::Common::People::PersonParser) msg = "Expecting Mapper object. Given: #{attr_map.class}" fatal msg if attr_map && !attr_map.is_a?(Eco::Data::Mapper) @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
#schema ⇒ Ecoportal::API::V1::PersonSchema (readonly)
person schema to be used in this entry factory
16 17 18 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 16 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.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 105 def entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil), **) # rubocop:disable Style/Semicolon msg = "You should at least use data: or file:, but not both" fatal msg if no_data == no_file msg = "You must specify a valid format: (symbol) when you use file." fatal msg if file && no_format msg = "Format should be a Symbol. Given '#{format}'" fatal msg if format && !format.is_a?(Symbol) msg = "There is no parser/serializer for format ':#{format}'" fatal msg 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:
.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 186 def export(data:, file: "export", format: :csv, encoding: "utf-8", internal_names: false) msg = "data: Expected Eco::API::Organization::People object. Given: #{data.class}" fatal msg unless data.is_a?(Eco::API::Organization::People) fatal "A file should be specified." if file.to_s.strip.empty? fatal "Format should be a Symbol. Given '#{format}'" if format && !format.is_a?(Symbol) msg = "There is no parser/serializer for format ':#{format}'" fatal msg unless @person_parser.defined?(format) run = true if self.class.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 return unless run deps = {"supervisor_id" => {people: data}} data_entries = data.map do |person| new(person, dependencies: deps).then 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 |
#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.
80 81 82 83 84 85 86 87 88 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 80 def new(data, dependencies: {}) PersonEntry.new( data, person_parser: person_parser, attr_map: @attr_map, dependencies: dependencies, logger: logger ) end |
#newFactory(schema: nil) ⇒ Object
rubocop:disable Naming/MethodName
52 53 54 55 56 57 58 59 60 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 52 def newFactory(schema: nil) # rubocop:disable Naming/MethodName self.class.new( environment, schema: schema, person_parser: @source_person_parser, default_parser: @default_parser, attr_map: @attr_map ) end |
#person_parser ⇒ Eco::API::Common::People::PersonParser
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)
65 66 67 68 69 70 71 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 65 def person_parser if @person_parser_patch_version < @source_person_parser.patch_version @person_parser.merge(@source_person_parser) @person_parser_patch_version = @source_person_parser.patch_version end @person_parser end |
#to_array_of_hashes(**kargs) ⇒ Object
rubocop:disable Metrics/AbcSize
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 125 def to_array_of_hashes(**kargs) # rubocop:disable Metrics/AbcSize 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 if (format != :xls) && file # rubocop:disable Style/IfUnlessModifier content = get_file_content(file, encoding: encoding) end 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 when NilClass abort("There is NO input data") else abort("Input content 'Array' of '#{sample.class}' is not supported.") end else if file && format == :xls person_parser.parse(format, file) else abort("Could not obtain any data out of these: #{kargs}. Given content: '#{content.class}'") 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 |