lib/sdr_client/redesigned_client/deposit.rb
# frozen_string_literal: true
module SdrClient
class RedesignedClient
# Deposit into the SDR API
class Deposit
def self.deposit_model(...)
new(...).deposit_model
end
# @param [Cocina::Model::RequestDRO] model for depositing
# @param [Boolean] accession should the accessionWF be started
# @param [String] basepath filepath to which filepaths are relative
# @param [Array<String>] files a list of relative filepaths to upload
# @param [Hash] options optional parameters
# @option options [Boolean] assign_doi should a DOI be assigned to this item
# @option options [String] priority what processing priority should be used ('low', 'default')
# @option options [String] user_versions action (none, new, update) to take for user version when closing version
# @option options [String] grouping_strategy what strategy will be used to group files
# @option options [String] file_set_strategy what strategy will be used to group file sets
# @option options [RequestBuilder] request_builder a request builder instance
def initialize(model:, accession:, basepath:, files: [], **options)
@model = model
@accession = accession
@basepath = basepath
@files = files
@options = options
end
def deposit_model # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
check_files_exist!
child_files_match! unless options[:request_builder]
file_metadata = UploadFilesMetadataBuilder.build(files: files, mime_types: mime_types, basepath: basepath)
upload_responses = UploadFiles.upload(file_metadata: file_metadata,
filepath_map: filepath_map)
if options[:request_builder]
@model = StructuralGrouper.group(
request_builder: options[:request_builder],
upload_responses: upload_responses,
grouping_strategy: options[:grouping_strategy],
file_set_strategy: options[:file_set_strategy]
)
child_files_match!
end
new_request_dro = UpdateDroWithFileIdentifiers.update(request_dro: model,
upload_responses: upload_responses)
CreateResource.run(accession: accession,
priority: options[:priority],
assign_doi: options[:assign_doi],
user_versions: options[:user_versions],
metadata: new_request_dro)
end
private
attr_reader :model, :files, :basepath, :accession, :options
def check_files_exist!
SdrClient::RedesignedClient.config.logger.info('checking to see if files exist')
files.each do |filepath|
raise Errno::ENOENT, filepath unless ::File.exist?(absolute_filepath_for(filepath))
end
end
def child_files_match!
# Files without request files.
files.each do |filepath|
raise "Request file not provided for #{filepath}" if request_files[filepath].nil?
end
# Request files without files
request_files.each_key do |request_filename|
raise "File not provided for request file #{request_filename}" unless files.include?(request_filename)
end
end
# Map of relative filepaths to mimetypes
def mime_types
return mime_types_from_request_builder if options[:request_builder]
request_files.transform_values { |file| file.hasMimeType || 'application/octet-stream' }
end
def mime_types_from_request_builder
files.to_h do |filepath|
[filepath, options[:request_builder].for(filepath)['mime_type']]
end
end
# Map of absolute filepaths to Cocina::Models::RequestFiles
def request_files
@request_files ||=
if model.structural
model.structural.contains.map do |file_set|
file_set.structural.contains.map do |file|
[file.filename, file]
end
end.flatten(1).to_h
else
{}
end
end
def absolute_filepath_for(filename)
::File.join(basepath, filename)
end
def filepath_map
@filepath_map ||= files.each_with_object({}) do |filepath, obj|
obj[filepath] = absolute_filepath_for(filepath)
end
end
end
end
end