app/parsers/bulkrax/application_parser.rb in bulkrax-1.0.2 vs app/parsers/bulkrax/application_parser.rb in bulkrax-2.0.0
- old
+ new
@@ -1,17 +1,17 @@
# frozen_string_literal: true
module Bulkrax
- class ApplicationParser
- attr_accessor :importerexporter
+ class ApplicationParser # rubocop:disable Metrics/ClassLength
+ attr_accessor :importerexporter, :headers
alias importer importerexporter
alias exporter importerexporter
- delegate :only_updates, :limit, :current_run, :errors,
- :seen, :increment_counters, :parser_fields, :user,
- :exporter_export_path, :exporter_export_zip_path, :importer_unzip_path, :validate_only,
- :status, :status_info, :status_at,
- to: :importerexporter
+ delegate :only_updates, :limit, :current_run, :errors, :mapping,
+ :seen, :increment_counters, :parser_fields, :user, :keys_without_numbers,
+ :key_without_numbers, :status, :status_info, :status_at,
+ :exporter_export_path, :exporter_export_zip_path, :importer_unzip_path, :validate_only,
+ to: :importerexporter
def self.parser_fields
{}
end
@@ -23,10 +23,11 @@
true
end
def initialize(importerexporter)
@importerexporter = importerexporter
+ @headers = []
end
# @api
def entry_class
raise StandardError, 'must be defined'
@@ -41,26 +42,60 @@
def records(_opts = {})
raise StandardError, 'must be defined'
end
def source_identifier
- @source_identifier ||= identifier_hash.values.first&.[]("from")&.first&.to_sym || :source_identifier
+ @source_identifier ||= get_field_mapping_hash_for('source_identifier')&.values&.first&.[]('from')&.first&.to_sym || :source_identifier
end
def work_identifier
- @work_identifier ||= identifier_hash.keys.first&.to_sym || :source
+ @work_identifier ||= get_field_mapping_hash_for('source_identifier')&.keys&.first&.to_sym || :source
end
- def identifier_hash
- @identifier_hash ||= importerexporter.mapping.select do |_, h|
- h.key?("source_identifier")
- end
- raise StandardError, "more than one source_identifier declared: #{@identifier_hash.keys.join(', ')}" if @identifier_hash.length > 1
+ def related_parents_raw_mapping
+ @related_parents_raw_mapping ||= get_field_mapping_hash_for('related_parents_field_mapping')&.values&.first&.[]('from')&.first
+ end
- @identifier_hash
+ def related_parents_parsed_mapping
+ @related_parents_parsed_mapping ||= get_field_mapping_hash_for('related_parents_field_mapping')&.keys&.first
end
+ def related_children_raw_mapping
+ @related_children_raw_mapping ||= get_field_mapping_hash_for('related_children_field_mapping')&.values&.first&.[]('from')&.first
+ end
+
+ def related_children_parsed_mapping
+ @related_children_parsed_mapping ||= get_field_mapping_hash_for('related_children_field_mapping')&.keys&.first
+ end
+
+ def get_field_mapping_hash_for(key)
+ return instance_variable_get("@#{key}_hash") if instance_variable_get("@#{key}_hash").present?
+
+ instance_variable_set(
+ "@#{key}_hash",
+ importerexporter.mapping.with_indifferent_access.select { |_, h| h.key?(key) }
+ )
+ raise StandardError, "more than one #{key} declared: #{instance_variable_get("@#{key}_hash").keys.join(', ')}" if instance_variable_get("@#{key}_hash").length > 1
+
+ instance_variable_get("@#{key}_hash")
+ end
+
+ def collection_field_mapping
+ ActiveSupport::Deprecation.warn(
+ 'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
+ ' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
+ )
+ Bulkrax.collection_field_mapping[self.entry_class.to_s]&.to_sym || :collection
+ end
+
+ def model_field_mappings
+ model_mappings = Bulkrax.field_mappings[self.class.to_s]&.dig('model', :from) || []
+ model_mappings |= ['model']
+
+ model_mappings
+ end
+
def perform_method
if self.validate_only
'perform_now'
else
'perform_later'
@@ -89,80 +124,23 @@
path
)
path
end
+ # Base path for imported and exported files
+ def base_path(type = 'import')
+ ENV['HYKU_MULTITENANT'] ? File.join(Bulkrax.send("#{type}_path"), Site.instance.account.name) : Bulkrax.send("#{type}_path")
+ end
+
# Path where we'll store the import metadata and files
# this is used for uploaded and cloud files
def path_for_import
- @path_for_import = File.join(Bulkrax.import_path, importerexporter.path_string)
+ @path_for_import = File.join(base_path, importerexporter.path_string)
FileUtils.mkdir_p(@path_for_import) unless File.exist?(@path_for_import)
@path_for_import
end
- # Optional, only used by certain parsers
- # Other parsers should override with a custom or empty method
- # Will be skipped unless the #record is a Hash
- def create_parent_child_relationships
- parents.each do |key, value|
- parent = entry_class.where(
- identifier: key,
- importerexporter_id: importerexporter.id,
- importerexporter_type: 'Bulkrax::Importer'
- ).first
-
- # not finding the entries here indicates that the given identifiers are incorrect
- # in that case we should log that
- children = value.map do |child|
- entry_class.where(
- identifier: child,
- importerexporter_id: importerexporter.id,
- importerexporter_type: 'Bulkrax::Importer'
- ).first
- end.compact.uniq
-
- if parent.present? && (children.length != value.length)
- # Increment the failures for the number we couldn't find
- # Because all of our entries have been created by now, if we can't find them, the data is wrong
- Rails.logger.error("Expected #{value.length} children for parent entry #{parent.id}, found #{children.length}")
- break if children.empty?
- Rails.logger.warn("Adding #{children.length} children to parent entry #{parent.id} (expected #{value.length})")
- end
- parent_id = parent.id
- child_entry_ids = children.map(&:id)
- ChildRelationshipsJob.perform_later(parent_id, child_entry_ids, current_run.id)
- end
- rescue StandardError => e
- status_info(e)
- end
-
- def parents
- @parents ||= setup_parents
- end
-
- def setup_parents
- pts = []
- records.each do |record|
- r = if record.respond_to?(:to_h)
- record.to_h
- else
- record
- end
- next unless r.is_a?(Hash)
- children = if r[:children].is_a?(String)
- r[:children].split(/\s*[:;|]\s*/)
- else
- r[:children]
- end
- next if children.blank?
- pts << {
- r[source_identifier] => children
- }
- end
- pts.blank? ? pts : pts.inject(:merge)
- end
-
def setup_export_file
raise StandardError, 'must be defined' if exporter?
end
def write_files
@@ -286,14 +264,11 @@
end
private
def real_import_file_path
- if file? && zip?
- unzip(parser_fields['import_file_path'])
- return importer_unzip_path
- else
- parser_fields['import_file_path']
- end
+ return importer_unzip_path if file? && zip?
+
+ parser_fields['import_file_path']
end
end
end