bulkrax 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/bulkrax/exporters_controller.rb +12 -4
- data/app/controllers/bulkrax/importers_controller.rb +22 -17
- data/app/factories/bulkrax/object_factory.rb +36 -59
- data/app/jobs/bulkrax/create_relationships_job.rb +187 -0
- data/app/jobs/bulkrax/delete_work_job.rb +6 -2
- data/app/jobs/bulkrax/export_work_job.rb +3 -1
- data/app/jobs/bulkrax/exporter_job.rb +1 -0
- data/app/jobs/bulkrax/{import_work_collection_job.rb → import_collection_job.rb} +2 -2
- data/app/jobs/bulkrax/importer_job.rb +16 -1
- data/app/matchers/bulkrax/application_matcher.rb +5 -5
- data/app/models/bulkrax/csv_collection_entry.rb +8 -6
- data/app/models/bulkrax/csv_entry.rb +124 -66
- data/app/models/bulkrax/entry.rb +19 -8
- data/app/models/bulkrax/exporter.rb +12 -5
- data/app/models/bulkrax/importer.rb +12 -5
- data/app/models/bulkrax/oai_entry.rb +5 -1
- data/app/models/bulkrax/rdf_entry.rb +16 -7
- data/app/models/bulkrax/xml_entry.rb +4 -0
- data/app/models/concerns/bulkrax/export_behavior.rb +2 -2
- data/app/models/concerns/bulkrax/has_matchers.rb +44 -13
- data/app/models/concerns/bulkrax/import_behavior.rb +35 -5
- data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +19 -0
- data/app/models/concerns/bulkrax/status_info.rb +4 -4
- data/app/parsers/bulkrax/application_parser.rb +59 -84
- data/app/parsers/bulkrax/bagit_parser.rb +12 -3
- data/app/parsers/bulkrax/csv_parser.rb +117 -63
- data/app/parsers/bulkrax/oai_dc_parser.rb +5 -2
- data/app/parsers/bulkrax/xml_parser.rb +5 -0
- data/app/views/bulkrax/exporters/_form.html.erb +1 -1
- data/app/views/bulkrax/exporters/show.html.erb +2 -1
- data/app/views/bulkrax/importers/index.html.erb +15 -17
- data/app/views/bulkrax/importers/show.html.erb +6 -2
- data/config/locales/bulkrax.en.yml +1 -0
- data/db/migrate/20190731114016_change_importer_and_exporter_to_polymorphic.rb +5 -1
- data/db/migrate/20211004170708_change_bulkrax_statuses_error_message_column_type_to_text.rb +5 -0
- data/db/migrate/20211203195233_rename_children_counters_to_relationships.rb +6 -0
- data/lib/bulkrax/engine.rb +1 -1
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +9 -17
- data/lib/generators/bulkrax/templates/bin/importer +17 -11
- data/lib/generators/bulkrax/templates/config/bulkrax_api.yml +3 -1
- data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +7 -12
- metadata +6 -4
- data/app/jobs/bulkrax/child_relationships_job.rb +0 -128
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56a6005830d733023f9455ebb9e0565081dacbfbf1a36ebad290d594d74499f4
|
4
|
+
data.tar.gz: dbfe501d7c62a47091e23fbc9b7b7e8aff3147f88c999eb9d55bc6e6bf27ae05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1054dbc43420ad3fba9f75e8c88cec4b795c55a1dc5416b5b37a7a75eff994f629aa7740dda54f635be406ec2b7c4f913b1de7426cbd1a378573cd42d526e5c7
|
7
|
+
data.tar.gz: 6eb81924d7587caddcea1ec4b7d71b41324336a85ea2ae6662662028ccc3c5b92f93b5aa02fe7d0a9c19cb5e16db560ff95cfc74b85f475bae0c425ecb96824c
|
data/README.md
CHANGED
@@ -51,9 +51,12 @@ module Bulkrax
|
|
51
51
|
if @exporter.save
|
52
52
|
if params[:commit] == 'Create and Export'
|
53
53
|
# Use perform now for export
|
54
|
-
Bulkrax::ExporterJob.
|
54
|
+
Bulkrax::ExporterJob.perform_later(@exporter.id)
|
55
|
+
message = 'Exporter was successfully created. A download link will appear once it completes.'
|
56
|
+
else
|
57
|
+
message = 'Exporter was successfully created.'
|
55
58
|
end
|
56
|
-
redirect_to exporters_path, notice:
|
59
|
+
redirect_to exporters_path, notice: message
|
57
60
|
else
|
58
61
|
render :new
|
59
62
|
end
|
@@ -63,8 +66,13 @@ module Bulkrax
|
|
63
66
|
def update
|
64
67
|
field_mapping_params
|
65
68
|
if @exporter.update(exporter_params)
|
66
|
-
|
67
|
-
|
69
|
+
if params[:commit] == 'Update and Re-Export All Items'
|
70
|
+
Bulkrax::ExporterJob.perform_later(@exporter.id)
|
71
|
+
message = 'Exporter was successfully updated. A download link will appear once it completes.'
|
72
|
+
else
|
73
|
+
'Exporter was successfully updated.'
|
74
|
+
end
|
75
|
+
redirect_to exporters_path, notice: message
|
68
76
|
else
|
69
77
|
render :edit
|
70
78
|
end
|
@@ -113,23 +113,9 @@ module Bulkrax
|
|
113
113
|
if @importer.update(importer_params)
|
114
114
|
files_for_import(file, cloud_files) unless file.nil? && cloud_files.nil?
|
115
115
|
# do not perform the import
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
elsif params[:commit] == 'Update and Harvest Updated Items'
|
120
|
-
Bulkrax::ImporterJob.perform_later(@importer.id, true)
|
121
|
-
elsif params[:commit] == 'Update Metadata and Files'
|
122
|
-
@importer.parser_fields['update_files'] = true
|
123
|
-
@importer.save
|
124
|
-
Bulkrax::ImporterJob.perform_later(@importer.id)
|
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 Files' || 'Update and Re-Harvest All Items')
|
127
|
-
@importer.parser_fields['replace_files'] = true
|
128
|
-
@importer.save
|
129
|
-
Bulkrax::ImporterJob.perform_later(@importer.id)
|
130
|
-
# In all other cases, perform a metadata-only re-import
|
131
|
-
else
|
132
|
-
Bulkrax::ImporterJob.perform_later(@importer.id)
|
116
|
+
unless params[:commit] == 'Update Importer'
|
117
|
+
set_files_parser_fields
|
118
|
+
Bulkrax::ImporterJob.send(@importer.parser.perform_method, @importer.id, update_harvest)
|
133
119
|
end
|
134
120
|
if api_request?
|
135
121
|
json_response('updated', :ok, 'Importer was successfully updated.')
|
@@ -310,6 +296,25 @@ module Bulkrax
|
|
310
296
|
redirect_to path, notice: message
|
311
297
|
end
|
312
298
|
end
|
299
|
+
|
300
|
+
# update methods (for commit deciphering)
|
301
|
+
def update_harvest
|
302
|
+
# OAI-only - selective re-harvest
|
303
|
+
params[:commit] == 'Update and Harvest Updated Items'
|
304
|
+
end
|
305
|
+
|
306
|
+
def set_files_parser_fields
|
307
|
+
if params[:commit] == 'Update Metadata and Files'
|
308
|
+
@importer.parser_fields['update_files'] = true
|
309
|
+
elsif params[:commit] == ('Update and Replace Files' || 'Update and Re-Harvest All Items')
|
310
|
+
@importer.parser_fields['replace_files'] = true
|
311
|
+
elsif params[:commit] == 'Update and Harvest Updated Items'
|
312
|
+
return
|
313
|
+
else
|
314
|
+
@importer.parser_fields['metadata_only'] = true
|
315
|
+
end
|
316
|
+
@importer.save
|
317
|
+
end
|
313
318
|
end
|
314
319
|
# rubocop:enable Metrics/ClassLength
|
315
320
|
end
|
@@ -5,15 +5,20 @@ module Bulkrax
|
|
5
5
|
extend ActiveModel::Callbacks
|
6
6
|
include Bulkrax::FileFactory
|
7
7
|
define_model_callbacks :save, :create
|
8
|
-
attr_reader :attributes, :object, :source_identifier_value, :klass, :replace_files, :update_files, :work_identifier
|
8
|
+
attr_reader :attributes, :object, :source_identifier_value, :klass, :replace_files, :update_files, :work_identifier, :collection_field_mapping
|
9
9
|
|
10
10
|
# rubocop:disable Metrics/ParameterLists
|
11
|
-
def initialize(attributes:, source_identifier_value:, work_identifier:, replace_files: false, user: nil, klass: nil, update_files: false)
|
11
|
+
def initialize(attributes:, source_identifier_value:, work_identifier:, collection_field_mapping:, replace_files: false, user: nil, klass: nil, update_files: false)
|
12
|
+
ActiveSupport::Deprecation.warn(
|
13
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
14
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
15
|
+
)
|
12
16
|
@attributes = ActiveSupport::HashWithIndifferentAccess.new(attributes)
|
13
17
|
@replace_files = replace_files
|
14
18
|
@update_files = update_files
|
15
19
|
@user = user || User.batch_user
|
16
20
|
@work_identifier = work_identifier
|
21
|
+
@collection_field_mapping = collection_field_mapping
|
17
22
|
@source_identifier_value = source_identifier_value
|
18
23
|
@klass = klass || Bulkrax.default_work_type.constantize
|
19
24
|
end
|
@@ -41,6 +46,7 @@ module Bulkrax
|
|
41
46
|
self.run
|
42
47
|
# Create the error exception if the object is not validly saved for some reason
|
43
48
|
raise ActiveFedora::RecordInvalid, object if !object.persisted? || object.changed?
|
49
|
+
object
|
44
50
|
end
|
45
51
|
|
46
52
|
def update
|
@@ -54,7 +60,7 @@ module Bulkrax
|
|
54
60
|
end
|
55
61
|
|
56
62
|
def find
|
57
|
-
return find_by_id if attributes[:id]
|
63
|
+
return find_by_id if attributes[:id].present?
|
58
64
|
return search_by_identifier if attributes[work_identifier].present?
|
59
65
|
end
|
60
66
|
|
@@ -121,52 +127,33 @@ module Bulkrax
|
|
121
127
|
end
|
122
128
|
|
123
129
|
def create_collection(attrs)
|
130
|
+
ActiveSupport::Deprecation.warn(
|
131
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
132
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
133
|
+
)
|
124
134
|
attrs = collection_type(attrs)
|
125
|
-
object
|
126
|
-
object
|
135
|
+
persist_collection_memberships(parent: object, child: find_collection(attributes[:child_collection_id])) if attributes[:child_collection_id].present?
|
136
|
+
persist_collection_memberships(parent: find_collection(attributes[collection_field_mapping]), child: object) if attributes[collection_field_mapping].present?
|
127
137
|
object.attributes = attrs
|
128
138
|
object.apply_depositor_metadata(@user)
|
129
139
|
object.save!
|
130
140
|
end
|
131
141
|
|
132
142
|
def update_collection(attrs)
|
133
|
-
|
134
|
-
|
143
|
+
ActiveSupport::Deprecation.warn(
|
144
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
145
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
146
|
+
)
|
147
|
+
persist_collection_memberships(parent: object, child: find_collection(attributes[:child_collection_id])) if attributes[:child_collection_id].present?
|
148
|
+
persist_collection_memberships(parent: find_collection(attributes[collection_field_mapping]), child: object) if attributes[collection_field_mapping].present?
|
135
149
|
object.attributes = attrs
|
136
150
|
object.save!
|
137
151
|
end
|
138
152
|
|
139
|
-
#
|
140
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
# and collections [{ id: collection_id }]
|
144
|
-
# member_ids comes from
|
145
|
-
# @todo - consider performance implications although we wouldn't expect a Collection to be a member of many Collections
|
146
|
-
def members
|
147
|
-
ms = object.members.to_a
|
148
|
-
[:children].each do |atat|
|
149
|
-
next if attributes[atat].blank?
|
150
|
-
ms.concat(
|
151
|
-
Array.wrap(
|
152
|
-
find_collection(attributes[atat])
|
153
|
-
)
|
154
|
-
)
|
155
|
-
end
|
156
|
-
ms.flatten.compact.uniq
|
157
|
-
end
|
158
|
-
|
159
|
-
def member_of_collections
|
160
|
-
ms = object.member_of_collection_ids.to_a.map { |id| find_collection(id) }
|
161
|
-
[:collection, :collections].each do |atat|
|
162
|
-
next if attributes[atat].blank?
|
163
|
-
ms.concat(
|
164
|
-
Array.wrap(
|
165
|
-
find_collection(attributes[atat])
|
166
|
-
)
|
167
|
-
)
|
168
|
-
end
|
169
|
-
ms.flatten.compact.uniq
|
153
|
+
# Add child to parent's #member_collections
|
154
|
+
# Add parent to child's #member_of_collections
|
155
|
+
def persist_collection_memberships(parent:, child:)
|
156
|
+
::Hyrax::Collections::NestedCollectionPersistenceService.persist_nested_collection_for(parent: parent, child: child)
|
170
157
|
end
|
171
158
|
|
172
159
|
def find_collection(id)
|
@@ -192,32 +179,22 @@ module Bulkrax
|
|
192
179
|
# which is used by Hyrax::Actors::AddAsMemberOfCollectionsActor
|
193
180
|
def create_attributes
|
194
181
|
return transform_attributes if klass == Collection
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
201
|
-
transform_attributes.except(:collections).merge(member_of_collections_attributes: collection_ids)
|
202
|
-
else
|
203
|
-
transform_attributes
|
204
|
-
end
|
182
|
+
ActiveSupport::Deprecation.warn(
|
183
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
184
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
185
|
+
)
|
186
|
+
transform_attributes.except(:collections, :collection, collection_field_mapping)
|
205
187
|
end
|
206
188
|
|
207
189
|
# Strip out the :collection key, and add the member_of_collection_ids,
|
208
190
|
# which is used by Hyrax::Actors::AddAsMemberOfCollectionsActor
|
209
191
|
def attribute_update
|
210
192
|
return transform_attributes.except(:id) if klass == Collection
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
end
|
217
|
-
transform_attributes.except(:id).except(:collections).merge(member_of_collections_attributes: collection_ids)
|
218
|
-
else
|
219
|
-
transform_attributes.except(:id)
|
220
|
-
end
|
193
|
+
ActiveSupport::Deprecation.warn(
|
194
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
195
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
196
|
+
)
|
197
|
+
transform_attributes.except(:id, :collections, :collection, collection_field_mapping)
|
221
198
|
end
|
222
199
|
|
223
200
|
# Override if we need to map the attributes from the parser in
|
@@ -230,7 +207,7 @@ module Bulkrax
|
|
230
207
|
|
231
208
|
# Regardless of what the Parser gives us, these are the properties we are prepared to accept.
|
232
209
|
def permitted_attributes
|
233
|
-
klass.properties.keys.map(&:to_sym) + %i[id edit_users edit_groups read_groups visibility work_members_attributes admin_set_id]
|
210
|
+
klass.properties.keys.map(&:to_sym) + %i[id edit_users edit_groups read_groups visibility work_members_attributes admin_set_id member_of_collections_attributes]
|
234
211
|
end
|
235
212
|
end
|
236
213
|
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bulkrax
|
4
|
+
# Responsible for creating parent-child relationships between Works and Collections.
|
5
|
+
#
|
6
|
+
# Handles three kinds of relationships:
|
7
|
+
# - Work to Collection
|
8
|
+
# - Collection to Collection
|
9
|
+
# - Work to Work
|
10
|
+
#
|
11
|
+
# These can be established from either side of the relationship (i.e. from parent to child or from child to parent).
|
12
|
+
# This job only creates one relationship at a time. If a record needs multiple parents or children or both, individual
|
13
|
+
# jobs should be run for each of those relationships.
|
14
|
+
#
|
15
|
+
# NOTE: In the context of this job, "record" is used to generically refer
|
16
|
+
# to either an instance of a Work or an instance of a Collection.
|
17
|
+
# NOTE: In the context of this job, "identifier" is used to generically refer
|
18
|
+
# to either a record's ID or an Bulkrax::Entry's source_identifier.
|
19
|
+
class CreateRelationshipsJob < ApplicationJob
|
20
|
+
queue_as :import
|
21
|
+
|
22
|
+
attr_accessor :base_entry, :child_record, :parent_record, :importer_run
|
23
|
+
|
24
|
+
# @param entry_identifier [String] source_identifier of the base Bulkrax::Entry the job was triggered from (see #build_for_importer)
|
25
|
+
# @param parent_identifier [String] Work/Collection ID or Bulkrax::Entry source_identifier
|
26
|
+
# @param child_identifier [String] Work/Collection ID or Bulkrax::Entry source_identifier
|
27
|
+
# @param importer_run [Bulkrax::ImporterRun] current importer run (needed to properly update counters)
|
28
|
+
#
|
29
|
+
# The entry_identifier is used to lookup the @base_entry for the job (a.k.a. the entry the job was called from).
|
30
|
+
# The @base_entry defines the context of the relationship (e.g. "this entry (@base_entry) should have a parent").
|
31
|
+
# Whether the @base_entry is the parent or the child in the relationship is determined by the presence of a
|
32
|
+
# parent_identifier or child_identifier param. For example, if a parent_identifier is passed, we know @base_entry
|
33
|
+
# is the child in the relationship, and vice versa if a child_identifier is passed.
|
34
|
+
def perform(entry_identifier:, parent_identifier: nil, child_identifier: nil, importer_run:)
|
35
|
+
@base_entry = Entry.find_by(identifier: entry_identifier)
|
36
|
+
@importer_run = importer_run
|
37
|
+
if parent_identifier.present?
|
38
|
+
@child_record = find_record(entry_identifier)
|
39
|
+
@parent_record = find_record(parent_identifier)
|
40
|
+
elsif child_identifier.present?
|
41
|
+
@parent_record = find_record(entry_identifier)
|
42
|
+
@child_record = find_record(child_identifier)
|
43
|
+
else
|
44
|
+
raise ::StandardError, %("#{entry_identifier}" needs either a child or a parent to create a relationship)
|
45
|
+
end
|
46
|
+
|
47
|
+
if @child_record.blank? || @parent_record.blank?
|
48
|
+
reschedule(
|
49
|
+
entry_identifier: entry_identifier,
|
50
|
+
parent_identifier: parent_identifier,
|
51
|
+
child_identifier: child_identifier,
|
52
|
+
importer_run: importer_run
|
53
|
+
)
|
54
|
+
return false # stop current job from continuing to run after rescheduling
|
55
|
+
end
|
56
|
+
|
57
|
+
create_relationship
|
58
|
+
rescue ::StandardError => e
|
59
|
+
base_entry.status_info(e)
|
60
|
+
importer_run.increment!(:failed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def create_relationship
|
66
|
+
if parent_record.is_a?(::Collection) && child_record.is_a?(::Collection)
|
67
|
+
collection_parent_collection_child
|
68
|
+
elsif parent_record.is_a?(::Collection) && curation_concern?(child_record)
|
69
|
+
collection_parent_work_child
|
70
|
+
elsif curation_concern?(parent_record) && child_record.is_a?(::Collection)
|
71
|
+
raise ::StandardError, 'a Collection may not be assigned as a child of a Work'
|
72
|
+
else
|
73
|
+
work_parent_work_child
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# This method allows us to create relationships with preexisting records (by their ID) OR
|
78
|
+
# with records that are concurrently being imported (by their Bulkrax::Entry source_identifier).
|
79
|
+
#
|
80
|
+
# @param identifier [String] Work/Collection ID or Bulkrax::Entry source_identifier
|
81
|
+
# @return [Work, Collection, nil] Work or Collection if found, otherwise nil
|
82
|
+
def find_record(identifier)
|
83
|
+
record = Entry.find_by(identifier: identifier)
|
84
|
+
record ||= ::Collection.where(id: identifier).first
|
85
|
+
if record.blank?
|
86
|
+
available_work_types.each do |work_type|
|
87
|
+
record ||= work_type.where(id: identifier).first
|
88
|
+
end
|
89
|
+
end
|
90
|
+
record = record.factory.find if record.is_a?(Entry)
|
91
|
+
|
92
|
+
record
|
93
|
+
end
|
94
|
+
|
95
|
+
# Check if the record is a Work
|
96
|
+
def curation_concern?(record)
|
97
|
+
available_work_types.include?(record.class)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Array<Class>] list of work type classes
|
101
|
+
def available_work_types
|
102
|
+
# If running in a Hyku app, do not reference disabled work types
|
103
|
+
@available_work_types ||= if defined?(::Hyku)
|
104
|
+
::Site.instance.available_works.map(&:constantize)
|
105
|
+
else
|
106
|
+
::Hyrax.config.curation_concerns
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def user
|
111
|
+
@user ||= importer_run.importer.user
|
112
|
+
end
|
113
|
+
|
114
|
+
# Work-Collection membership is added to the child as member_of_collection_ids
|
115
|
+
# This is adding the reverse relationship, from the child to the parent
|
116
|
+
def collection_parent_work_child
|
117
|
+
ActiveSupport::Deprecation.warn(
|
118
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
119
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
120
|
+
)
|
121
|
+
attrs = { id: child_record.id, member_of_collections_attributes: { 0 => { id: parent_record.id } } }
|
122
|
+
ObjectFactory.new(
|
123
|
+
attributes: attrs,
|
124
|
+
source_identifier_value: nil, # sending the :id in the attrs means the factory doesn't need a :source_identifier_value
|
125
|
+
work_identifier: base_entry.parser.work_identifier,
|
126
|
+
collection_field_mapping: base_entry.parser.collection_field_mapping,
|
127
|
+
replace_files: false,
|
128
|
+
user: user,
|
129
|
+
klass: child_record.class
|
130
|
+
).run
|
131
|
+
# TODO: add counters for :processed_parents and :failed_parents
|
132
|
+
importer_run.increment!(:processed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
133
|
+
end
|
134
|
+
|
135
|
+
# Collection-Collection membership is added to the as member_ids
|
136
|
+
def collection_parent_collection_child
|
137
|
+
ActiveSupport::Deprecation.warn(
|
138
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
139
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
140
|
+
)
|
141
|
+
attrs = { id: parent_record.id, child_collection_id: child_record.id }
|
142
|
+
ObjectFactory.new(
|
143
|
+
attributes: attrs,
|
144
|
+
source_identifier_value: nil, # sending the :id in the attrs means the factory doesn't need a :source_identifier_value
|
145
|
+
work_identifier: base_entry.parser.work_identifier,
|
146
|
+
collection_field_mapping: base_entry.parser.collection_field_mapping,
|
147
|
+
replace_files: false,
|
148
|
+
user: user,
|
149
|
+
klass: parent_record.class
|
150
|
+
).run
|
151
|
+
# TODO: add counters for :processed_parents and :failed_parents
|
152
|
+
importer_run.increment!(:processed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
153
|
+
end
|
154
|
+
|
155
|
+
# Work-Work membership is added to the parent as member_ids
|
156
|
+
def work_parent_work_child
|
157
|
+
ActiveSupport::Deprecation.warn(
|
158
|
+
'Creating Collections using the collection_field_mapping will no longer be supported as of Bulkrax version 3.0.' \
|
159
|
+
' Please configure Bulkrax to use related_parents_field_mapping and related_children_field_mapping instead.'
|
160
|
+
)
|
161
|
+
attrs = {
|
162
|
+
id: parent_record.id,
|
163
|
+
work_members_attributes: { 0 => { id: child_record.id } }
|
164
|
+
}
|
165
|
+
ObjectFactory.new(
|
166
|
+
attributes: attrs,
|
167
|
+
source_identifier_value: nil, # sending the :id in the attrs means the factory doesn't need a :source_identifier_value
|
168
|
+
work_identifier: base_entry.parser.work_identifier,
|
169
|
+
collection_field_mapping: base_entry.parser.collection_field_mapping,
|
170
|
+
replace_files: false,
|
171
|
+
user: user,
|
172
|
+
klass: parent_record.class
|
173
|
+
).run
|
174
|
+
# TODO: add counters for :processed_parents and :failed_parents
|
175
|
+
importer_run.increment!(:processed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
176
|
+
end
|
177
|
+
|
178
|
+
def reschedule(entry_identifier:, parent_identifier:, child_identifier:, importer_run:)
|
179
|
+
CreateRelationshipsJob.set(wait: 10.minutes).perform_later(
|
180
|
+
entry_identifier: entry_identifier,
|
181
|
+
parent_identifier: parent_identifier,
|
182
|
+
child_identifier: child_identifier,
|
183
|
+
importer_run: importer_run
|
184
|
+
)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -8,8 +8,12 @@ module Bulkrax
|
|
8
8
|
def perform(entry, importer_run)
|
9
9
|
work = entry.factory.find
|
10
10
|
work&.delete
|
11
|
-
importer_run.increment!(:deleted_records)
|
12
|
-
importer_run.decrement!(:enqueued_records)
|
11
|
+
ImporterRun.find(importer_run.id).increment!(:deleted_records)
|
12
|
+
ImporterRun.find(importer_run.id).decrement!(:enqueued_records)
|
13
|
+
entry.save!
|
14
|
+
entry.importer.current_run = ImporterRun.find(importer_run.id)
|
15
|
+
entry.importer.record_status
|
16
|
+
entry.status_info("Deleted", ImporterRun.find(importer_run.id))
|
13
17
|
end
|
14
18
|
# rubocop:enable Rails/SkipsModelValidations
|
15
19
|
end
|
@@ -26,12 +26,14 @@ module Bulkrax
|
|
26
26
|
# rubocop:enable Rails/SkipsModelValidations
|
27
27
|
end
|
28
28
|
exporter_run = ExporterRun.find(args[1])
|
29
|
-
return if exporter_run.enqueued_records.positive?
|
29
|
+
return entry if exporter_run.enqueued_records.positive?
|
30
30
|
if exporter_run.failed_records.positive?
|
31
31
|
exporter_run.exporter.status_info('Complete (with failures)')
|
32
32
|
else
|
33
33
|
exporter_run.exporter.status_info('Complete')
|
34
34
|
end
|
35
|
+
|
36
|
+
return entry
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Bulkrax
|
4
|
-
class
|
4
|
+
class ImportCollectionJob < ApplicationJob
|
5
5
|
queue_as :import
|
6
6
|
|
7
7
|
# rubocop:disable Rails/SkipsModelValidations
|
@@ -28,7 +28,7 @@ module Bulkrax
|
|
28
28
|
collection = entry.factory.find
|
29
29
|
permission_template = Hyrax::PermissionTemplate.find_or_create_by!(source_id: collection.id)
|
30
30
|
|
31
|
-
Hyrax::PermissionTemplateAccess.
|
31
|
+
Hyrax::PermissionTemplateAccess.find_or_create_by!(
|
32
32
|
permission_template_id: permission_template.id,
|
33
33
|
agent_id: user.user_key,
|
34
34
|
agent_type: 'user',
|
@@ -6,17 +6,32 @@ module Bulkrax
|
|
6
6
|
|
7
7
|
def perform(importer_id, only_updates_since_last_import = false)
|
8
8
|
importer = Importer.find(importer_id)
|
9
|
+
|
9
10
|
importer.current_run
|
11
|
+
unzip_imported_file(importer.parser)
|
10
12
|
import(importer, only_updates_since_last_import)
|
13
|
+
update_current_run_counters(importer)
|
11
14
|
schedule(importer) if importer.schedulable?
|
12
15
|
end
|
13
16
|
|
14
17
|
def import(importer, only_updates_since_last_import)
|
15
18
|
importer.only_updates = only_updates_since_last_import || false
|
16
19
|
return unless importer.valid_import?
|
20
|
+
|
17
21
|
importer.import_collections
|
18
22
|
importer.import_works
|
19
|
-
|
23
|
+
end
|
24
|
+
|
25
|
+
def unzip_imported_file(parser)
|
26
|
+
return unless parser.file? && parser.zip?
|
27
|
+
|
28
|
+
parser.unzip(parser.parser_fields['import_file_path'])
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_current_run_counters(importer)
|
32
|
+
importer.current_run.total_work_entries = importer.limit || importer.parser.works_total
|
33
|
+
importer.current_run.total_collection_entries = importer.parser.collections_total
|
34
|
+
importer.current_run.save!
|
20
35
|
end
|
21
36
|
|
22
37
|
def schedule(importer)
|
@@ -20,9 +20,9 @@ module Bulkrax
|
|
20
20
|
return unless content.send(self.if[0], Regexp.new(self.if[1]))
|
21
21
|
end
|
22
22
|
|
23
|
-
@result
|
24
|
-
@result.strip
|
25
|
-
process_split
|
23
|
+
# @result will evaluate to an empty string for nil content values
|
24
|
+
@result = content.to_s.gsub(/\s/, ' ').strip # remove any line feeds and tabs
|
25
|
+
process_split if @result.present?
|
26
26
|
@result = @result[0] if @result.is_a?(Array) && @result.size == 1
|
27
27
|
process_parse
|
28
28
|
return @result
|
@@ -66,14 +66,14 @@ module Bulkrax
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def parse_subject(src)
|
69
|
-
string = src.
|
69
|
+
string = src.strip.downcase
|
70
70
|
return if string.blank?
|
71
71
|
|
72
72
|
string.slice(0, 1).capitalize + string.slice(1..-1)
|
73
73
|
end
|
74
74
|
|
75
75
|
def parse_types(src)
|
76
|
-
src.
|
76
|
+
src.strip.titleize
|
77
77
|
end
|
78
78
|
|
79
79
|
# Allow for mapping a model field to the work type or collection
|
@@ -6,14 +6,16 @@ module Bulkrax
|
|
6
6
|
Collection
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
# Use identifier set by CsvParser#unique_collection_identifier, which falls back
|
10
|
+
# on the Collection's first title if record[source_identifier] is not present
|
11
|
+
def add_identifier
|
12
|
+
self.parsed_metadata[work_identifier] = self.identifier
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def add_collection_type_gid
|
16
|
+
return if self.parsed_metadata['collection_type_gid'].present?
|
17
|
+
|
18
|
+
self.parsed_metadata['collection_type_gid'] = ::Hyrax::CollectionType.find_or_create_default_collection_type.gid
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|