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
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::Timestamp
Data::Files::Timestamp::DEFAULT_TIMESTAMP
Constants included from Data::Files::Folder
Data::Files::Folder::PRESERVED_FILES
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
PersonEntrythat share dependencies via thisEntryFactoryenvironment. -
#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) ⇒ Array<Hash>
Input file format parsing to obtain the final processing model.
Methods included from Data::Files::ClassMethods
Methods included from Data::Files::RelativePath
Methods included from Data::Files::Timestamp
Methods included from Data::Files::Folder
#archive_file, #clear_folder, #csv_files, #ensure_file_path!, #ensure_folder!, #folder_files
Methods included from Language::AuxiliarLogger
Methods included from Data::Files::Encoding
#bom?, #encoding, #get_file_content_with_encoding, #remove_bom, #scoped_encoding
Methods included from Data::Files::Content
#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 51 52 53 54 55 56 57 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 29 def initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil) # rubocop:disable Naming/MethodParameterName 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.
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 147 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 120 def entries( data: (no_data = true; nil), # rubocop:disable Style/Semicolon file: (no_file = true; nil), # rubocop:disable Style/Semicolon 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:.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 236 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 File.exist?(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.
91 92 93 94 95 96 97 98 99 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 91 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
59 60 61 62 63 64 65 66 67 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 59 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)
75 76 77 78 79 80 81 82 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 75 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) ⇒ Array<Hash>
This only takes care of the file format parsing alone (i.e. csv, json).
- The parsing of the file happens here.
- It also adds a row index (idx column).
Input file format parsing to obtain the final processing model.
155 156 157 158 159 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 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 220 221 222 |
# File 'lib/eco/api/common/people/entry_factory.rb', line 155 def to_array_of_hashes(**kargs) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength content, file, encoding, format = kargs.values_at( :content, :file, :encoding, :format ) # Support for multiple file (iterated self call) if file.is_a?(Array) return file.each_with_object([]) do |f, out| log(:info) { "Parsing file '#{f}'" } curr = to_array_of_hashes(**kargs, file: f) out.concat(curr) end end # Get content only when it's not :xls, nor :json (so when is :csv). # @note: even if content was provided, file takes precedence if file && get_content?(format) content = get_file_content( file, encoding: encoding ) end case content when Hash log(:error) { "Input data as 'Hash' not supported. Expecting 'Enumerable' or 'String'" } exit(1) when String deps ||= {} deps = deps.merge(**kargs.slice(: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 first_idx = start_from_two ? 2 : 1 # add row index column out_array.each.with_index(first_idx) do |entry_hash, idx| entry_hash['idx'] = idx entry_hash['source_file'] = file end end end |