diff --git a/app/controllers/standard_ingests_controller.rb b/app/controllers/standard_ingests_controller.rb index 8ec144e6..2b6898bf 100644 --- a/app/controllers/standard_ingests_controller.rb +++ b/app/controllers/standard_ingests_controller.rb @@ -9,10 +9,11 @@ def create if @standard_ingest.valid? Resque.enqueue(StandardIngestJob, 'admin_set' => @standard_ingest.admin_set, + 'basepath' => @standard_ingest.basepath, 'batch_user' => @standard_ingest.user.user_key, 'collection_id' => @standard_ingest.collection_id, 'config_file' => @standard_ingest.config_file, - 'folder_path' => @standard_ingest.folder_path) + 'subpath' => @standard_ingest.subpath) render "queued" else render "new" @@ -22,7 +23,7 @@ def create private def create_params - params.require(:standard_ingest).permit(:folder_path, :admin_set, :collection_id, :config_file) + params.require(:standard_ingest).permit(:basepath, :admin_set, :collection_id, :config_file, :subpath) end def authorize_create diff --git a/app/helpers/standard_ingest_helper.rb b/app/helpers/standard_ingest_helper.rb index 5393f64d..75892aad 100644 --- a/app/helpers/standard_ingest_helper.rb +++ b/app/helpers/standard_ingest_helper.rb @@ -1,12 +1,11 @@ module StandardIngestHelper - def standard_ingest_folder_options_for_select - options_for_select(standard_ingest_folders.collect { |f| [ f, File.join(DulHydra.standard_ingest_base_path, f) ] }, @standard_ingest.folder_path) - end + # For convenience, for now, we assume that standard ingest will always use the default configuration file + # (StandardIngest::DEFAULT_CONFIG_FILE), though StandardIngest is coded to permit passing in a different + # config file. - def standard_ingest_folders - base = DulHydra.standard_ingest_base_path - Dir.entries(base).select {|e| File.directory? File.join(base, e) }.reject{ |e| e.starts_with?('.') } + def permitted_standard_ingest_bases + StandardIngest.default_basepaths end end diff --git a/app/jobs/standard_ingest_job.rb b/app/jobs/standard_ingest_job.rb index c266c3f8..67d97127 100644 --- a/app/jobs/standard_ingest_job.rb +++ b/app/jobs/standard_ingest_job.rb @@ -11,7 +11,8 @@ def self.perform(args) model_stats = results.inspection_results.content_model_stats if results.inspection_results ActiveSupport::Notifications.instrument(StandardIngest::FINISHED, user_key: args['batch_user'], - folder_path: args['folder_path'], + basepath: args['basepath'], + subpath: args['subpath'], collection_id: args['collection_id'], file_count: file_count, model_stats: model_stats, diff --git a/app/models/standard_ingest.rb b/app/models/standard_ingest.rb index 32be6fd9..cdcb3ff8 100644 --- a/app/models/standard_ingest.rb +++ b/app/models/standard_ingest.rb @@ -1,7 +1,7 @@ class StandardIngest include ActiveModel::Model - attr_reader :admin_set, :collection_id, :config_file, :configuration, :folder_path + attr_reader :admin_set, :basepath, :collection_id, :config_file, :configuration, :subpath attr_accessor :results, :user # Lifecycle events @@ -14,7 +14,7 @@ class StandardIngest DEFAULT_CONFIG_FILE = Rails.root.join('config', 'standard_ingest.yml') METADATA_FILE = 'metadata.txt' - validates_presence_of(:folder_path, :user) + validates_presence_of(:basepath, :subpath, :user) with_options if: 'folder_path.present?' do |folder| folder.validate :folder_directory_must_exist folder.validate :data_directory_must_exist @@ -26,12 +26,21 @@ class StandardIngest validate :collection_must_exist, if: 'collection_id.present?' validates_presence_of(:admin_set, unless: 'collection_id.present?') + def self.default_config + YAML.load(File.read(DEFAULT_CONFIG_FILE)).deep_symbolize_keys + end + + def self.default_basepaths + default_config[:basepaths] + end + def initialize(args) @admin_set = args['admin_set'] + @basepath = args['basepath'] @collection_id = args['collection_id'] @config_file = args['config_file'] || DEFAULT_CONFIG_FILE.to_s @configuration = load_configuration - @folder_path = args['folder_path'] + @subpath = args['subpath'] @user = User.find_by_user_key(args['batch_user']) @results = Results.new end @@ -134,6 +143,10 @@ def metadata_provider @metadata_provider ||= IngestMetadata.new(File.join(data_path, METADATA_FILE), configuration[:metadata]) end + def folder_path + @folder_path ||= File.join(basepath, subpath) + end + def inspection_results @inspection_results ||= InspectStandardIngest.new(folder_path, configuration[:scanner]).call end diff --git a/app/views/standard_ingests/_folder_path.html.erb b/app/views/standard_ingests/_folder_path.html.erb new file mode 100644 index 00000000..eb8da3ff --- /dev/null +++ b/app/views/standard_ingests/_folder_path.html.erb @@ -0,0 +1,13 @@ +
+ <%= f.label :basepath %> + <% if permitted_standard_ingest_bases.size == 1 %> + <%= f.hidden_field :basepath, value: permitted_standard_ingest_bases.first %> + <%= permitted_standard_ingest_bases.first %> + <% else %> + <%= f.select :basepath, options_for_select(permitted_standard_ingest_bases), { prompt: true }, { class: 'form-control' } %> + <% end %> +
+
+ <%= f.label :subpath %> + <%= f.text_field :subpath, class: 'form-control' %> +
diff --git a/app/views/standard_ingests/new.html.erb b/app/views/standard_ingests/new.html.erb index c12f2625..413b9cee 100644 --- a/app/views/standard_ingests/new.html.erb +++ b/app/views/standard_ingests/new.html.erb @@ -26,14 +26,7 @@ <%= f.hidden_field :collection_id %> <%= @standard_ingest.collection_id.present? ? object_display_title(@standard_ingest.collection_id) : '' %> -
- <%= f.label :base_path, "Base Path" %> - <%= DulHydra.standard_ingest_base_path %> -
-
- <%= f.label :folder_path, "Folder" %> - <%= f.select :folder_path, standard_ingest_folder_options_for_select, { include_blank: "Select Standard Ingest Folder" }, { class: "form-control" } %> -
+ <%= render partial: 'folder_path', locals: { f: f } %>
<% unless @standard_ingest.collection_id.present? %> <%= f.label :admin_set, "Admin Set" %> diff --git a/config/initializers/dul_hydra.rb b/config/initializers/dul_hydra.rb index ec430bbe..92f47706 100644 --- a/config/initializers/dul_hydra.rb +++ b/config/initializers/dul_hydra.rb @@ -12,7 +12,6 @@ } config.metadata_file_creators_group = ENV['METADATA_FILE_CREATORS_GROUP'] config.create_menu_models = [ "Collection", "MetadataFile", "NestedFolderIngest", "StandardIngest" ] - config.standard_ingest_base_path = ENV['STANDARD_INGEST_BASE_PATH'] config.preview_banner_msg = ENV['PREVIEW_BANNER_MSG'] config.collection_report_fields = [:pid, :local_id, :content_size] end diff --git a/config/standard_ingest.yml b/config/standard_ingest.yml.sample similarity index 79% rename from config/standard_ingest.yml rename to config/standard_ingest.yml.sample index c29645a6..d2673b03 100644 --- a/config/standard_ingest.yml +++ b/config/standard_ingest.yml.sample @@ -1,3 +1,6 @@ +:basepaths: + - /path/to/base/folder1/ + - /path/to/base/folder2/ :scanner: :exclude: - .DS_Store diff --git a/lib/dul_hydra/configurable.rb b/lib/dul_hydra/configurable.rb index 7f18a8f4..ee2d79b0 100644 --- a/lib/dul_hydra/configurable.rb +++ b/lib/dul_hydra/configurable.rb @@ -81,9 +81,6 @@ module Configurable [ :nested_path ] end - # Base path for Standard Ingest folders - mattr_accessor :standard_ingest_base_path - # Entries per page on batches index display mattr_accessor :batches_per_page do ENV["BATCHES_PER_PAGE"] || 10 diff --git a/lib/dul_hydra/version.rb b/lib/dul_hydra/version.rb index 2e996918..92422ec6 100644 --- a/lib/dul_hydra/version.rb +++ b/lib/dul_hydra/version.rb @@ -1,3 +1,3 @@ module DulHydra - VERSION = "4.11.4" + VERSION = "4.12.0" end diff --git a/spec/controllers/standard_ingests_controller_spec.rb b/spec/controllers/standard_ingests_controller_spec.rb index 1e7af31b..2970c06d 100644 --- a/spec/controllers/standard_ingests_controller_spec.rb +++ b/spec/controllers/standard_ingests_controller_spec.rb @@ -5,12 +5,15 @@ describe "#create" do let(:user) { FactoryGirl.create(:user) } let(:admin_set) { "foo" } - let(:folder_path) { "/foo/bar/baz" } + let(:basepath) { "/foo/bar/" } + let(:subpath) { "baz" } + let(:folder_path) { File.join(basepath, subpath) } let(:checksum_path) { File.join(folder_path, StandardIngest::CHECKSUM_FILE).to_s } let(:data_path) { File.join(folder_path, StandardIngest::DATA_DIRECTORY).to_s } let(:metadata_path) { File.join(data_path, StandardIngest::METADATA_FILE).to_s } - let(:job_params) { {"admin_set" => admin_set, "batch_user" => user.user_key, "collection_id" => "", - "config_file" => StandardIngest::DEFAULT_CONFIG_FILE.to_s, "folder_path" => folder_path } } + let(:job_params) { {"admin_set" => admin_set, "basepath" => basepath, "batch_user" => user.user_key, + "collection_id" => "", "config_file" => StandardIngest::DEFAULT_CONFIG_FILE.to_s, + "subpath" => subpath} } before do sign_in user @@ -20,6 +23,7 @@ allow(File).to receive(:exist?).and_call_original allow(File).to receive(:exist?).with(checksum_path) { true } allow(File).to receive(:exist?).with(metadata_path) { true } + allow_any_instance_of(StandardIngest).to receive(:load_configuration) { {} } allow_any_instance_of(StandardIngest).to receive(:validate_metadata_file) { nil } end @@ -30,7 +34,8 @@ } it "enqueues the job and renders the 'queued' view" do expect(Resque).to receive(:enqueue).with(StandardIngestJob, job_params) - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "", "admin_set" => admin_set } + post :create, standard_ingest: { "basepath" => basepath, "collection_id" => "", "admin_set" => admin_set, + "subpath" => subpath } expect(response).to render_template(:queued) end describe "and the collection is specified" do @@ -39,7 +44,7 @@ controller.current_ability.can(:add_children, "test:1") } it "is successful" do - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "test:1" } + post :create, standard_ingest: { "basepath" => basepath, "collection_id" => "test:1", "subpath" => subpath } expect(response.response_code).to eq(200) end end @@ -49,7 +54,7 @@ controller.current_ability.cannot(:add_children, "test:1") } it "is forbidden" do - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "test:1" } + post :create, standard_ingest: {"basepath" => basepath, "collection_id" => "test:1", "subpath" => subpath } expect(response.response_code).to eq(403) end end @@ -61,7 +66,7 @@ } describe "and the collection is not specified" do it "is forbidden" do - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "" } + post :create, standard_ingest: {"basepath" => basepath, "collection_id" => "", "subpath" => subpath } expect(response.response_code).to eq(403) end end @@ -71,7 +76,7 @@ controller.current_ability.can(:add_children, "test:1") } it "is successful" do - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "test:1" } + post :create, standard_ingest: {"basepath" => basepath, "collection_id" => "test:1", "subpath" => subpath } expect(response.response_code).to eq(200) end end @@ -81,7 +86,7 @@ controller.current_ability.cannot(:add_children, "test:1") } it "is forbidden" do - post :create, standard_ingest: {"folder_path" => folder_path, "collection_id" => "test:1" } + post :create, standard_ingest: {"basepath" => basepath, "collection_id" => "test:1", "subpath" => subpath } expect(response.response_code).to eq(403) end end diff --git a/spec/jobs/standard_ingest_job_spec.rb b/spec/jobs/standard_ingest_job_spec.rb index 948d19f9..71d81373 100644 --- a/spec/jobs/standard_ingest_job_spec.rb +++ b/spec/jobs/standard_ingest_job_spec.rb @@ -3,15 +3,17 @@ RSpec.describe StandardIngestJob, type: :job do let(:user_key) { 'joe@test.edu' } - let(:folder_path) { '/foo/bar/baz' } + let(:basepath) { "/foo/bar/" } + let(:subpath) { "baz" } let(:collection_pid) { 'test:1' } let(:batch) { double('Ddr::Batch::Batch', id: 5) } let(:item_count) { 7 } let(:component_count) { 10 } let(:target_count) { 2 } - let(:job_params) { { "batch_user" => user_key, "folder_path" => folder_path } } + let(:job_params) { { "batch_user" => user_key, "basepath" => basepath, "subpath" => subpath } } before do + allow_any_instance_of(StandardIngest).to receive(:load_configuration) { {} } allow_any_instance_of(InspectStandardIngest).to receive(:call) { inspection_results } end @@ -34,7 +36,8 @@ it "should publish the appropriate notification" do expect(ActiveSupport::Notifications).to receive(:instrument).with(StandardIngest::FINISHED, user_key: user_key, - folder_path: folder_path, + basepath: basepath, + subpath: subpath, collection_id: collection_pid, file_count: file_count, model_stats: model_stats, @@ -48,7 +51,8 @@ it "should publish the appropriate notification" do expect(ActiveSupport::Notifications).to receive(:instrument).with(StandardIngest::FINISHED, user_key: user_key, - folder_path: folder_path, + basepath: basepath, + subpath: subpath, collection_id: nil, file_count: file_count, model_stats: model_stats, @@ -72,7 +76,8 @@ it "should publish the appropriate notification" do expect(ActiveSupport::Notifications).to receive(:instrument).with(StandardIngest::FINISHED, user_key: user_key, - folder_path: folder_path, + basepath: basepath, + subpath: subpath, collection_id: collection_pid, file_count: nil, model_stats: nil, @@ -85,7 +90,8 @@ it "should publish the appropriate notification" do expect(ActiveSupport::Notifications).to receive(:instrument).with(StandardIngest::FINISHED, user_key: user_key, - folder_path: folder_path, + basepath: basepath, + subpath: subpath, collection_id: nil, file_count: nil, model_stats: nil, diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 7cc9991e..f759b7ff 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -68,8 +68,11 @@ end describe "StandardIngest abilities" do - let(:resource) { StandardIngest.new({"folder_path" => '/foo', "batch_user" => auth_context.user.user_key }) } - before { auth_context.user.save! } + let(:resource) { StandardIngest.new({"basepath" => '/foo', "batch_user" => auth_context.user.user_key, subpath: 'bar' }) } + before do + auth_context.user.save! + allow_any_instance_of(StandardIngest).to receive(:load_configuration) { {} } + end describe "create" do before { allow_any_instance_of(described_class).to receive(:can?).and_call_original } describe "when the user can create collections" do diff --git a/spec/models/standard_ingest_spec.rb b/spec/models/standard_ingest_spec.rb index 270b7105..a1594f58 100644 --- a/spec/models/standard_ingest_spec.rb +++ b/spec/models/standard_ingest_spec.rb @@ -4,20 +4,26 @@ let(:user) { FactoryGirl.create(:user) } let(:admin_set) { 'foo' } - let(:folder_path) { '/test/directory' } + let(:basepath) { '/test/' } + let(:subpath) { 'directory/' } let(:fs_node_paths) { filesystem.each_leaf.map { |leaf| Filesystem.node_locator(leaf) } } let(:ingest_metadata) { double(IngestMetadata) } subject { StandardIngest.new(standard_ingest_args) } + before do + allow_any_instance_of(StandardIngest).to receive(:load_configuration) { {} } + end + describe 'validation' do let(:filesystem) { Filesystem.new } let(:standard_ingest_args) { { 'batch_user' => user.user_key, - 'folder_path' => folder_path, + 'basepath' => basepath, + 'subpath' => subpath, 'admin_set' => admin_set } } before do filesystem.tree = sample_filesystem_without_dot_files - allow(Dir).to receive(:exist?).with(folder_path) { true } + allow(Dir).to receive(:exist?).with(subject.folder_path) { true } allow(Dir).to receive(:exist?).with(subject.data_path) { true } allow(File).to receive(:exist?).with(subject.checksum_path) { true } allow(subject).to receive(:metadata_provider) { ingest_metadata } @@ -53,7 +59,8 @@ describe 'item adding ingest' do let(:collection_repo_id) { 'test:1' } let(:standard_ingest_args) { { 'batch_user' => user.user_key, - 'folder_path' => folder_path, + 'basepath' => basepath, + 'subpath' => subpath, 'collection_id' => collection_repo_id } } before { allow(Collection).to receive(:exists?).with(collection_repo_id) { true } } it "should be valid" do @@ -63,7 +70,7 @@ end end describe 'invalid standard ingest folder' do - let(:error_message) { "#{File.join(folder_path, 'data')} is not a valid standard ingest directory" } + let(:error_message) { "#{File.join(subject.folder_path, 'data')} is not a valid standard ingest directory" } before do allow(File).to receive(:exist?).with(subject.metadata_path) { false } allow(subject).to receive(:inspection_results).and_raise(DulHydra::BatchError, error_message) @@ -81,10 +88,13 @@ let(:ingest_metadata) { double(IngestMetadata) } let(:standard_ingest_checksum) { double(StandardIngestChecksum) } let(:filesystem) { filesystem_standard_ingest } - let(:config) { {:scanner=>{:exclude=>[".DS_Store", "Thumbs.db", "metadata.txt"], :targets=>"dpc_targets", - :intermediate_files=>"intermediate_files"}, - :metadata=>{:csv=>{:encoding=>"UTF-8", :headers=>true, :col_sep=>"\t"}, - :parse=>{:repeating_fields_separator=>";"}}} } + let(:config) do + { basepaths: [ "/base/path1", "/base/path2" ], + scanner: { exclude: [ ".DS_Store", "Thumbs.db", "metadata.txt" ], targets: "dpc_targets", + intermediate_files: "intermediate_files" }, + metadata: { csv:{ encoding: "UTF-8", headers: true, col_sep: "\t" }, + parse: { repeating_fields_separator: ";" } } } + end let(:admin_set) { 'dvs' } before do @@ -97,7 +107,8 @@ describe "collection creating standard ingest" do let(:standard_ingest_args) { { 'admin_set' => admin_set, - 'folder_path' => folder_path, + 'basepath' => basepath, + 'subpath' => subpath, 'batch_user' => user.user_key } } let(:batch_builder_args) { { user: user, filesystem: filesystem, @@ -122,7 +133,8 @@ let(:collection_repo_id) { 'test:1' } let(:standard_ingest_args) { { 'admin_set' => admin_set, 'collection_id' => collection_repo_id, - 'folder_path' => folder_path, + 'basepath' => basepath, + 'subpath' => subpath, 'batch_user' => user.user_key } } let(:batch_builder_args) { { user: user, filesystem: filesystem,