From d5bda39e3ad4556acfb29c8c1000098787eda280 Mon Sep 17 00:00:00 2001 From: Peter Mangiafico Date: Mon, 15 Mar 2021 13:45:52 -0700 Subject: [PATCH 1/5] normalize content types in pre-assembly to match current set --- app/lib/pre_assembly/digital_object.rb | 1 + app/models/batch_context.rb | 3 +- app/views/batch_contexts/_new_bc_form.erb | 1 + spec/features/dark_file_object_spec.rb | 2 +- spec/features/document_spec.rb | 2 +- spec/features/image_spec.rb | 2 +- spec/features/map_spec.rb | 75 +++++++++++++++++++++++ spec/features/public_tif_spec.rb | 2 +- spec/models/batch_context_spec.rb | 3 +- 9 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 spec/features/map_spec.rb diff --git a/app/lib/pre_assembly/digital_object.rb b/app/lib/pre_assembly/digital_object.rb index de1997e58..28470ae76 100644 --- a/app/lib/pre_assembly/digital_object.rb +++ b/app/lib/pre_assembly/digital_object.rb @@ -47,6 +47,7 @@ def content_md_creation_style Cocina::Models::Vocab.object => :file, Cocina::Models::Vocab.book => :simple_book, Cocina::Models::Vocab.manuscript => :simple_book, + Cocina::Models::Vocab.document => :document, Cocina::Models::Vocab.map => :map, Cocina::Models::Vocab.three_dimensional => :'3d' }.fetch(object_type, content_structure.to_sym) diff --git a/app/models/batch_context.rb b/app/models/batch_context.rb index 47c80cfe8..865475be8 100644 --- a/app/models/batch_context.rb +++ b/app/models/batch_context.rb @@ -23,7 +23,8 @@ class BatchContext < ApplicationRecord 'file' => 3, 'media' => 4, '3d' => 5, - 'document' => 6 + 'document' => 6, + 'maps' => 7 } enum content_metadata_creation: { diff --git a/app/views/batch_contexts/_new_bc_form.erb b/app/views/batch_contexts/_new_bc_form.erb index c3acb0000..894c5b631 100644 --- a/app/views/batch_contexts/_new_bc_form.erb +++ b/app/views/batch_contexts/_new_bc_form.erb @@ -20,6 +20,7 @@ ['File', 'file'], ['Media', 'media'], ['3D', '3d'], + ['Map', 'maps'] ] %> diff --git a/spec/features/dark_file_object_spec.rb b/spec/features/dark_file_object_spec.rb index 7d6f56afb..1ffd54543 100644 --- a/spec/features/dark_file_object_spec.rb +++ b/spec/features/dark_file_object_spec.rb @@ -10,7 +10,7 @@ let(:bare_druid) { 'tx666tx9999' } let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'tx', '666', 'tx', '9999', bare_druid) } let(:cocina_model_dark_access) { instance_double(Cocina::Models::Access, access: 'dark') } - let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.media, access: cocina_model_dark_access) } + let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.object, access: cocina_model_dark_access) } let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } let(:exp_content_md) do diff --git a/spec/features/document_spec.rb b/spec/features/document_spec.rb index 82e1e5c15..52ff640bd 100644 --- a/spec/features/document_spec.rb +++ b/spec/features/document_spec.rb @@ -8,7 +8,7 @@ let(:bare_druid) { 'pr666rr9999' } let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'pr', '666', 'rr', '9999', bare_druid) } let(:cocina_model_world_access) { instance_double(Cocina::Models::Access, access: 'world') } - let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.media, access: cocina_model_world_access) } + let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.document, access: cocina_model_world_access) } let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } let(:exp_content_md) do diff --git a/spec/features/image_spec.rb b/spec/features/image_spec.rb index 6298ce518..082adf707 100644 --- a/spec/features/image_spec.rb +++ b/spec/features/image_spec.rb @@ -8,7 +8,7 @@ let(:bare_druid) { 'pr666rr9999' } let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'pr', '666', 'rr', '9999', bare_druid) } let(:cocina_model_world_access) { instance_double(Cocina::Models::Access, access: 'world') } - let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.media, access: cocina_model_world_access) } + let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.image, access: cocina_model_world_access) } let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } let(:exp_content_md) do diff --git a/spec/features/map_spec.rb b/spec/features/map_spec.rb new file mode 100644 index 000000000..8f25ba5b4 --- /dev/null +++ b/spec/features/map_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +RSpec.describe 'Create Map object', type: :feature do + let(:user) { create(:user) } + let(:user_id) { "#{user.sunet_id}@stanford.edu" } + let(:project_name) { "image-#{RandomWord.nouns.next}" } + let(:bundle_dir) { Rails.root.join('spec/test_data/image_jpg') } + let(:bare_druid) { 'pr666rr9999' } + let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'pr', '666', 'rr', '9999', bare_druid) } + let(:cocina_model_world_access) { instance_double(Cocina::Models::Access, access: 'world') } + let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.map, access: cocina_model_world_access) } + let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } + let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } + let(:exp_content_md) do + <<~XML + + + + + 3e9498107f73ff827e718d5c743f8813 + + + + XML + end + + before do + FileUtils.remove_dir(object_staging_dir) if Dir.exist?(object_staging_dir) + + login_as(user, scope: :user) + + allow(Dor::Services::Client).to receive(:object).and_return(dsc_object) + allow(StartAccession).to receive(:run).with(druid: "druid:#{bare_druid}", user: user.sunet_id) + end + + # have background jobs run synchronously + include ActiveJob::TestHelper + around do |example| + perform_enqueued_jobs do + example.run + end + end + + it do + visit '/' + expect(page).to have_selector('h3', text: 'Complete the form below') + + fill_in 'Project name', with: project_name + select 'Pre Assembly Run', from: 'Job type' + select 'Map', from: 'Content structure' + fill_in 'Bundle dir', with: bundle_dir + + click_button 'Submit' + exp_str = 'Success! Your job is queued. A link to job output will be emailed to you upon completion.' + expect(page).to have_content exp_str + + # go to job details page, wait for preassembly to finish + first('td > a').click + expect(page).to have_content project_name + expect(page).to have_link('Download') + + result_file = Rails.root.join(Settings.job_output_parent_dir, user_id, project_name, "#{project_name}_progress.yml") + yaml = YAML.load_file(result_file) + expect(yaml[:status]).to eq 'success' + + # we got all the expected content files + expect(Dir.children(File.join(object_staging_dir, 'content')).size).to eq 1 + + metadata_dir = File.join(object_staging_dir, 'metadata') + expect(Dir.children(metadata_dir).size).to eq 1 + + content_md_xml = File.open(File.join(metadata_dir, 'contentMetadata.xml')).read + expect(noko_doc(content_md_xml)).to be_equivalent_to exp_content_md + end +end diff --git a/spec/features/public_tif_spec.rb b/spec/features/public_tif_spec.rb index 1df9a6448..e3907adea 100644 --- a/spec/features/public_tif_spec.rb +++ b/spec/features/public_tif_spec.rb @@ -10,7 +10,7 @@ let(:bare_druid) { 'tf111tf2222' } let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'tf', '111', 'tf', '2222', bare_druid) } let(:cocina_model_world_access) { instance_double(Cocina::Models::Access, access: 'world') } - let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.media, access: cocina_model_world_access) } + let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.image, access: cocina_model_world_access) } let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } let(:exp_content_md) do diff --git a/spec/models/batch_context_spec.rb b/spec/models/batch_context_spec.rb index fe5865e30..d01d79394 100644 --- a/spec/models/batch_context_spec.rb +++ b/spec/models/batch_context_spec.rb @@ -63,7 +63,8 @@ 'file' => 3, 'media' => 4, '3d' => 5, - 'document' => 6 + 'document' => 6, + 'maps' => 7 ) end From a7f2b2ef1e3742a1ccd437e5a9dbfabab75ab729 Mon Sep 17 00:00:00 2001 From: Peter Mangiafico Date: Tue, 16 Mar 2021 09:18:44 -0700 Subject: [PATCH 2/5] remove map spec; add webarchive seed as an option --- app/lib/pre_assembly/digital_object.rb | 3 +- app/models/batch_context.rb | 3 +- app/views/batch_contexts/_new_bc_form.erb | 3 +- spec/features/map_spec.rb | 75 ----------------------- spec/models/batch_context_spec.rb | 3 +- 5 files changed, 8 insertions(+), 79 deletions(-) delete mode 100644 spec/features/map_spec.rb diff --git a/app/lib/pre_assembly/digital_object.rb b/app/lib/pre_assembly/digital_object.rb index 28470ae76..7d29fca68 100644 --- a/app/lib/pre_assembly/digital_object.rb +++ b/app/lib/pre_assembly/digital_object.rb @@ -49,7 +49,8 @@ def content_md_creation_style Cocina::Models::Vocab.manuscript => :simple_book, Cocina::Models::Vocab.document => :document, Cocina::Models::Vocab.map => :map, - Cocina::Models::Vocab.three_dimensional => :'3d' + Cocina::Models::Vocab.three_dimensional => :'3d', + Cocina::Models::Vocab.webarchive_seed => :'webarchive-seed' }.fetch(object_type, content_structure.to_sym) end diff --git a/app/models/batch_context.rb b/app/models/batch_context.rb index 865475be8..cc45e175e 100644 --- a/app/models/batch_context.rb +++ b/app/models/batch_context.rb @@ -24,7 +24,8 @@ class BatchContext < ApplicationRecord 'media' => 4, '3d' => 5, 'document' => 6, - 'maps' => 7 + 'maps' => 7, + 'webarchive_seed' => 8 } enum content_metadata_creation: { diff --git a/app/views/batch_contexts/_new_bc_form.erb b/app/views/batch_contexts/_new_bc_form.erb index 894c5b631..9d10519fe 100644 --- a/app/views/batch_contexts/_new_bc_form.erb +++ b/app/views/batch_contexts/_new_bc_form.erb @@ -20,7 +20,8 @@ ['File', 'file'], ['Media', 'media'], ['3D', '3d'], - ['Map', 'maps'] + ['Map', 'maps'], + ['Webarchive seed', 'webarchive_seed'] ] %> diff --git a/spec/features/map_spec.rb b/spec/features/map_spec.rb deleted file mode 100644 index 8f25ba5b4..000000000 --- a/spec/features/map_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe 'Create Map object', type: :feature do - let(:user) { create(:user) } - let(:user_id) { "#{user.sunet_id}@stanford.edu" } - let(:project_name) { "image-#{RandomWord.nouns.next}" } - let(:bundle_dir) { Rails.root.join('spec/test_data/image_jpg') } - let(:bare_druid) { 'pr666rr9999' } - let(:object_staging_dir) { Rails.root.join(Settings.assembly_staging_dir, 'pr', '666', 'rr', '9999', bare_druid) } - let(:cocina_model_world_access) { instance_double(Cocina::Models::Access, access: 'world') } - let(:item) { instance_double(Cocina::Models::DRO, type: Cocina::Models::Vocab.map, access: cocina_model_world_access) } - let(:dsc_object_version) { instance_double(Dor::Services::Client::ObjectVersion, openable?: true) } - let(:dsc_object) { instance_double(Dor::Services::Client::Object, version: dsc_object_version, find: item) } - let(:exp_content_md) do - <<~XML - - - - - 3e9498107f73ff827e718d5c743f8813 - - - - XML - end - - before do - FileUtils.remove_dir(object_staging_dir) if Dir.exist?(object_staging_dir) - - login_as(user, scope: :user) - - allow(Dor::Services::Client).to receive(:object).and_return(dsc_object) - allow(StartAccession).to receive(:run).with(druid: "druid:#{bare_druid}", user: user.sunet_id) - end - - # have background jobs run synchronously - include ActiveJob::TestHelper - around do |example| - perform_enqueued_jobs do - example.run - end - end - - it do - visit '/' - expect(page).to have_selector('h3', text: 'Complete the form below') - - fill_in 'Project name', with: project_name - select 'Pre Assembly Run', from: 'Job type' - select 'Map', from: 'Content structure' - fill_in 'Bundle dir', with: bundle_dir - - click_button 'Submit' - exp_str = 'Success! Your job is queued. A link to job output will be emailed to you upon completion.' - expect(page).to have_content exp_str - - # go to job details page, wait for preassembly to finish - first('td > a').click - expect(page).to have_content project_name - expect(page).to have_link('Download') - - result_file = Rails.root.join(Settings.job_output_parent_dir, user_id, project_name, "#{project_name}_progress.yml") - yaml = YAML.load_file(result_file) - expect(yaml[:status]).to eq 'success' - - # we got all the expected content files - expect(Dir.children(File.join(object_staging_dir, 'content')).size).to eq 1 - - metadata_dir = File.join(object_staging_dir, 'metadata') - expect(Dir.children(metadata_dir).size).to eq 1 - - content_md_xml = File.open(File.join(metadata_dir, 'contentMetadata.xml')).read - expect(noko_doc(content_md_xml)).to be_equivalent_to exp_content_md - end -end diff --git a/spec/models/batch_context_spec.rb b/spec/models/batch_context_spec.rb index d01d79394..a205f4db2 100644 --- a/spec/models/batch_context_spec.rb +++ b/spec/models/batch_context_spec.rb @@ -64,7 +64,8 @@ 'media' => 4, '3d' => 5, 'document' => 6, - 'maps' => 7 + 'maps' => 7, + 'webarchive_seed' => 8 ) end From ec8ab129d03e492b7fafb6d382578d622aa16843 Mon Sep 17 00:00:00 2001 From: Peter Mangiafico Date: Tue, 16 Mar 2021 11:13:12 -0700 Subject: [PATCH 3/5] bump assembly-objectfile and add unit tests --- Gemfile | 2 +- Gemfile.lock | 4 +- spec/lib/pre_assembly/digital_object_spec.rb | 104 +++++++++++++++++++ 3 files changed, 107 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 5f0fce66a..2bb0bfb9b 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'uglifier' # compressor for JavaScript assets # Stanford gems gem 'assembly-image', '~> 1.7' -gem 'assembly-objectfile', '~> 1.10' +gem 'assembly-objectfile', '~> 1.10', '>= 1.10.2' # webarchive-seed and reading order is supported in 1.10.2 and better gem 'dor-services-client', '~> 6.27' gem 'dor-workflow-client' gem 'druid-tools' diff --git a/Gemfile.lock b/Gemfile.lock index 115ea782e..ae1dff0e6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -67,7 +67,7 @@ GEM assembly-image (1.7.7) assembly-objectfile (>= 1.6.4) mini_exiftool (>= 1.6, < 3) - assembly-objectfile (1.10.0) + assembly-objectfile (1.10.2) activesupport (>= 5.2.0) deprecation dry-struct (~> 1.0) @@ -469,7 +469,7 @@ PLATFORMS DEPENDENCIES assembly-image (~> 1.7) - assembly-objectfile (~> 1.10) + assembly-objectfile (~> 1.10, >= 1.10.2) bootstrap (~> 4.3, >= 4.3.1) capistrano-bundler capistrano-passenger diff --git a/spec/lib/pre_assembly/digital_object_spec.rb b/spec/lib/pre_assembly/digital_object_spec.rb index ec628fee2..2d1901e7b 100644 --- a/spec/lib/pre_assembly/digital_object_spec.rb +++ b/spec/lib/pre_assembly/digital_object_spec.rb @@ -175,6 +175,110 @@ def add_object_files(extension = 'tif', all_files_public: false) end end + describe 'map content metadata' do + let(:exp_xml) do + noko_doc <<-XML + + + + + 1111 + + + + + + 2222 + + + + XML + end + + let(:assembly_directory) { PreAssembly::AssemblyDirectory.new(druid_id: druid.id) } + + before do + allow(object).to receive(:druid).and_return(druid) + allow(object).to receive(:object_type).and_return('') + allow(bc).to receive(:content_structure).and_return('map') + add_object_files('jp2') + allow(object).to receive(:assembly_directory).and_return(assembly_directory) + end + + around do |example| + RSpec::Mocks.with_temporary_scope do + Dir.mktmpdir(*tmp_dir_args) do |tmp_area| + allow(assembly_directory).to receive(:druid_tree_dir).and_return(tmp_area) + example.run + end + end + end + + it 'generates the expected xml text' do + expect(noko_doc(object.send(:create_content_metadata, false))).to be_equivalent_to exp_xml + end + + it 'is able to write the content_metadata XML to a file' do + assembly_directory.create_object_directories + file_name = object.send(:assembly_directory).content_metadata_file + expect(File.exist?(file_name)).to eq(false) + object.send(:generate_content_metadata, false) + expect(noko_doc(File.read(file_name))).to be_equivalent_to exp_xml + end + end + + describe 'webarchive-seed content metadata' do + let(:exp_xml) do + noko_doc <<-XML + + + + + 1111 + + + + + + 2222 + + + + XML + end + + let(:assembly_directory) { PreAssembly::AssemblyDirectory.new(druid_id: druid.id) } + + before do + allow(object).to receive(:druid).and_return(druid) + allow(object).to receive(:object_type).and_return('') + allow(bc).to receive(:content_structure).and_return('webarchive-seed') + add_object_files('jp2') + allow(object).to receive(:assembly_directory).and_return(assembly_directory) + end + + around do |example| + RSpec::Mocks.with_temporary_scope do + Dir.mktmpdir(*tmp_dir_args) do |tmp_area| + allow(assembly_directory).to receive(:druid_tree_dir).and_return(tmp_area) + example.run + end + end + end + + it 'generates the expected xml text' do + expect(noko_doc(object.send(:create_content_metadata, false))).to be_equivalent_to exp_xml + end + + it 'is able to write the content_metadata XML to a file' do + assembly_directory.create_object_directories + file_name = object.send(:assembly_directory).content_metadata_file + expect(File.exist?(file_name)).to eq(false) + object.send(:generate_content_metadata, false) + expect(noko_doc(File.read(file_name))).to be_equivalent_to exp_xml + end + end + describe 'grouped by filename, simple book content metadata without file attributes' do let(:exp_xml) do noko_doc <<-XML From 3854efad79091ade72a7340fd12c132ea3be4698 Mon Sep 17 00:00:00 2001 From: Peter Mangiafico Date: Tue, 16 Mar 2021 17:32:28 -0700 Subject: [PATCH 4/5] reading order --- Gemfile | 3 +- Gemfile.lock | 36 ++----------------- .../pre_assembly/content_metadata_creator.rb | 6 ++-- app/lib/pre_assembly/digital_object.rb | 6 ++++ app/models/batch_context.rb | 3 +- app/views/batch_contexts/_new_bc_form.erb | 5 +-- spec/models/batch_context_spec.rb | 3 +- 7 files changed, 20 insertions(+), 42 deletions(-) diff --git a/Gemfile b/Gemfile index 5f0fce66a..a166d0bb2 100644 --- a/Gemfile +++ b/Gemfile @@ -24,8 +24,7 @@ gem 'uglifier' # compressor for JavaScript assets # Stanford gems gem 'assembly-image', '~> 1.7' -gem 'assembly-objectfile', '~> 1.10' -gem 'dor-services-client', '~> 6.27' +gem 'assembly-objectfile', '~> 1.10', '>= 1.10.2' # webarchive-seed and reading order is supported in 1.10.2 and bettergem 'dor-services-client', '~> 6.27' gem 'dor-workflow-client' gem 'druid-tools' diff --git a/Gemfile.lock b/Gemfile.lock index 115ea782e..74a0e223c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -67,7 +67,7 @@ GEM assembly-image (1.7.7) assembly-objectfile (>= 1.6.4) mini_exiftool (>= 1.6, < 3) - assembly-objectfile (1.10.0) + assembly-objectfile (1.10.2) activesupport (>= 5.2.0) deprecation dry-struct (~> 1.0) @@ -115,17 +115,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - cocina-models (0.55.0) - activesupport - dry-struct (~> 1.0) - dry-types (~> 1.1) - openapi3_parser - openapi_parser - thor - zeitwerk (~> 2.1) coderay (1.1.3) - commonmarker (0.21.2) - ruby-enum (~> 0.5) concurrent-ruby (1.1.8) config (3.0.0) deep_merge (~> 1.2, >= 1.2.1) @@ -155,13 +145,6 @@ GEM capistrano-one_time_key capistrano-shared_configs docile (1.3.5) - dor-services-client (6.27.0) - activesupport (>= 4.2, < 7) - cocina-models (~> 0.55.0) - deprecation - faraday (>= 0.15, < 2) - moab-versioning (~> 4.0) - zeitwerk (~> 2.1) dor-workflow-client (3.23.1) activesupport (>= 3.2.1, < 7) deprecation (>= 0.99.0) @@ -271,11 +254,6 @@ GEM mini_mime (1.0.2) mini_portile2 (2.5.0) minitest (5.14.4) - moab-versioning (4.4.1) - druid-tools (>= 1.0.0) - json - nokogiri - nokogiri-happymapper mono_logger (1.1.0) multi_json (1.15.0) multipart-post (2.1.1) @@ -290,13 +268,7 @@ GEM racc (~> 1.4) nokogiri (1.11.2-x86_64-linux) racc (~> 1.4) - nokogiri-happymapper (0.8.1) - nokogiri (~> 1.5) okcomputer (1.18.4) - openapi3_parser (0.9.0) - commonmarker (~> 0.17) - psych (~> 3.1) - openapi_parser (0.12.1) orm_adapter (0.5.0) parallel (1.20.1) parser (3.0.0.0) @@ -311,7 +283,6 @@ GEM pry (~> 0.13.0) pry-rails (0.3.9) pry (>= 0.10.4) - psych (3.3.1) public_suffix (4.0.6) racc (1.5.2) rack (2.2.3) @@ -398,8 +369,6 @@ GEM unicode-display_width (>= 1.4.0, < 1.7) rubocop-rspec (1.41.0) rubocop (>= 0.68.1) - ruby-enum (0.9.0) - i18n ruby-progressbar (1.11.0) ruby2_keywords (0.0.4) sassc (2.0.1) @@ -469,7 +438,7 @@ PLATFORMS DEPENDENCIES assembly-image (~> 1.7) - assembly-objectfile (~> 1.10) + assembly-objectfile (~> 1.10, >= 1.10.2) bootstrap (~> 4.3, >= 4.3.1) capistrano-bundler capistrano-passenger @@ -480,7 +449,6 @@ DEPENDENCIES devise devise-remote-user dlss-capistrano (~> 3.10) - dor-services-client (~> 6.27) dor-workflow-client druid-tools equivalent-xml diff --git a/app/lib/pre_assembly/content_metadata_creator.rb b/app/lib/pre_assembly/content_metadata_creator.rb index da79dd36a..c965115f2 100644 --- a/app/lib/pre_assembly/content_metadata_creator.rb +++ b/app/lib/pre_assembly/content_metadata_creator.rb @@ -4,12 +4,13 @@ module PreAssembly class ContentMetadataCreator # rubocop:disable Metrics/ParameterLists def initialize(druid_id:, content_md_creation:, object_files:, - content_md_creation_style:, media_manifest:, add_file_attributes:) + content_md_creation_style:, media_manifest:, reading_order:, add_file_attributes:) @druid_id = druid_id @content_md_creation = content_md_creation @object_files = object_files @content_md_creation_style = content_md_creation_style @media_manifest = media_manifest + @reading_order = reading_order @add_file_attributes = add_file_attributes end # rubocop:enable Metrics/ParameterLists @@ -24,13 +25,14 @@ def create add_exif: false, bundle: content_md_creation.to_sym, style: content_md_creation_style, + reading_order: reading_order, add_file_attributes: add_file_attributes) end private attr_reader :druid_id, :content_md_creation, :object_files, - :content_md_creation_style, :media_manifest, :add_file_attributes + :content_md_creation_style, :media_manifest, :reading_order, :add_file_attributes # Object files that should be included in content metadata. def content_object_files diff --git a/app/lib/pre_assembly/digital_object.rb b/app/lib/pre_assembly/digital_object.rb index de1997e58..af52f9642 100644 --- a/app/lib/pre_assembly/digital_object.rb +++ b/app/lib/pre_assembly/digital_object.rb @@ -118,11 +118,17 @@ def generate_content_metadata(file_attributes_supplied) # Invoke the contentMetadata creation method used by the project # @param [Boolean] file_attributes_supplied - true if publish/preserve/shelve attribs are supplied def create_content_metadata(file_attributes_supplied) + reading_order = if content_structure == :simple_book_rtl + 'rtl' + else + 'ltr' + end ContentMetadataCreator.new(druid_id: druid.id, content_md_creation: content_md_creation, object_files: object_files, content_md_creation_style: content_md_creation_style, media_manifest: media_manifest, + reading_order: reading_order, add_file_attributes: file_attributes_supplied).create end diff --git a/app/models/batch_context.rb b/app/models/batch_context.rb index 47c80cfe8..8b91e15c7 100644 --- a/app/models/batch_context.rb +++ b/app/models/batch_context.rb @@ -23,7 +23,8 @@ class BatchContext < ApplicationRecord 'file' => 3, 'media' => 4, '3d' => 5, - 'document' => 6 + 'document' => 6, + 'simple_book_rtl' => 7 } enum content_metadata_creation: { diff --git a/app/views/batch_contexts/_new_bc_form.erb b/app/views/batch_contexts/_new_bc_form.erb index c3acb0000..8ac7f262f 100644 --- a/app/views/batch_contexts/_new_bc_form.erb +++ b/app/views/batch_contexts/_new_bc_form.erb @@ -14,8 +14,9 @@ <%= form.input :content_structure, collection: [ - ['Simple Image', 'simple_image'], - ['Simple Book', 'simple_book'], + ['Image', 'simple_image'], + ['Book (ltr)', 'simple_book'], + ['Book (rtl)', 'simple_book_rtl'], ['Document', 'document'], ['File', 'file'], ['Media', 'media'], diff --git a/spec/models/batch_context_spec.rb b/spec/models/batch_context_spec.rb index fe5865e30..b60a8e9e2 100644 --- a/spec/models/batch_context_spec.rb +++ b/spec/models/batch_context_spec.rb @@ -63,7 +63,8 @@ 'file' => 3, 'media' => 4, '3d' => 5, - 'document' => 6 + 'document' => 6, + 'simple_book_rtl' => 7 ) end From a7e742155da340aa7f2ffeae5f807a512ba426db Mon Sep 17 00:00:00 2001 From: Peter Mangiafico Date: Tue, 16 Mar 2021 18:00:20 -0700 Subject: [PATCH 5/5] add support for reading order --- app/lib/pre_assembly/digital_object.rb | 16 ++- spec/features/image_spec.rb | 2 +- spec/features/public_tif_spec.rb | 2 +- .../content_metadata_creator_spec.rb | 6 +- spec/lib/pre_assembly/digital_object_spec.rb | 110 +++++++++++++++++- 5 files changed, 125 insertions(+), 11 deletions(-) diff --git a/app/lib/pre_assembly/digital_object.rb b/app/lib/pre_assembly/digital_object.rb index 8dd2dcb71..15aa005d6 100644 --- a/app/lib/pre_assembly/digital_object.rb +++ b/app/lib/pre_assembly/digital_object.rb @@ -120,15 +120,19 @@ def generate_content_metadata(file_attributes_supplied) # Invoke the contentMetadata creation method used by the project # @param [Boolean] file_attributes_supplied - true if publish/preserve/shelve attribs are supplied def create_content_metadata(file_attributes_supplied) - reading_order = if content_structure == :simple_book_rtl - 'rtl' - else - 'ltr' - end + # Special case: if the content_structure set by the user is a rtl simple book, + # be sure we set this as the style, else use the default and style from the object + if content_structure == 'simple_book_rtl' + reading_order = 'rtl' + content_style = :simple_book + else + reading_order = 'ltr' + content_style = content_md_creation_style + end ContentMetadataCreator.new(druid_id: druid.id, content_md_creation: content_md_creation, object_files: object_files, - content_md_creation_style: content_md_creation_style, + content_md_creation_style: content_style, media_manifest: media_manifest, reading_order: reading_order, add_file_attributes: file_attributes_supplied).create diff --git a/spec/features/image_spec.rb b/spec/features/image_spec.rb index 082adf707..7e02a53d1 100644 --- a/spec/features/image_spec.rb +++ b/spec/features/image_spec.rb @@ -47,7 +47,7 @@ fill_in 'Project name', with: project_name select 'Pre Assembly Run', from: 'Job type' - select 'Simple Image', from: 'Content structure' + select 'Image', from: 'Content structure' fill_in 'Bundle dir', with: bundle_dir click_button 'Submit' diff --git a/spec/features/public_tif_spec.rb b/spec/features/public_tif_spec.rb index e3907adea..0080d1b9e 100644 --- a/spec/features/public_tif_spec.rb +++ b/spec/features/public_tif_spec.rb @@ -49,7 +49,7 @@ fill_in 'Project name', with: project_name select 'Pre Assembly Run', from: 'Job type' - select 'Simple Image', from: 'Content structure' + select 'Image', from: 'Content structure' fill_in 'Bundle dir', with: bundle_dir choose 'Preserve=Yes, Shelve=Yes, Publish=Yes' diff --git a/spec/lib/pre_assembly/content_metadata_creator_spec.rb b/spec/lib/pre_assembly/content_metadata_creator_spec.rb index 4f3e91666..e813a4d75 100644 --- a/spec/lib/pre_assembly/content_metadata_creator_spec.rb +++ b/spec/lib/pre_assembly/content_metadata_creator_spec.rb @@ -7,6 +7,7 @@ object_files: object_files, content_md_creation_style: content_md_creation_style, media_manifest: media_manifest, + reading_order: reading_order, add_file_attributes: add_file_attributes) end @@ -14,6 +15,7 @@ let(:content_md_creation) { 'bar' } let(:content_md_creation_style) { 'baz' } let(:add_file_attributes) { false } + let(:reading_order) { 'ltr' } let(:media_manifest) { 'quix' } describe '#content_object_files' do @@ -55,7 +57,7 @@ creator.create expect(Assembly::ContentMetadata).to have_received(:create_content_metadata) .with(druid: druid_id, objects: object_files, add_exif: false, - bundle: :bar, style: content_md_creation_style, add_file_attributes: false) + bundle: :bar, style: content_md_creation_style, reading_order: reading_order, add_file_attributes: false) end end @@ -66,7 +68,7 @@ creator.create expect(Assembly::ContentMetadata).to have_received(:create_content_metadata) .with(druid: druid_id, objects: object_files, add_exif: false, - bundle: :bar, style: content_md_creation_style, add_file_attributes: true) + bundle: :bar, style: content_md_creation_style, reading_order: reading_order, add_file_attributes: true) end end end diff --git a/spec/lib/pre_assembly/digital_object_spec.rb b/spec/lib/pre_assembly/digital_object_spec.rb index 2d1901e7b..63d9a4b44 100644 --- a/spec/lib/pre_assembly/digital_object_spec.rb +++ b/spec/lib/pre_assembly/digital_object_spec.rb @@ -110,7 +110,7 @@ def add_object_files(extension = 'tif', all_files_public: false) end describe '#create_content_metadata' do - describe 'default content metadata' do + describe 'default content metadata (image)' do let(:exp_xml) do noko_doc <<-XML @@ -227,6 +227,112 @@ def add_object_files(extension = 'tif', all_files_public: false) end end + describe 'book (ltr) content metadata' do + let(:exp_xml) do + noko_doc <<-XML + + + + + + 1111 + + + + + + 2222 + + + + XML + end + + let(:assembly_directory) { PreAssembly::AssemblyDirectory.new(druid_id: druid.id) } + + before do + allow(object).to receive(:druid).and_return(druid) + allow(object).to receive(:object_type).and_return('') + allow(bc).to receive(:content_structure).and_return('simple_book') + add_object_files('jp2') + allow(object).to receive(:assembly_directory).and_return(assembly_directory) + end + + around do |example| + RSpec::Mocks.with_temporary_scope do + Dir.mktmpdir(*tmp_dir_args) do |tmp_area| + allow(assembly_directory).to receive(:druid_tree_dir).and_return(tmp_area) + example.run + end + end + end + + it 'generates the expected xml text' do + expect(noko_doc(object.send(:create_content_metadata, false))).to be_equivalent_to exp_xml + end + + it 'is able to write the content_metadata XML to a file' do + assembly_directory.create_object_directories + file_name = object.send(:assembly_directory).content_metadata_file + expect(File.exist?(file_name)).to eq(false) + object.send(:generate_content_metadata, false) + expect(noko_doc(File.read(file_name))).to be_equivalent_to exp_xml + end + end + + describe 'book (rtl) content metadata' do + let(:exp_xml) do + noko_doc <<-XML + + + + + + 1111 + + + + + + 2222 + + + + XML + end + + let(:assembly_directory) { PreAssembly::AssemblyDirectory.new(druid_id: druid.id) } + + before do + allow(object).to receive(:druid).and_return(druid) + allow(object).to receive(:object_type).and_return('') + allow(bc).to receive(:content_structure).and_return('simple_book_rtl') + add_object_files('jp2') + allow(object).to receive(:assembly_directory).and_return(assembly_directory) + end + + around do |example| + RSpec::Mocks.with_temporary_scope do + Dir.mktmpdir(*tmp_dir_args) do |tmp_area| + allow(assembly_directory).to receive(:druid_tree_dir).and_return(tmp_area) + example.run + end + end + end + + it 'generates the expected xml text' do + expect(noko_doc(object.send(:create_content_metadata, false))).to be_equivalent_to exp_xml + end + + it 'is able to write the content_metadata XML to a file' do + assembly_directory.create_object_directories + file_name = object.send(:assembly_directory).content_metadata_file + expect(File.exist?(file_name)).to eq(false) + object.send(:generate_content_metadata, false) + expect(noko_doc(File.read(file_name))).to be_equivalent_to exp_xml + end + end + describe 'webarchive-seed content metadata' do let(:exp_xml) do noko_doc <<-XML @@ -283,6 +389,7 @@ def add_object_files(extension = 'tif', all_files_public: false) let(:exp_xml) do noko_doc <<-XML + @@ -323,6 +430,7 @@ def add_object_files(extension = 'tif', all_files_public: false) let(:exp_xml) do noko_doc <<-XML +