# 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] 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