bulkrax 8.2.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/app/assets/javascripts/bulkrax/bulkrax.js +9 -7
- data/app/assets/javascripts/bulkrax/importers.js.erb +134 -99
- data/app/controllers/bulkrax/importers_controller.rb +16 -5
- data/app/factories/bulkrax/object_factory.rb +1 -1
- data/app/jobs/bulkrax/delete_file_set_job.rb +2 -2
- data/app/views/bulkrax/importers/_bagit_fields.html.erb +10 -3
- data/app/views/bulkrax/importers/_csv_fields.html.erb +13 -9
- data/app/views/bulkrax/importers/_file_uploader.html.erb +37 -0
- data/app/views/bulkrax/importers/_xml_fields.html.erb +10 -4
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +40 -3
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a409c17f35bc09ef0a8c63d06a064d01fbff68a0e4c0b91c9bfaed45d6e8169
|
4
|
+
data.tar.gz: 7fad94124795ff133b83d05030c550f2a52f808ac017fdd3a436c17ce039cd01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65280762e81baa620e73d965d5e7c58ec4ccb40d303c00cf634e7f9b3b3850e541cc9964900ce7b9aec9f6be1a7fe81dd9781db5b74209a9f8661f5f8a96f595
|
7
|
+
data.tar.gz: e91e65f6de8edc1640dd9b6e75c246fff4fd0812a3f87f6b4600dd9c95afc095be6076c9a80c5bca50ccc73c3831fc0a30c1160b46f18c483a6d68277bf762a8
|
data/README.md
CHANGED
@@ -24,6 +24,14 @@ $ rails db:migrate
|
|
24
24
|
|
25
25
|
If using Sidekiq, set up queues for `import` and `export`.
|
26
26
|
|
27
|
+
### Bundle errors on ARM
|
28
|
+
|
29
|
+
If posix-spawn is failing to bundle on an ARM based processor, try the following
|
30
|
+
|
31
|
+
`bundle config build.posix-spawn --with-cflags="-Wno-incompatible-function-pointer-types"`
|
32
|
+
|
33
|
+
Then rebundle. See https://github.com/rtomayko/posix-spawn/issues/92
|
34
|
+
|
27
35
|
### Manual Installation
|
28
36
|
|
29
37
|
Add this line to your application's Gemfile:
|
@@ -5,18 +5,20 @@ $(document).on('turbolinks:load ready', function() {
|
|
5
5
|
$('button#err_toggle').click(function() {
|
6
6
|
$('#error_trace').toggle();
|
7
7
|
});
|
8
|
+
|
8
9
|
$('button#fm_toggle').click(function() {
|
9
10
|
$('#field_mapping').toggle();
|
10
11
|
});
|
12
|
+
|
11
13
|
$('#bulkraxItemModal').on('show.bs.modal', function (event) {
|
12
|
-
var button = $(event.relatedTarget) // Button that triggered the modal
|
13
|
-
var recipient = button.data('entry-id') // Extract info from data-* attributes
|
14
|
+
var button = $(event.relatedTarget); // Button that triggered the modal
|
15
|
+
var recipient = button.data('entry-id'); // Extract info from data-* attributes
|
14
16
|
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
|
15
17
|
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
|
16
|
-
var modal = $(this)
|
18
|
+
var modal = $(this);
|
17
19
|
modal.find('a').each(function() {
|
18
|
-
this.href = this.href.replace(/\d+\?/, recipient + '?')
|
19
|
-
})
|
20
|
-
return true
|
21
|
-
})
|
20
|
+
this.href = this.href.replace(/\d+\?/, recipient + '?');
|
21
|
+
});
|
22
|
+
return true;
|
23
|
+
});
|
22
24
|
});
|
@@ -2,205 +2,240 @@
|
|
2
2
|
// All this logic will automatically be available in application.js.
|
3
3
|
|
4
4
|
function prepBulkrax(event) {
|
5
|
-
var refresh_button = $('.refresh-set-source')
|
6
|
-
var base_url = $('#importer_parser_fields_base_url')
|
7
|
-
var initial_base_url = base_url.val()
|
8
|
-
var file_path_value = $('#importer_parser_fields_import_file_path').val()
|
9
|
-
handleFileToggle(file_path_value)
|
5
|
+
var refresh_button = $('.refresh-set-source');
|
6
|
+
var base_url = $('#importer_parser_fields_base_url');
|
7
|
+
var initial_base_url = base_url.val();
|
8
|
+
var file_path_value = $('#importer_parser_fields_import_file_path').val();
|
9
|
+
handleFileToggle(file_path_value);
|
10
|
+
|
11
|
+
// Initialize the uploader only if hyraxUploader is defined
|
12
|
+
if (typeof $.fn.hyraxUploader === 'function') {
|
13
|
+
// Initialize the uploader
|
14
|
+
$('.fileupload-bulkrax').hyraxUploader({ maxNumberOfFiles: 1 });
|
15
|
+
|
16
|
+
// Function to toggle 'required' attribute based on uploaded files
|
17
|
+
function toggleRequiredAttribute() {
|
18
|
+
const fileInput = $('#addfiles');
|
19
|
+
const uploadedFilesTable = $('.fileupload-bulkrax tbody.files');
|
20
|
+
|
21
|
+
if (uploadedFilesTable.find('tr.template-download').length > 0) {
|
22
|
+
// Remove 'required' if there are uploaded files
|
23
|
+
fileInput.removeAttr('required');
|
24
|
+
} else {
|
25
|
+
// Add 'required' if no uploaded files
|
26
|
+
fileInput.attr('required', 'required');
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
// Check the required attribute when a file is added or removed
|
31
|
+
$('#addfiles').on('change', function() {
|
32
|
+
toggleRequiredAttribute();
|
33
|
+
});
|
34
|
+
|
35
|
+
// Also check when an upload completes or is canceled
|
36
|
+
$('.fileupload-bulkrax').on('fileuploadcompleted fileuploaddestroyed', function() {
|
37
|
+
toggleRequiredAttribute();
|
38
|
+
});
|
39
|
+
|
40
|
+
// Ensure 'required' is only added if there are no files on form reset
|
41
|
+
$('#file-upload-cancel-btn').on('click', function() {
|
42
|
+
$('#addfiles').attr('required', 'required');
|
43
|
+
$('#addfiles').val(''); // Clear file input to ensure 'required' behavior resets
|
44
|
+
});
|
45
|
+
|
46
|
+
// Initial check in case files are already uploaded
|
47
|
+
toggleRequiredAttribute();
|
48
|
+
}
|
10
49
|
|
11
50
|
// handle refreshing/loading of external sets via button click
|
12
51
|
$('body').on('click', '.refresh-set-source', function(e) {
|
13
|
-
e.preventDefault()
|
52
|
+
e.preventDefault();
|
14
53
|
|
15
|
-
external_set_select = $("#importer_parser_fields_set")
|
16
|
-
handleSourceLoad(refresh_button, base_url, external_set_select)
|
17
|
-
})
|
54
|
+
external_set_select = $("#importer_parser_fields_set");
|
55
|
+
handleSourceLoad(refresh_button, base_url, external_set_select);
|
56
|
+
});
|
18
57
|
|
19
58
|
// handle refreshing/loading of external sets via blur event for the base_url field
|
20
59
|
$('body').on('blur', '#importer_parser_fields_base_url', function(e) {
|
21
|
-
e.preventDefault()
|
60
|
+
e.preventDefault();
|
22
61
|
|
23
62
|
// retrieve the latest base_url
|
24
|
-
base_url = $('#importer_parser_fields_base_url')
|
63
|
+
base_url = $('#importer_parser_fields_base_url');
|
25
64
|
|
26
65
|
// ensure we don't make another query if the value is the same -- this can be forced by clicking the refresh button
|
27
66
|
if (initial_base_url != base_url.val()) {
|
28
|
-
external_set_select = $("#importer_parser_fields_set")
|
29
|
-
handleSourceLoad(refresh_button, base_url, external_set_select)
|
30
|
-
initial_base_url = base_url.val()
|
67
|
+
external_set_select = $("#importer_parser_fields_set");
|
68
|
+
handleSourceLoad(refresh_button, base_url, external_set_select);
|
69
|
+
initial_base_url = base_url.val();
|
31
70
|
}
|
32
|
-
})
|
71
|
+
});
|
33
72
|
|
34
73
|
// hide and show correct parser fields depending on klass setting
|
35
74
|
$('body').on('change', '#importer_parser_klass', function(e) {
|
36
|
-
handleParserKlass()
|
37
|
-
})
|
38
|
-
handleParserKlass()
|
75
|
+
handleParserKlass();
|
76
|
+
});
|
77
|
+
handleParserKlass();
|
39
78
|
|
40
79
|
// observer for cloud files being added
|
41
80
|
var form = document.getElementById('new_importer');
|
42
81
|
if (form == null) {
|
43
|
-
|
82
|
+
form = document.getElementsByClassName('edit_importer')[0];
|
44
83
|
}
|
84
|
+
|
45
85
|
// only setup the observer on the new and edit importer pages
|
46
86
|
if (form != null) {
|
47
87
|
var config = { childList: true, attributes: true };
|
48
88
|
var callback = function(mutationsList) {
|
49
89
|
for(var mutation of mutationsList) {
|
50
|
-
|
51
90
|
if (mutation.type == 'childList') {
|
52
91
|
browseButton = document.getElementById('browse');
|
53
|
-
var exp = /selected_files\[[0-9]*\]\[url\]
|
92
|
+
var exp = /selected_files\[[0-9]*\]\[url\]/;
|
54
93
|
for (var node of mutation.addedNodes) {
|
55
94
|
if (node.attributes != undefined) {
|
56
|
-
var name = node.attributes.name.value
|
95
|
+
var name = node.attributes.name.value;
|
57
96
|
if (exp.test(name)) {
|
58
97
|
browseButton.innerHTML = 'Cloud Files Added';
|
59
98
|
browseButton.style.backgroundColor = 'green';
|
60
|
-
browseButton.after(document.createElement("br"), node.value.toString())
|
99
|
+
browseButton.after(document.createElement("br"), node.value.toString());
|
61
100
|
}
|
62
101
|
}
|
63
102
|
}
|
64
103
|
}
|
65
104
|
}
|
66
105
|
};
|
67
|
-
var observer = new MutationObserver
|
68
|
-
observer.observe
|
106
|
+
var observer = new MutationObserver(callback);
|
107
|
+
observer.observe(form, config);
|
69
108
|
}
|
70
109
|
}
|
71
110
|
|
72
111
|
function handleFileToggle(file_path) {
|
73
112
|
if (file_path === undefined || file_path.length === 0) {
|
74
|
-
$('#file_path').hide()
|
75
|
-
$('#file_upload').hide()
|
76
|
-
$('#cloud').hide()
|
77
|
-
$('#existing_options').hide()
|
78
|
-
$('#file_path input').attr('required', null)
|
79
|
-
$('#file_upload input').attr('required', null)
|
113
|
+
$('#file_path').hide();
|
114
|
+
$('#file_upload').hide();
|
115
|
+
$('#cloud').hide();
|
116
|
+
$('#existing_options').hide();
|
117
|
+
$('#file_path input').attr('required', null);
|
118
|
+
$('#file_upload input').attr('required', null);
|
80
119
|
} else {
|
81
|
-
$('#file_path').show()
|
82
|
-
$('#file_upload').hide()
|
83
|
-
$('#cloud').hide()
|
84
|
-
$('#existing_options').hide()
|
85
|
-
$('#file_path input').attr('required', 'required')
|
86
|
-
$('#file_upload input').attr('required', null)
|
87
|
-
$('#importer_parser_fields_file_style_specify_a_path_on_the_server').attr('checked', true)
|
120
|
+
$('#file_path').show();
|
121
|
+
$('#file_upload').hide();
|
122
|
+
$('#cloud').hide();
|
123
|
+
$('#existing_options').hide();
|
124
|
+
$('#file_path input').attr('required', 'required');
|
125
|
+
$('#file_upload input').attr('required', null);
|
126
|
+
$('#importer_parser_fields_file_style_specify_a_path_on_the_server').attr('checked', true);
|
88
127
|
}
|
89
128
|
|
90
129
|
$('#importer_parser_fields_file_style_upload_a_file').click(function(e){
|
91
|
-
$('#file_path').hide()
|
92
|
-
$('#file_upload').show()
|
93
|
-
$('#cloud').hide()
|
94
|
-
$('#existing_options').hide()
|
95
|
-
$('#file_path input').attr('required', null)
|
96
|
-
$('#file_upload input').attr('required', 'required')
|
97
|
-
})
|
130
|
+
$('#file_path').hide();
|
131
|
+
$('#file_upload').show();
|
132
|
+
$('#cloud').hide();
|
133
|
+
$('#existing_options').hide();
|
134
|
+
$('#file_path input').attr('required', null);
|
135
|
+
$('#file_upload input').attr('required', 'required');
|
136
|
+
});
|
98
137
|
$('#importer_parser_fields_file_style_specify_a_path_on_the_server').click(function(e){
|
99
|
-
$('#file_path').show()
|
100
|
-
$('#file_upload').hide()
|
101
|
-
$('#cloud').hide()
|
102
|
-
$('#existing_options').hide()
|
103
|
-
$('#file_path input').attr('required', 'required')
|
104
|
-
$('#file_upload input').attr('required', null)
|
105
|
-
})
|
138
|
+
$('#file_path').show();
|
139
|
+
$('#file_upload').hide();
|
140
|
+
$('#cloud').hide();
|
141
|
+
$('#existing_options').hide();
|
142
|
+
$('#file_path input').attr('required', 'required');
|
143
|
+
$('#file_upload input').attr('required', null);
|
144
|
+
});
|
106
145
|
$('#importer_parser_fields_file_style_add_cloud_file').click(function(e){
|
107
|
-
$('#file_path').hide()
|
108
|
-
$('#file_upload').hide()
|
109
|
-
$('#cloud').show()
|
110
|
-
$('#existing_options').hide()
|
111
|
-
$('#file_path input').attr('required', null)
|
112
|
-
$('#file_upload input').attr('required', null)
|
113
|
-
})
|
146
|
+
$('#file_path').hide();
|
147
|
+
$('#file_upload').hide();
|
148
|
+
$('#cloud').show();
|
149
|
+
$('#existing_options').hide();
|
150
|
+
$('#file_path input').attr('required', null);
|
151
|
+
$('#file_upload input').attr('required', null);
|
152
|
+
});
|
114
153
|
$('#importer_parser_fields_file_style_existing_entries').click(function(e){
|
115
|
-
$('#file_path').hide()
|
116
|
-
$('#file_upload').hide()
|
117
|
-
$('#cloud').hide()
|
118
|
-
$('#existing_options').show()
|
119
|
-
$('#file_path input').attr('required', null)
|
120
|
-
$('#file_upload input').attr('required', null)
|
121
|
-
})
|
122
|
-
|
154
|
+
$('#file_path').hide();
|
155
|
+
$('#file_upload').hide();
|
156
|
+
$('#cloud').hide();
|
157
|
+
$('#existing_options').show();
|
158
|
+
$('#file_path input').attr('required', null);
|
159
|
+
$('#file_upload input').attr('required', null);
|
160
|
+
});
|
123
161
|
}
|
124
162
|
|
125
163
|
function handleParserKlass() {
|
126
164
|
<% Bulkrax.parsers.map{ |p| p[:partial]}.uniq.each do |partial| %>
|
127
165
|
if($('.<%= partial %>').length > 0) {
|
128
|
-
window.<%= partial %> = $('.<%= partial %>').detach()
|
166
|
+
window.<%= partial %> = $('.<%= partial %>').detach();
|
129
167
|
}
|
130
168
|
<% end %>
|
131
169
|
|
132
|
-
var parser_klass = $("#importer_parser_klass option:selected")
|
170
|
+
var parser_klass = $("#importer_parser_klass option:selected");
|
133
171
|
if(parser_klass.length > 0 && parser_klass.data('partial') && parser_klass.data('partial').length > 0) {
|
134
|
-
$('.parser_fields').append(window[parser_klass.data('partial')])
|
172
|
+
$('.parser_fields').append(window[parser_klass.data('partial')]);
|
135
173
|
}
|
136
174
|
|
137
|
-
handleBrowseEverything()
|
138
|
-
var file_path_value = $('#importer_parser_fields_import_file_path').val()
|
139
|
-
handleFileToggle(file_path_value)
|
175
|
+
handleBrowseEverything();
|
176
|
+
var file_path_value = $('#importer_parser_fields_import_file_path').val();
|
177
|
+
handleFileToggle(file_path_value);
|
140
178
|
}
|
141
179
|
|
142
180
|
function handleBrowseEverything(){
|
143
|
-
var button = $("button[data-toggle='browse-everything']")
|
181
|
+
var button = $("button[data-toggle='browse-everything']");
|
144
182
|
if(button.length == 0) { return; }
|
145
183
|
button.browseEverything({
|
146
184
|
route: button.data('route'),
|
147
185
|
target: button.data('target')
|
148
186
|
}).done(function(data) {
|
149
187
|
var evt = { isDefaultPrevented: function() { return false; } };
|
150
|
-
$('.ev-browser.show').removeClass('show')
|
188
|
+
$('.ev-browser.show').removeClass('show');
|
151
189
|
if($('#fileupload').length > 0) {
|
152
|
-
var files = $.map(data, function(d) { return { name: d.file_name, size: d.file_size, id: d.url } });
|
190
|
+
var files = $.map(data, function(d) { return { name: d.file_name, size: d.file_size, id: d.url }; });
|
153
191
|
$.blueimp.fileupload.prototype.options.done.call($('#fileupload').fileupload(), evt, { result: { files: files }});
|
154
192
|
}
|
155
|
-
return true
|
156
|
-
// User has submitted files; data contains an array of URLs and their options
|
193
|
+
return true;
|
157
194
|
}).cancel(function() {
|
158
|
-
$('.ev-browser.show').removeClass('show')
|
159
|
-
// User cancelled the browse operation
|
195
|
+
$('.ev-browser.show').removeClass('show');
|
160
196
|
}).fail(function(status, error, text) {
|
161
|
-
$('.ev-browser.show').removeClass('show')
|
162
|
-
// URL retrieval experienced a technical failure
|
197
|
+
$('.ev-browser.show').removeClass('show');
|
163
198
|
});
|
164
199
|
}
|
165
200
|
|
166
201
|
function handleSourceLoad(refresh_button, base_url, external_set_select) {
|
167
202
|
if (base_url.val() == "") { // ignore empty base_url value
|
168
|
-
return
|
203
|
+
return;
|
169
204
|
}
|
170
205
|
|
171
|
-
var initial_button_text = refresh_button.html()
|
206
|
+
var initial_button_text = refresh_button.html();
|
172
207
|
|
173
|
-
refresh_button.html('Refreshing...')
|
174
|
-
refresh_button.attr('disabled', true)
|
208
|
+
refresh_button.html('Refreshing...');
|
209
|
+
refresh_button.attr('disabled', true);
|
175
210
|
|
176
211
|
$.post('/importers/external_sets', {
|
177
212
|
base_url: base_url.val(),
|
178
213
|
}, function(res) {
|
179
214
|
if (!res.error) {
|
180
|
-
genExternalSetOptions(external_set_select, res.sets)
|
215
|
+
genExternalSetOptions(external_set_select, res.sets);
|
181
216
|
} else {
|
182
|
-
setError(external_set_select, res.error)
|
217
|
+
setError(external_set_select, res.error);
|
183
218
|
}
|
184
219
|
|
185
|
-
refresh_button.html(initial_button_text)
|
186
|
-
refresh_button.attr('disabled', false)
|
187
|
-
})
|
220
|
+
refresh_button.html(initial_button_text);
|
221
|
+
refresh_button.attr('disabled', false);
|
222
|
+
});
|
188
223
|
}
|
189
224
|
|
190
225
|
function genExternalSetOptions(selector, sets) {
|
191
|
-
out = '<option value="">- Select One -</option>'
|
226
|
+
out = '<option value="">- Select One -</option>';
|
192
227
|
|
193
228
|
out += sets.map(function(set) {
|
194
|
-
return '<option value="'+set[1]+'">'+set[0]+'</option>'
|
195
|
-
})
|
229
|
+
return '<option value="'+set[1]+'">'+set[0]+'</option>';
|
230
|
+
});
|
196
231
|
|
197
|
-
selector.html(out)
|
198
|
-
selector.attr('disabled', false)
|
232
|
+
selector.html(out);
|
233
|
+
selector.attr('disabled', false);
|
199
234
|
}
|
200
235
|
|
201
236
|
function setError(selector, error) {
|
202
|
-
selector.html('<option value="none">Error - Please enter Base URL and try again</option>')
|
203
|
-
selector.attr('disabled', true)
|
237
|
+
selector.html('<option value="none">Error - Please enter Base URL and try again</option>');
|
238
|
+
selector.attr('disabled', true);
|
204
239
|
}
|
205
240
|
|
206
|
-
$(document).on({'ready': prepBulkrax, 'turbolinks:load': prepBulkrax})
|
241
|
+
$(document).on({'ready': prepBulkrax, 'turbolinks:load': prepBulkrax});
|
@@ -78,11 +78,13 @@ module Bulkrax
|
|
78
78
|
|
79
79
|
# POST /importers
|
80
80
|
# rubocop:disable Metrics/MethodLength
|
81
|
+
# rubocop:disable Metrics/AbcSize
|
81
82
|
def create
|
82
83
|
# rubocop:disable Style/IfInsideElse
|
83
84
|
if api_request?
|
84
85
|
return return_json_response unless valid_create_params?
|
85
86
|
end
|
87
|
+
uploads = Hyrax::UploadedFile.find(params[:uploaded_files]) if params[:uploaded_files].present?
|
86
88
|
file = file_param
|
87
89
|
cloud_files = cloud_params
|
88
90
|
|
@@ -93,7 +95,7 @@ module Bulkrax
|
|
93
95
|
# on a new import otherwise it only gets updated during the update path
|
94
96
|
@importer.parser_fields['update_files'] = true if params[:commit] == 'Create and Import'
|
95
97
|
if @importer.save
|
96
|
-
files_for_import(file, cloud_files)
|
98
|
+
files_for_import(file, cloud_files, uploads)
|
97
99
|
if params[:commit] == 'Create and Import'
|
98
100
|
Bulkrax::ImporterJob.send(@importer.parser.perform_method, @importer.id)
|
99
101
|
render_request('Importer was successfully created and import has been queued.')
|
@@ -112,6 +114,7 @@ module Bulkrax
|
|
112
114
|
end
|
113
115
|
# rubocop:enable Style/IfInsideElse
|
114
116
|
end
|
117
|
+
# rubocop:enable Metrics/AbcSize
|
115
118
|
|
116
119
|
# PATCH/PUT /importers/1
|
117
120
|
# # @todo refactor so as to not need to disable rubocop
|
@@ -120,7 +123,7 @@ module Bulkrax
|
|
120
123
|
if api_request?
|
121
124
|
return return_json_response unless valid_update_params?
|
122
125
|
end
|
123
|
-
|
126
|
+
uploads = Hyrax::UploadedFile.find(params[:uploaded_files]) if params[:uploaded_files].present?
|
124
127
|
file = file_param
|
125
128
|
cloud_files = cloud_params
|
126
129
|
|
@@ -128,7 +131,7 @@ module Bulkrax
|
|
128
131
|
field_mapping_params if params[:importer][:parser_fields].present?
|
129
132
|
|
130
133
|
if @importer.update(importer_params)
|
131
|
-
files_for_import(file, cloud_files)
|
134
|
+
files_for_import(file, cloud_files, uploads)
|
132
135
|
# do not perform the import
|
133
136
|
unless params[:commit] == 'Update Importer'
|
134
137
|
set_files_parser_fields
|
@@ -218,8 +221,9 @@ module Bulkrax
|
|
218
221
|
|
219
222
|
private
|
220
223
|
|
221
|
-
def files_for_import(file, cloud_files)
|
222
|
-
return if file.blank? && cloud_files.blank?
|
224
|
+
def files_for_import(file, cloud_files, uploads)
|
225
|
+
return if file.blank? && cloud_files.blank? && uploads.blank?
|
226
|
+
|
223
227
|
@importer[:parser_fields]['import_file_path'] = @importer.parser.write_import_file(file) if file.present?
|
224
228
|
if cloud_files.present?
|
225
229
|
@importer[:parser_fields]['cloud_file_paths'] = cloud_files
|
@@ -229,6 +233,13 @@ module Bulkrax
|
|
229
233
|
target = @importer.parser.retrieve_cloud_files(cloud_files, @importer)
|
230
234
|
@importer[:parser_fields]['import_file_path'] = target if target.present?
|
231
235
|
end
|
236
|
+
|
237
|
+
if uploads.present?
|
238
|
+
uploads.each do |upload|
|
239
|
+
@importer[:parser_fields]['import_file_path'] = @importer.parser.write_import_file(upload.file.file)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
232
243
|
@importer.save
|
233
244
|
end
|
234
245
|
|
@@ -10,11 +10,11 @@ module Bulkrax
|
|
10
10
|
om = parent.ordered_members.to_a
|
11
11
|
om.delete(file_set)
|
12
12
|
parent.ordered_members = om
|
13
|
-
|
13
|
+
parent.save
|
14
|
+
elsif parent&.respond_to?(:member_ids)
|
14
15
|
parent.member_ids.delete(file_set.id)
|
15
16
|
Hyrax.persister.save(resource: parent)
|
16
17
|
end
|
17
|
-
parent.save
|
18
18
|
end
|
19
19
|
|
20
20
|
super
|
@@ -41,9 +41,16 @@
|
|
41
41
|
<p>File upload and Cloud File upload must be a Zip file containing a single BagIt Bag, or a folder containing multiple BagIt Bags.</p>
|
42
42
|
<p>The Server Path can point to a BagIt Bag, a folder containing BagIt Bags, or a zip file containing either.</p>
|
43
43
|
|
44
|
-
|
44
|
+
<%= fi.input :file_style,
|
45
|
+
collection: ['Upload a File', 'Specify a Path on the Server'] +
|
46
|
+
(defined?(::Hyrax) && Hyrax.config.browse_everything? ? ['Add Cloud File'] : []),
|
47
|
+
as: :radio_buttons, label: false %>
|
45
48
|
<div id='file_upload'>
|
46
|
-
|
49
|
+
<% if defined?(::Hyrax) %>
|
50
|
+
<%= render 'bulkrax/importers/file_uploader', accepted_file_types: 'application/zip' %>
|
51
|
+
<% else %>
|
52
|
+
<%= fi.input 'file', as: :file, input_html: {accept: 'application/zip'} %><br />
|
53
|
+
<% end %>
|
47
54
|
</div>
|
48
55
|
<div id='file_path'>
|
49
56
|
<%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
|
@@ -53,4 +60,4 @@
|
|
53
60
|
<%= render 'browse_everything', form: form %>
|
54
61
|
<% end %>
|
55
62
|
</div>
|
56
|
-
</div>
|
63
|
+
</div>
|
@@ -1,5 +1,4 @@
|
|
1
1
|
<div class='csv_fields'>
|
2
|
-
|
3
2
|
<%= fi.input :visibility,
|
4
3
|
label: 'Default Visibility',
|
5
4
|
collection: [
|
@@ -11,7 +10,6 @@
|
|
11
10
|
input_html: { class: 'form-control' },
|
12
11
|
hint: 'If your CSV includes the visibility field, it will override the default setting.'
|
13
12
|
%>
|
14
|
-
|
15
13
|
<% if defined?(::Hyrax) %>
|
16
14
|
<% rights_statements = Hyrax.config.rights_statement_service_class.new %>
|
17
15
|
<%= fi.input :rights_statement,
|
@@ -24,26 +22,32 @@
|
|
24
22
|
%>
|
25
23
|
<%= fi.input :override_rights_statement, as: :boolean, hint: 'If checked, always use the selected rights statment. If unchecked, use rights or rights_statement from the record and only use the provided value if dc:rights is blank.', input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
|
26
24
|
<% end %>
|
27
|
-
<h4>Add CSV File to Import:</h4>
|
25
|
+
<h4>Add CSV or ZIP File to Import:</h4>
|
28
26
|
<%# accept a single file upload; data files and bags will need to be added another way %>
|
29
|
-
|
30
27
|
<% file_style_list = ['Upload a File', 'Specify a Path on the Server'] %>
|
31
28
|
<% file_style_list << 'Existing Entries' unless importer.new_record? %>
|
32
29
|
<%= fi.input :file_style, collection: file_style_list, as: :radio_buttons, label: false %>
|
30
|
+
|
33
31
|
<div id='file_upload'>
|
34
|
-
|
32
|
+
<% if defined?(::Hyrax) %>
|
33
|
+
<%= render 'bulkrax/importers/file_uploader', accepted_file_types: 'text/csv,application/zip,application/gzip' %>
|
34
|
+
<% else %>
|
35
|
+
<%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip,application/gzip' } %><br />
|
36
|
+
<% end %>
|
35
37
|
</div>
|
38
|
+
|
36
39
|
<div id='file_path'>
|
37
40
|
<%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
|
38
41
|
</div>
|
42
|
+
|
39
43
|
<div id='existing_options'>
|
40
44
|
<%= fi.collection_check_boxes :entry_statuses, [['Failed'], ['Pending'], ['Skipped'], ['Deleted'], ['Complete']], :first, :first %>
|
41
45
|
</div>
|
42
|
-
|
46
|
+
|
43
47
|
<% if defined?(::Hyrax) && Hyrax.config.browse_everything? %>
|
44
|
-
|
45
|
-
|
48
|
+
<h4>Add Files to Import:</h4>
|
49
|
+
<p>Choose files to upload. The filenames must be unique, and the filenames must be referenced in a column called 'file' in the accompanying CSV file.</p>
|
46
50
|
<%= render 'browse_everything', form: form %>
|
47
51
|
<% end %>
|
48
52
|
<br />
|
49
|
-
</div>
|
53
|
+
</div>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<div class="fileupload-bulkrax">
|
2
|
+
<noscript><input type="hidden" name="redirect" value="<%= main_app.root_path %>" /></noscript>
|
3
|
+
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
|
4
|
+
<div class="fileupload-buttonbar">
|
5
|
+
<div class="row">
|
6
|
+
<div class="col-12">
|
7
|
+
<div class="fileinput-button" id="add-files">
|
8
|
+
<input id="addfiles" type="file" style="display:none;" name="files[]"
|
9
|
+
accept="<%= accepted_file_types || 'text/csv,application/zip,application/gzip' %>" multiple />
|
10
|
+
<button type="button" class="btn btn-success" onclick="document.getElementById('addfiles').click();">
|
11
|
+
<span class="fa fa-plus"></span>
|
12
|
+
<span>Add Files</span>
|
13
|
+
</button>
|
14
|
+
</div>
|
15
|
+
<button type="reset" id="file-upload-cancel-btn" class="btn btn-warning cancel">
|
16
|
+
<span class="fa fa-ban"></span>
|
17
|
+
<span>Cancel Upload</span>
|
18
|
+
</button>
|
19
|
+
<span class="fileupload-process"></span>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<div class="row">
|
23
|
+
<div class="col-12">
|
24
|
+
<div class="fileupload-progress fade">
|
25
|
+
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
26
|
+
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success" style="width:0%;"></div>
|
27
|
+
</div>
|
28
|
+
<div class="progress-extended"> </div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div class="dropzone">
|
34
|
+
Drop files here to upload
|
35
|
+
</div>
|
36
|
+
<%= render 'hyrax/uploads/js_templates' %>
|
37
|
+
</div>
|
@@ -47,16 +47,22 @@
|
|
47
47
|
<p>File upload and Cloud File upload MUST be a either a single XML file (for metadata only import) OR a Zip file containing the XML files and data files, each in a separate folder.</p>
|
48
48
|
<p>The Server Path can point to a folder containing XML files and data files to import, or direct to the XML file itself.</p>
|
49
49
|
|
50
|
-
|
50
|
+
<%= fi.input :file_style,
|
51
|
+
collection: ['Upload a File', 'Specify a Path on the Server'] +
|
52
|
+
(defined?(::Hyrax) && Hyrax.config.browse_everything? ? ['Add Cloud File'] : []),
|
53
|
+
as: :radio_buttons, label: false %>
|
51
54
|
<div id='file_upload'>
|
52
|
-
|
55
|
+
<% if defined?(::Hyrax) %>
|
56
|
+
<%= render 'bulkrax/importers/file_uploader', accepted_file_types: 'application/zip,application/xml' %>
|
57
|
+
<% else %>
|
58
|
+
<%= fi.input 'file', as: :file, input_html: {accept: ['application/zip', 'application/xml']} %><br />
|
59
|
+
<% end%>
|
53
60
|
</div>
|
54
61
|
<div id='file_path'>
|
55
62
|
<%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
|
56
63
|
</div>
|
57
64
|
<div id='cloud'>
|
58
65
|
<% if defined?(::Hyrax) && Hyrax.config.browse_everything? %>
|
59
|
-
<%= render 'browse_everything', form: form %>
|
60
66
|
<% end %>
|
61
67
|
</div>
|
62
|
-
</div>
|
68
|
+
</div>
|
data/lib/bulkrax/version.rb
CHANGED
data/lib/bulkrax.rb
CHANGED
@@ -98,7 +98,20 @@ module Bulkrax
|
|
98
98
|
attr_writer :collection_model_class
|
99
99
|
|
100
100
|
def collection_model_internal_resource
|
101
|
-
|
101
|
+
# WARN: Using #try on :internal_resource can yield unexpected results.
|
102
|
+
# If the method is undefined, it can return a truthy value instead of
|
103
|
+
# the typical nil.
|
104
|
+
#
|
105
|
+
# E.g.
|
106
|
+
# ```ruby
|
107
|
+
# Hyrax::FileSet.try(:internal_resource) || 'hi'
|
108
|
+
# => #<Dry::Types::Result::Failure input=:internal_resource error=...
|
109
|
+
# ```
|
110
|
+
if collection_model_class.respond_to?(:internal_resource)
|
111
|
+
collection_model_class.internal_resource
|
112
|
+
else
|
113
|
+
collection_model_class.to_s
|
114
|
+
end
|
102
115
|
end
|
103
116
|
|
104
117
|
def file_model_class
|
@@ -108,7 +121,20 @@ module Bulkrax
|
|
108
121
|
attr_writer :file_model_class
|
109
122
|
|
110
123
|
def file_model_internal_resource
|
111
|
-
|
124
|
+
# WARN: Using #try on :internal_resource can yield unexpected results.
|
125
|
+
# If the method is undefined, it can return a truthy value instead of
|
126
|
+
# the typical nil.
|
127
|
+
#
|
128
|
+
# E.g.
|
129
|
+
# ```ruby
|
130
|
+
# Hyrax::FileSet.try(:internal_resource) || 'hi'
|
131
|
+
# => #<Dry::Types::Result::Failure input=:internal_resource error=...
|
132
|
+
# ```
|
133
|
+
if file_model_class.respond_to?(:internal_resource)
|
134
|
+
file_model_class.internal_resource
|
135
|
+
else
|
136
|
+
file_model_class.to_s
|
137
|
+
end
|
112
138
|
end
|
113
139
|
|
114
140
|
def curation_concerns
|
@@ -118,7 +144,18 @@ module Bulkrax
|
|
118
144
|
attr_writer :curation_concerns
|
119
145
|
|
120
146
|
def curation_concern_internal_resources
|
121
|
-
curation_concerns.map
|
147
|
+
curation_concerns.map do |cc|
|
148
|
+
# WARN: Using #try on :internal_resource can yield unexpected results.
|
149
|
+
# If the method is undefined, it can return a truthy value instead of
|
150
|
+
# the typical nil.
|
151
|
+
#
|
152
|
+
# E.g.
|
153
|
+
# ```ruby
|
154
|
+
# Hyrax::FileSet.try(:internal_resource) || 'hi'
|
155
|
+
# => #<Dry::Types::Result::Failure input=:internal_resource error=...
|
156
|
+
# ```
|
157
|
+
cc.respond_to?(:internal_resource) ? cc.internal_resource : cc.to_s
|
158
|
+
end.uniq
|
122
159
|
end
|
123
160
|
|
124
161
|
attr_writer :ingest_queue_name
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bulkrax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.
|
4
|
+
version: 8.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Kaufman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -134,14 +134,14 @@ dependencies:
|
|
134
134
|
requirements:
|
135
135
|
- - "~>"
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version:
|
137
|
+
version: '5.0'
|
138
138
|
type: :runtime
|
139
139
|
prerelease: false
|
140
140
|
version_requirements: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
144
|
+
version: '5.0'
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: loofah
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -428,6 +428,7 @@ files:
|
|
428
428
|
- app/views/bulkrax/importers/_csv_fields.html.erb
|
429
429
|
- app/views/bulkrax/importers/_edit_form_buttons.html.erb
|
430
430
|
- app/views/bulkrax/importers/_edit_item_buttons.html.erb
|
431
|
+
- app/views/bulkrax/importers/_file_uploader.html.erb
|
431
432
|
- app/views/bulkrax/importers/_form.html.erb
|
432
433
|
- app/views/bulkrax/importers/_oai_fields.html.erb
|
433
434
|
- app/views/bulkrax/importers/_xml_fields.html.erb
|
@@ -518,7 +519,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
518
519
|
- !ruby/object:Gem::Version
|
519
520
|
version: '0'
|
520
521
|
requirements: []
|
521
|
-
rubygems_version: 3.4.
|
522
|
+
rubygems_version: 3.4.20
|
522
523
|
signing_key:
|
523
524
|
specification_version: 4
|
524
525
|
summary: Import and export tool for Hyrax and Hyku
|