bulkrax 1.0.1 → 1.0.2

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: 4e97637c391f4f4a5d9c13d04b76315da5931ecf0ae418a50eeae7a872b9d525
4
- data.tar.gz: dbba6215c04c4f65d40dbd37bf7e962aa2e9f42fd677be260a12f0f02d4c7ce5
3
+ metadata.gz: 2cad330885f5f4d2dce25c989ebc7552b49b2212b68434d5def942fff61ad23a
4
+ data.tar.gz: 2b1e71044b26ff6ab9b25822ee969a7e886e095bbd2147b9b240406634e8f832
5
5
  SHA512:
6
- metadata.gz: e385b03e162c0765134354d44575662260ce33cd007adeeabc6d920db749c3b43e3741d99779b2ba5b9d5a126610a205f9c5d33d6f8761f356e8d34de1eac196
7
- data.tar.gz: ae3edaa107bb8a5df268e19909850b34b171a024aba07e1b24d6cbd6407546e7184cb4e925964b8e21842eb842f38b2078f9419a862660787c1a80406173615e
6
+ metadata.gz: 18e70353c64be13d686ff1da35d01c932422da49f9fd0ebf08470fdc0edc9333a9b51633b158cfaedf020ae5e3830574eb192a69ba498dff81e92847de4235f7
7
+ data.tar.gz: 6502ec16bc63aefed3c678ec062d3bc923c159260ac39278e692f4628bfe05acd675d49193b92c9e42f2ab50976d48c3d608d77f8db1d45774a664fd74b09bce
@@ -118,12 +118,12 @@ module Bulkrax
118
118
  # OAI-only - selective re-harvest
119
119
  elsif params[:commit] == 'Update and Harvest Updated Items'
120
120
  Bulkrax::ImporterJob.perform_later(@importer.id, true)
121
- elsif params[:commit] == 'Update All (update metadata and update files)'
121
+ elsif params[:commit] == 'Update Metadata and Files'
122
122
  @importer.parser_fields['update_files'] = true
123
123
  @importer.save
124
124
  Bulkrax::ImporterJob.perform_later(@importer.id)
125
125
  # Perform a full metadata and files re-import; do the same for an OAI re-harvest of all items
126
- elsif params[:commit] == ('Update and Replace (update metadata and replace files)' || 'Update and Re-Harvest All Items')
126
+ elsif params[:commit] == ('Update and Replace Files' || 'Update and Re-Harvest All Items')
127
127
  @importer.parser_fields['replace_files'] = true
128
128
  @importer.save
129
129
  Bulkrax::ImporterJob.perform_later(@importer.id)
@@ -19,6 +19,11 @@ module Bulkrax
19
19
  end
20
20
  # rubocop:enable Metrics/ParameterLists
21
21
 
22
+ # update files is set, replace files is set or this is a create
23
+ def with_files
24
+ update_files || replace_files || !object
25
+ end
26
+
22
27
  def run
23
28
  arg_hash = { id: attributes[:id], name: 'UPDATE', klass: klass }
24
29
  @object = find
@@ -204,10 +209,10 @@ module Bulkrax
204
209
  def attribute_update
205
210
  return transform_attributes.except(:id) if klass == Collection
206
211
  if attributes[:collection].present?
207
- transform_attributes.except(:id).except(:collection).merge(member_of_collections_attributes: { 0 => { id: collection.id } })
212
+ transform_attributes.except(:id).except(:collection).merge(member_of_collections_attributes: { "0" => { id: collection.id } })
208
213
  elsif attributes[:collections].present?
209
214
  collection_ids = attributes[:collections].each.with_index.each_with_object({}) do |(element, index), ids|
210
- ids[index] = element
215
+ ids[index.to_s] = element
211
216
  end
212
217
  transform_attributes.except(:id).except(:collections).merge(member_of_collections_attributes: collection_ids)
213
218
  else
@@ -218,8 +223,9 @@ module Bulkrax
218
223
  # Override if we need to map the attributes from the parser in
219
224
  # a way that is compatible with how the factory needs them.
220
225
  def transform_attributes
221
- attributes.slice(*permitted_attributes)
222
- .merge(file_attributes(update_files))
226
+ @transform_attributes = attributes.slice(*permitted_attributes)
227
+ @transform_attributes.merge!(file_attributes(update_files)) if with_files
228
+ @transform_attributes
223
229
  end
224
230
 
225
231
  # Regardless of what the Parser gives us, these are the properties we are prepared to accept.
@@ -54,7 +54,10 @@ module Bulkrax
54
54
  end
55
55
 
56
56
  def parse_remote_files(src)
57
- { url: src.strip } if src.present?
57
+ return if src.blank?
58
+ src.strip!
59
+ name = Bulkrax::Importer.safe_uri_filename(src)
60
+ { url: src, file_name: name }
58
61
  end
59
62
 
60
63
  def parse_language(src)
@@ -97,9 +97,17 @@ module Bulkrax
97
97
  mapping.each do |key, value|
98
98
  next if Bulkrax.reserved_properties.include?(key) && !field_supported?(key)
99
99
  next if key == "model"
100
- next unless hyrax_record.respond_to?(key.to_s)
101
- data = hyrax_record.send(key.to_s)
102
- if data.is_a?(ActiveTriples::Relation)
100
+
101
+ object_key = key if value.key?('object')
102
+ next unless hyrax_record.respond_to?(key.to_s) || object_key.present?
103
+
104
+ data = object_key.present? ? hyrax_record.send(value['object']) : hyrax_record.send(key.to_s)
105
+ if object_key.present?
106
+ next self.parsed_metadata[key] = '' if data.empty?
107
+ data = data.first if data.is_a?(ActiveTriples::Relation)
108
+
109
+ object_metadata(data, object_key)
110
+ elsif data.is_a?(ActiveTriples::Relation)
103
111
  self.parsed_metadata[key] = data.map { |d| prepare_export_data(d) }.join('; ').to_s unless value[:excluded]
104
112
  else
105
113
  self.parsed_metadata[key] = prepare_export_data(data)
@@ -115,6 +123,32 @@ module Bulkrax
115
123
  end
116
124
  end
117
125
 
126
+ def object_metadata(data, object_key)
127
+ data = convert_to_hash(data)
128
+
129
+ data.each_with_index do |obj, index|
130
+ next unless obj[object_key]
131
+
132
+ next self.parsed_metadata["#{object_key}_#{index + 1}"] = prepare_export_data(obj[object_key]) unless obj[object_key].is_a?(Array)
133
+
134
+ obj[object_key].each_with_index do |_nested_item, nested_index|
135
+ self.parsed_metadata["#{object_key}_#{index + 1}_#{nested_index + 1}"] = prepare_export_data(obj[object_key][nested_index])
136
+ end
137
+ end
138
+ end
139
+
140
+ def convert_to_hash(data)
141
+ # converts data from `'[{}]'` to `[{}]`
142
+ gsub_data = data.gsub(/\[{/, '{')
143
+ .gsub(/}\]/, '}')
144
+ .gsub('=>', ':')
145
+ .gsub(/},\s?{/, "}},{{")
146
+ .split("},{")
147
+ gsub_data = [gsub_data] if gsub_data.is_a?(String)
148
+
149
+ return gsub_data.map { |d| JSON.parse(d) }
150
+ end
151
+
118
152
  # In order for the existing exported hyrax_record, to be updated by a re-import
119
153
  # we need a unique value in system_identifier
120
154
  # add the existing hyrax_record id to system_identifier
@@ -24,6 +24,16 @@ module Bulkrax
24
24
  attr_accessor :only_updates, :file_style, :file
25
25
  attr_writer :current_run
26
26
 
27
+ def self.safe_uri_filename(uri)
28
+ uri = URI.parse(uri) unless uri.is_a?(URI)
29
+ r = Faraday.head(uri.to_s)
30
+ return CGI.parse(r.headers['content-disposition'])["filename"][0].delete("\"")
31
+ rescue
32
+ filename = File.basename(uri.path)
33
+ filename.delete!('/')
34
+ filename.presence || file_set.id
35
+ end
36
+
27
37
  def status
28
38
  if self.validate_only
29
39
  'Validated'
@@ -33,7 +33,8 @@ module Bulkrax
33
33
  if file_value.is_a?(Hash)
34
34
  file_value
35
35
  elsif file_value.is_a?(String)
36
- { url: file_value }
36
+ name = Bulkrax::Importer.safe_uri_filename(file_value)
37
+ { url: file_value, file_name: name }
37
38
  else
38
39
  Rails.logger.error("skipped remote file #{file_value} because we do not recognize the type")
39
40
  nil
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
-
2
+ # rubocop:disable Metrics/ModuleLength
3
3
  module Bulkrax
4
4
  module HasMatchers
5
5
  extend ActiveSupport::Concern
@@ -90,9 +90,20 @@ module Bulkrax
90
90
  end
91
91
 
92
92
  def multiple_metadata(content)
93
- content = content.content if content.is_a?(Nokogiri::XML::NodeSet)
94
93
  return unless content
95
- content.is_a?(Array) ? content : Array.wrap(content.strip)
94
+
95
+ case content
96
+ when Nokogiri::XML::NodeSet
97
+ content&.content
98
+ when Array
99
+ content
100
+ when Hash
101
+ Array.wrap(content)
102
+ when String
103
+ Array.wrap(content.strip)
104
+ else
105
+ Array.wrap(content)
106
+ end
96
107
  end
97
108
 
98
109
  def matched_metadata(multiple, name, result, object_multiple)
@@ -153,3 +164,4 @@ module Bulkrax
153
164
  end
154
165
  end
155
166
  end
167
+ # rubocop:enable Metrics/ModuleLength
@@ -7,6 +7,13 @@
7
7
  <div class='panel panel-default'>
8
8
  <div class='panel-body'>
9
9
 
10
+ <% if File.exist?(@exporter.exporter_export_zip_path) %>
11
+ <p class='bulkrax-p-align'>
12
+ <strong>Download:</strong>
13
+ <%= link_to raw('<span class="glyphicon glyphicon-download"></span>'), exporter_download_path(@exporter) %>
14
+ </p>
15
+ <% end %>
16
+
10
17
  <p class='bulkrax-p-align'>
11
18
  <strong><%= t('bulkrax.exporter.labels.name') %>:</strong>
12
19
  <%= @exporter.name %>
@@ -116,6 +123,10 @@
116
123
  <%= page_entries_info(@work_entries) %><br>
117
124
  <%= paginate(@work_entries, param_name: :work_entries_page) %>
118
125
  <br>
126
+ <% if File.exist?(@exporter.exporter_export_zip_path) %>
127
+ <%= link_to 'Download', exporter_download_path(@exporter) %>
128
+ |
129
+ <% end %>
119
130
  <%= link_to 'Edit', edit_exporter_path(@exporter) %>
120
131
  |
121
132
  <%= link_to 'Back', exporters_path %>
@@ -1,16 +1,47 @@
1
+ <div class="modal fade" id="bulkraxModal" tabindex="-1" role="dialog" aria-labelledby="bulkraxModalLabel">
2
+ <div class="modal-dialog" role="document">
3
+ <div class="modal-content">
4
+ <div class="modal-body">
5
+ <h5>Options for Updating the Importer</h5>
6
+ <hr />
1
7
 
2
- <%# If we can know the parser, we can vary the buttons here %>
8
+ <% if @importer.importer_runs.blank? %>
9
+ <p>Only update the values in the importer form. Do not import metadata or files for any works or collections.</p>
10
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
11
+ <hr />
12
+ <p>Update the values in the importer form and run the importer for the first time.</p>
13
+ <%= form.button :submit, value: 'Update and Import', class: 'btn btn-primary' %>
14
+ <% elsif @importer.parser_klass.include?('Oai') %>
15
+ <p>Only update the values in the importer form. Do not update metadata or files for any works or collections.</p>
16
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
17
+ <hr />
18
+ <p>Update the values in the importer form and update items that have changed at the source.</p>
19
+ <%= form.button :submit, value: 'Update and Harvest Updated Items', class: 'btn btn-primary' %>
20
+ <hr />
21
+ <p>Update the values in the importer form and recreate all items from the source.</p>
22
+ <%= form.button :submit, value: 'Update and Re-Harvest All Items', class: 'btn btn-primary' %>
23
+ <% else %>
24
+ <p>Only update the values in the importer form. Do not update metadata or files for any works or collections.</p>
25
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
26
+ <hr />
27
+ <p>Update the values in the importer form and update the metadata for all works. Do not update any files.</p>
28
+ <%= form.button :submit, value: 'Update Metadata', class: 'btn btn-primary' %>
29
+ <hr />
30
+ <p>Update the values in the importer form and update the metadata and files for all works. Creates new versions of the files and retains the old versions.</p>
31
+ <%= form.button :submit, value: 'Update Metadata and Files', class: 'btn btn-primary' %>
32
+ <hr />
33
+ <p>Update the values in the importer form and update the metadata. Completely removes all files attached to works for this importer and recreates the files from scratch.</p>
34
+ <%= form.button :submit,
35
+ value: 'Update and Replace Files',
36
+ class: 'btn btn-primary',
37
+ data: {confirm: "Are you sure? This will remove all files before adding them from the import."} %>
38
+ <% end %>
39
+ <hr />
3
40
 
4
- <% if @importer.importer_runs.blank? %>
5
- <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
6
- | <%= form.button :submit, value: 'Update and Import (importer has not yet been run)', class: 'btn btn-primary' %>
7
- <% elsif @importer.parser_klass.include?('Oai') %>
8
- <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
9
- | <%= form.button :submit, value: 'Update and Harvest Updated Items', class: 'btn btn-primary' %>
10
- | <%= form.button :submit, value: 'Update and Re-Harvest All Items', class: 'btn btn-primary' %>
11
- <% else %>
12
- <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
13
- | <%= form.button :submit, value: 'Update and Re-Import (update metadata only)', class: 'btn btn-primary' %>
14
- | <%= form.button :submit, value: 'Update All (update metadata and update files)', class: 'btn btn-primary' %>
15
- | <%= form.button :submit, value: 'Update and Re-Import (update metadata and replace files)', class: 'btn btn-primary', data: {confirm: "Are you sure? This will remove all files before adding them from the import."} %>
16
- <% end %>
41
+ </div>
42
+ <div class="modal-footer">
43
+ <button type="button" class="btn btn-default" data-dismiss="modal"><%= t('helpers.action.cancel') %></button>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
@@ -5,10 +5,12 @@
5
5
  <div class="row">
6
6
  <div class="col-md-12">
7
7
  <div class="panel panel-default tabs">
8
+
8
9
  <%= simple_form_for @importer, html: { multipart: true } do |form| %>
9
10
  <%= render 'form', importer: @importer, form: form %>
10
11
  <div class="panel-footer">
11
12
  <div class='pull-right'>
13
+ <%= link_to 'Update Importer', '#bulkraxModal', class: "btn btn-primary", data: { toggle: 'modal' } %>
12
14
  <%= render 'edit_form_buttons', form: form %>
13
15
  <% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
14
16
  | <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- VERSION = '1.0.1'
4
+ VERSION = '1.0.2'
5
5
  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: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Kaufman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails