-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSVImporter file upload bug fix #1541
Changes from 3 commits
93cb695
e6a358a
9650e54
1cf7f5c
904a369
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
id,type,title,description,resource_type,contributor,contributor,date_created,file | ||
11111111-2465-1111-5468-000123456789,ETD,Hammock Tacos,,image,Tracy S Gertler,Cynthia V Stack,2015-03-29T22:12:12.100363+00:00,example3.tiff | ||
22222222-0971-2222-1353-000123456789,ETD,Freegan Intelligentsia,,text,Tracy S Gertler,Cynthia V Stack,2015-03-29T22:12:12.100363+00:00,sample.docx |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
module Importer | ||
# rubocop:disable Metrics/ClassLength | ||
class CSVParser | ||
include Enumerable | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,11 +25,16 @@ def run | |
object | ||
end | ||
|
||
## FOR CONSIDERATION: handle a row (i.e. Work) with more than one file: | ||
## currently the file_set is replaced on update | ||
def update | ||
raise "Object doesn't exist" unless object | ||
@attr = update_attributes | ||
run_callbacks(:save) do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are all the callbacks removed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't understand their use! Everything seems to work without. With them the method's Assignment Branch Condition size throws a rubocop error - would you prefer me to change the rubocop threshold for this too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, adjust the thresholds as needed. If the callbacks aren't used, then make a separate PR to "remove unused callbacks" It's easer to understand PRs if they constrain themselves to a single change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok thanks! I just restored the callbacks - that didn't cause a rubocop failure anymore. I think I was getting that on my initial solution before extracting logic in new methods. |
||
work_actor.update(environment(update_attributes)) | ||
work_actor.update(environment(@attr)) | ||
end | ||
destroy_existing_file_set if object.file_sets.present? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure you want to destroy an existing file set? Why not update it? If you replace one fileset with another, people who have cited an existing URI are going to have their references broken. What's the benefit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question; I am not sure that is the best way forward. This is how I envision the use of the csv importer:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that's universal though. What if I only want to update titles. Reuploading all the files is going to be very slow. And I don't want to have to do that just to update some metadata. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi! Apologies for a late reply. Good point. |
||
attach_file_to_work | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. attaching a file to a work is the responsibility of the work actor. Why are you adding it here in duplicate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is done in the actor stack here: https://github.com/samvera/hyrax/blob/f43e7048bf3961f48812809897b36d84b6577f68/app/actors/hyrax/actors/create_with_files_actor.rb#L10 now. So you may need to upload the file and then set the uploaded file id in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! Will work on this. |
||
log_updated(object) | ||
end | ||
|
||
|
@@ -62,13 +67,14 @@ def search_by_identifier | |
# https://github.com/projecthydra/active_fedora/issues/874 | ||
# 2+ years later, still open! | ||
def create | ||
attrs = create_attributes | ||
@attr = create_attributes | ||
@object = klass.new | ||
run_callbacks :save do | ||
run_callbacks :create do | ||
klass == Collection ? create_collection(attrs) : work_actor.create(environment(attrs)) | ||
klass == Collection ? create_collection(@attr) : work_actor.create(environment(@attr)) | ||
end | ||
end | ||
attach_file_to_work | ||
log_created(object) | ||
end | ||
|
||
|
@@ -107,14 +113,33 @@ def transform_attributes | |
.merge(file_attributes) | ||
end | ||
|
||
# NOTE: This approach is probably broken since the actor that handled `:files` attribute was removed: | ||
# https://github.com/samvera/hyrax/commit/3f1b58195d4381c51fde8b9149016c5b09f0c9b4 | ||
def file_attributes | ||
files_directory.present? && files.present? ? { files: file_paths } : {} | ||
end | ||
|
||
def file_paths | ||
files.map { |file_name| File.join(files_directory, file_name) } | ||
attributes[:file].map { |file_name| File.join(files_directory, file_name) } if attributes[:file] | ||
end | ||
|
||
def import_file(path) | ||
u = Hyrax::UploadedFile.new | ||
u.user_id = User.find_by_user_key(User.batch_user_key).id if User.find_by_user_key(User.batch_user_key) | ||
u.file = CarrierWave::SanitizedFile.new(path) | ||
u.save | ||
u | ||
end | ||
|
||
## If no file name is provided in the CSV file, `attach_file_to_work` is not performed | ||
## TO DO: handle invalid file in CSV | ||
## currently the importer stops if no file corresponding to a given file_name is found | ||
def attach_file_to_work | ||
imported_file = [import_file(file_paths.first)] if file_paths | ||
AttachFilesToWorkJob.new.perform(object, imported_file, @attr) if imported_file | ||
end | ||
|
||
def destroy_existing_file_set | ||
f = object.file_sets.first | ||
f.destroy if attributes[:file] != f.title | ||
end | ||
|
||
# Regardless of what the MODS Parser gives us, these are the properties we are prepared to accept. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
RSpec.shared_examples "csv_importer" do | ||
context "with a file" do | ||
let(:attributes) do | ||
{ | ||
id: "123", | ||
title: ["Gluten-free umami"], | ||
file: ["world.png"] | ||
} | ||
end | ||
let(:factory) { described_class.new(attributes, 'spec/fixtures/images') } | ||
|
||
before { factory.run } | ||
|
||
describe "#run" do | ||
it "uploads the content of the file" do | ||
expect(Hyrax::UploadedFile.last[:file]).to eq("world.png") | ||
end | ||
|
||
it "attaches the uploaded file to a work" do | ||
expect(Hyrax::UploadedFile.last[:file_set_uri]).to eq(work.find("123").file_sets.first.uri) | ||
end | ||
end | ||
|
||
# describe "when a work with the same id already exists" do | ||
# let(:new_attr) do | ||
# { | ||
# id: "123", | ||
# title: ["Squid tofu banjo"], | ||
# file: ["nypl-hydra-of-lerna.jpg"] | ||
# } | ||
# end | ||
# | ||
# # Ldp::NotFound Error for the update method in 2 tests below - how to stub?? | ||
# | ||
# it "updates metadata" do | ||
# new_factory = described_class.new(new_attr, 'spec/fixtures/images') | ||
# new_factory.run | ||
# expect(work.last.title).to eq(["Squid tofu banjo"]) | ||
# end | ||
# | ||
# # current behavior - may want to handle this differently? | ||
# it "replaces its file_set" do | ||
# new_factory = described_class.new(new_attr, 'spec/fixtures/images') | ||
# new_factory.run | ||
# expect(Hyrax::UploadedFile.last[:file]).to eq("nypl-hydra-of-lerna.jpg") | ||
# end | ||
# end | ||
end | ||
|
||
context "without a file" do | ||
## the csv_importer still creates a Work when no file is provided. | ||
## TO DO: handle invalid file in CSV; current behavior: | ||
## the importer stops if no file corresponding to a given file_name is found | ||
let(:attributes) { { id: "345", title: ["Artisan succulents"] } } | ||
let(:factory) { described_class.new(attributes) } | ||
|
||
before { factory.run } | ||
|
||
it "creates a Work with supplied metadata" do | ||
expect(work.find("345").title).to eq(["Artisan succulents"]) | ||
end | ||
|
||
it "updates a Work with supplied metadata" do | ||
new_attr = { id: "345", title: ["Retro humblebrag"] } | ||
new_factory = described_class.new(new_attr) | ||
new_factory.run | ||
expect(work.find("345").title).to eq(["Retro humblebrag"]) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have you chosen to use an instance variable here? Why not a local?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is called in
attach_file_to_work
(line 137).