bulkrax 8.2.3 → 8.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efd4c183d72156bd32a32eb0e160485f1dc46c67630f6835db761bb93ab3b16b
4
- data.tar.gz: 05c58dccdae7e285db479602490dd3be7429405f931a18aede0accbd4eec3503
3
+ metadata.gz: 9a409c17f35bc09ef0a8c63d06a064d01fbff68a0e4c0b91c9bfaed45d6e8169
4
+ data.tar.gz: 7fad94124795ff133b83d05030c550f2a52f808ac017fdd3a436c17ce039cd01
5
5
  SHA512:
6
- metadata.gz: e64eecf68566f81c2d105640b71b8b6834e4c32fc18a416f0c026883387a257f913ad82ad676826b6a744a352edbce4a21aa82a304b23f2583f2c15a97f72078
7
- data.tar.gz: 9c4ce4f1b4d36c5dcb031ce0a8ecb6617c0114dbc891384d3de5fe6e5ee42b04761001d269d22d6b54c616aaf3cf793e461187d0e17fd20c3a025a907c20fb4e
6
+ metadata.gz: 65280762e81baa620e73d965d5e7c58ec4ccb40d303c00cf634e7f9b3b3850e541cc9964900ce7b9aec9f6be1a7fe81dd9781db5b74209a9f8661f5f8a96f595
7
+ data.tar.gz: e91e65f6de8edc1640dd9b6e75c246fff4fd0812a3f87f6b4600dd9c95afc095be6076c9a80c5bca50ccc73c3831fc0a30c1160b46f18c483a6d68277bf762a8
@@ -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
- var form = document.getElementsByClassName('edit_importer')[0];
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 (callback);
68
- observer.observe (form, config);
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) // sets is [[name, spec]...]
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) unless file.nil? && cloud_files.nil?
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
 
@@ -132,7 +132,7 @@ module Bulkrax
132
132
  status_message: status_message_for(e),
133
133
  type: e.type,
134
134
  updated_at: e.updated_at,
135
- errors: e.status_message == 'Failed' ? view_context.link_to(e.error_class, view_context.item_entry_path(item, e)) : "",
135
+ errors: e.latest_status&.error_class&.present? ? view_context.link_to(e.latest_status.error_class, view_context.item_entry_path(item, e), title: e.latest_status.error_message) : "",
136
136
  actions: entry_util_links(e, item)
137
137
  }
138
138
  end
@@ -165,10 +165,7 @@ module Bulkrax
165
165
  end
166
166
 
167
167
  def delete(_user)
168
- obj = find
169
- return false unless obj
170
-
171
- obj.delete(eradicate: true)
168
+ find&.delete(eradicate: true)
172
169
  end
173
170
 
174
171
  private
@@ -26,7 +26,7 @@ module Bulkrax
26
26
  end
27
27
  # rubocop:enable Rails/SkipsModelValidations
28
28
  end
29
- return entry if exporter_run.reload.enqueued_records.positive?
29
+ return entry if exporter_run.enqueued_records.positive?
30
30
 
31
31
  if exporter_run.failed_records.positive?
32
32
  exporter_run.exporter.set_status_info('Complete (with failures)')
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class Status < ApplicationRecord
5
- belongs_to :statusable, polymorphic: true, denormalize: { fields: %i[status_message error_class], if: :latest? }
5
+ belongs_to :statusable, polymorphic: true, denormalize: { fields: %i[status_message], if: :latest? }
6
6
  belongs_to :runnable, polymorphic: true
7
7
  serialize :error_backtrace, Array
8
8
 
@@ -26,15 +26,11 @@ module Bulkrax
26
26
 
27
27
  # Prepend the file_set id to ensure a unique filename and also one that is not longer than 255 characters
28
28
  def filename(file_set)
29
+ # NOTE: Will this work with Valkyrie?
29
30
  return if file_set.original_file.blank?
30
- if file_set.original_file.respond_to?(:original_filename) # valkyrie
31
- fn = file_set.original_file.original_filename
32
- mime = ::Marcel::MimeType.for(file_set.original_file.file.io)
33
- else # original non valkyrie version
34
- fn = file_set.original_file.file_name.first
35
- mime = ::Marcel::MimeType.for(declared_type: file_set.original_file.mime_type)
36
- end
37
- ext_mime = ::Marcel::MimeType.for(name: fn)
31
+ fn = file_set.original_file.file_name.first
32
+ mime = ::Marcel::MimeType.for(file_set.original_file.mime_type)
33
+ ext_mime = ::Marcel::MimeType.for(file_set.original_file.file_name)
38
34
  if fn.include?(file_set.id) || importerexporter.metadata_only?
39
35
  filename = "#{fn}.#{mime.to_sym}"
40
36
  filename = fn if mime.to_s == ext_mime.to_s
@@ -244,10 +244,7 @@ module Bulkrax
244
244
  record = Bulkrax.object_factory.find(identifier)
245
245
  return unless record
246
246
 
247
- file_sets = Array.wrap(record) if record.file_set?
248
- if file_sets.nil? # for valkyrie
249
- file_sets = record.respond_to?(:file_sets) ? record.file_sets : record.members&.select(&:file_set?)
250
- end
247
+ file_sets = record.file_set? ? Array.wrap(record) : record.file_sets
251
248
  file_sets << record.thumbnail if exporter.include_thumbnails && record.thumbnail.present? && record.work?
252
249
  file_sets.each do |fs|
253
250
  path = File.join(exporter_export_path, folder_count, 'files')
@@ -255,7 +252,7 @@ module Bulkrax
255
252
  file = filename(fs)
256
253
  next if file.blank? || fs.original_file.blank?
257
254
 
258
- io = fs.original_file.respond_to?(:uri) ? open(fs.original_file.uri) : fs.original_file.file.io
255
+ io = open(fs.original_file.uri)
259
256
  File.open(File.join(path, file), 'wb') do |f|
260
257
  f.write(io.read)
261
258
  f.close
@@ -173,7 +173,7 @@ module Bulkrax
173
173
  # @see https://github.com/samvera/hyrax/blob/64c0bbf0dc0d3e1b49f040b50ea70d177cc9d8f6/app/indexers/hyrax/work_indexer.rb#L15-L18
174
174
  def file_sets
175
175
  @file_sets ||= ParserExportRecordSet.in_batches(candidate_file_set_ids) do |batch_of_ids|
176
- fsq = "has_model_ssim:\"#{Bulkrax.file_model_internal_resource.demodulize}\" AND id:(\"" + batch_of_ids.join('" OR "') + "\")"
176
+ fsq = "has_model_ssim:#{Bulkrax.file_model_internal_resource} AND id:(\"" + batch_of_ids.join('" OR "') + "\")"
177
177
  fsq += extra_filters if extra_filters.present?
178
178
  Bulkrax.object_factory.query(
179
179
  fsq,
@@ -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
- <%= fi.input :file_style, collection: ['Upload a File', 'Specify a Path on the Server', 'Add Cloud File'], as: :radio_buttons, label: false %>
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
- <%= fi.input 'file', as: :file, input_html: {accept: 'application/zip'} %><br />
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
- <%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip,application/gzip' } %><br />
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
- <h4>Add Files to Import:</h4>
45
- <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>
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">&nbsp;</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
- <%= fi.input :file_style, collection: ['Upload a File', 'Specify a Path on the Server', 'Add Cloud File'], as: :radio_buttons, label: false %>
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
- <%= fi.input 'file', as: :file, input_html: {accept: ['application/zip', 'application/xml']} %><br />
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>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- VERSION = '8.2.3'
4
+ VERSION = '8.3.0'
5
5
  end
@@ -9,7 +9,7 @@ namespace :bulkrax do
9
9
  progress_mark: ' ',
10
10
  remainder_mark: "\u{FF65}")
11
11
  Bulkrax::Status.latest_by_statusable.includes(:statusable).find_each do |status|
12
- status.statusable.update(status_message: status.status_message, error_class: status.error_class)
12
+ status.statusable.update(status_message: status.status_message)
13
13
  @progress.increment
14
14
  end
15
15
  end
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.2.3
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-12-20 00:00:00.000000000 Z
11
+ date: 2024-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.0
33
+ version: 0.4.6
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.0
40
+ version: 0.4.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: coderay
43
43
  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
@@ -486,8 +487,6 @@ files:
486
487
  - db/migrate/20240823173525_add_error_tracking_to_pending_relationships.rb
487
488
  - db/migrate/20240916182737_add_last_imported_at_to_bulkrax_importers.rb
488
489
  - db/migrate/20240916182823_add_next_import_at_to_bulkrax_importers.rb
489
- - db/migrate/20241203010707_entry_error_denormalization.rb
490
- - db/migrate/20241205212513_faster_first_entry.rb
491
490
  - lib/bulkrax.rb
492
491
  - lib/bulkrax/engine.rb
493
492
  - lib/bulkrax/entry_spec_helper.rb
@@ -520,7 +519,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
520
519
  - !ruby/object:Gem::Version
521
520
  version: '0'
522
521
  requirements: []
523
- rubygems_version: 3.1.4
522
+ rubygems_version: 3.4.20
524
523
  signing_key:
525
524
  specification_version: 4
526
525
  summary: Import and export tool for Hyrax and Hyku
@@ -1,7 +0,0 @@
1
- class EntryErrorDenormalization < ActiveRecord::Migration[5.1]
2
- def change
3
- add_column :bulkrax_entries, :error_class, :string unless column_exists?(:bulkrax_entries, :error_class)
4
- add_column :bulkrax_importers, :error_class, :string unless column_exists?(:bulkrax_importers, :error_class)
5
- add_column :bulkrax_exporters, :error_class, :string unless column_exists?(:bulkrax_exporters, :error_class)
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
- class FasterFirstEntry < ActiveRecord::Migration[5.2]
3
- def change
4
- add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type, :id], name: 'index_bulkrax_entries_on_importerexporter_id_type_and_id' unless index_exists?(:bulkrax_entries, [:importerexporter_id, :importerexporter_type, :id],
5
- name: 'index_bulkrax_entries_on_importerexporter_id_type_and_id')
6
- end
7
- end