bulkrax 5.0.0 → 5.1.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/app/controllers/bulkrax/entries_controller.rb +4 -2
- data/app/controllers/bulkrax/exporters_controller.rb +13 -9
- data/app/controllers/bulkrax/importers_controller.rb +7 -6
- data/app/helpers/bulkrax/application_helper.rb +1 -1
- data/app/helpers/bulkrax/importers_helper.rb +2 -2
- data/app/jobs/bulkrax/create_relationships_job.rb +75 -59
- data/app/jobs/bulkrax/delete_job.rb +1 -1
- data/app/jobs/bulkrax/export_work_job.rb +2 -2
- data/app/jobs/bulkrax/import_file_set_job.rb +1 -1
- data/app/jobs/bulkrax/importer_job.rb +1 -1
- data/app/models/bulkrax/exporter.rb +15 -7
- data/app/models/bulkrax/importer.rb +4 -4
- data/app/models/bulkrax/importer_run.rb +6 -0
- data/app/models/bulkrax/oai_entry.rb +14 -2
- data/app/models/bulkrax/pending_relationship.rb +4 -0
- data/app/models/concerns/bulkrax/dynamic_record_lookup.rb +2 -0
- data/app/models/concerns/bulkrax/status_info.rb +9 -4
- data/app/parsers/bulkrax/bagit_parser.rb +1 -1
- data/app/views/bulkrax/exporters/_form.html.erb +33 -17
- data/app/views/bulkrax/exporters/edit.html.erb +1 -1
- data/app/views/bulkrax/exporters/new.html.erb +1 -1
- data/app/views/bulkrax/importers/_form.html.erb +5 -5
- data/lib/bulkrax/entry_spec_helper.rb +173 -0
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +6 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 490e0f170cc1128c00c467c3cc344db627d027a3b857d53dfa33b97805567d4b
|
4
|
+
data.tar.gz: 7290801bacea707b7398e674a17acf56e7a770cfb3bea20958169588a4404175
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6f5486405e2d2eb7f6c0c49b17ed0926e55a701368e42c93db9b009a5f663682ec4141fe1dd58d0dde132fa747010ada7cd22187b81d60a7e8b6b23cbf2e24d
|
7
|
+
data.tar.gz: d56a8780ef074d412ac7406d3f3ddb39b34b17bbe43c61a64bebe06f39952a1d62cbf2dbd01a7012bcd776686def03c5a5e6c556cc1384284c2dea8a89f3eec2
|
@@ -5,10 +5,10 @@ require_dependency "oai"
|
|
5
5
|
|
6
6
|
module Bulkrax
|
7
7
|
class EntriesController < ApplicationController
|
8
|
-
include Hyrax::ThemedLayoutController
|
8
|
+
include Hyrax::ThemedLayoutController if defined?(::Hyrax)
|
9
9
|
before_action :authenticate_user!
|
10
10
|
before_action :check_permissions
|
11
|
-
with_themed_layout 'dashboard'
|
11
|
+
with_themed_layout 'dashboard' if defined?(::Hyrax)
|
12
12
|
|
13
13
|
def show
|
14
14
|
if params[:importer_id].present?
|
@@ -23,6 +23,7 @@ module Bulkrax
|
|
23
23
|
@importer = Importer.find(params[:importer_id])
|
24
24
|
@entry = Entry.find(params[:id])
|
25
25
|
|
26
|
+
return unless defined?(::Hyrax)
|
26
27
|
add_breadcrumb t(:'hyrax.controls.home'), main_app.root_path
|
27
28
|
add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
|
28
29
|
add_breadcrumb 'Importers', bulkrax.importers_path
|
@@ -35,6 +36,7 @@ module Bulkrax
|
|
35
36
|
@exporter = Exporter.find(params[:exporter_id])
|
36
37
|
@entry = Entry.find(params[:id])
|
37
38
|
|
39
|
+
return unless defined?(::Hyrax)
|
38
40
|
add_breadcrumb t(:'hyrax.controls.home'), main_app.root_path
|
39
41
|
add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
|
40
42
|
add_breadcrumb 'Exporters', bulkrax.exporters_path
|
@@ -4,24 +4,26 @@ require_dependency "bulkrax/application_controller"
|
|
4
4
|
|
5
5
|
module Bulkrax
|
6
6
|
class ExportersController < ApplicationController
|
7
|
-
include Hyrax::ThemedLayoutController
|
7
|
+
include Hyrax::ThemedLayoutController if defined?(::Hyrax)
|
8
8
|
include Bulkrax::DownloadBehavior
|
9
9
|
before_action :authenticate_user!
|
10
10
|
before_action :check_permissions
|
11
11
|
before_action :set_exporter, only: [:show, :edit, :update, :destroy]
|
12
|
-
with_themed_layout 'dashboard'
|
12
|
+
with_themed_layout 'dashboard' if defined?(::Hyrax)
|
13
13
|
|
14
14
|
# GET /exporters
|
15
15
|
def index
|
16
16
|
@exporters = Exporter.all
|
17
17
|
|
18
|
-
add_exporter_breadcrumbs
|
18
|
+
add_exporter_breadcrumbs if defined?(::Hyrax)
|
19
19
|
end
|
20
20
|
|
21
21
|
# GET /exporters/1
|
22
22
|
def show
|
23
|
-
|
24
|
-
|
23
|
+
if defined?(::Hyrax)
|
24
|
+
add_exporter_breadcrumbs
|
25
|
+
add_breadcrumb @exporter.name
|
26
|
+
end
|
25
27
|
|
26
28
|
@work_entries = @exporter.entries.where(type: @exporter.parser.entry_class.to_s).page(params[:work_entries_page]).per(30)
|
27
29
|
@collection_entries = @exporter.entries.where(type: @exporter.parser.collection_entry_class.to_s).page(params[:collections_entries_page]).per(30)
|
@@ -31,16 +33,18 @@ module Bulkrax
|
|
31
33
|
# GET /exporters/new
|
32
34
|
def new
|
33
35
|
@exporter = Exporter.new
|
34
|
-
|
36
|
+
return unless defined?(::Hyrax)
|
35
37
|
add_exporter_breadcrumbs
|
36
38
|
add_breadcrumb 'New'
|
37
39
|
end
|
38
40
|
|
39
41
|
# GET /exporters/1/edit
|
40
42
|
def edit
|
41
|
-
|
42
|
-
|
43
|
-
|
43
|
+
if defined?(::Hyrax)
|
44
|
+
add_exporter_breadcrumbs
|
45
|
+
add_breadcrumb @exporter.name, bulkrax.exporter_path(@exporter.id)
|
46
|
+
add_breadcrumb 'Edit'
|
47
|
+
end
|
44
48
|
|
45
49
|
# Correctly populate export_source_collection input
|
46
50
|
@collection = Collection.find(@exporter.export_source) if @exporter.export_source.present? && @exporter.export_from == 'collection'
|
@@ -6,7 +6,7 @@ require_dependency 'oai'
|
|
6
6
|
module Bulkrax
|
7
7
|
# rubocop:disable Metrics/ClassLength
|
8
8
|
class ImportersController < ApplicationController
|
9
|
-
include Hyrax::ThemedLayoutController
|
9
|
+
include Hyrax::ThemedLayoutController if defined?(::Hyrax)
|
10
10
|
include Bulkrax::DownloadBehavior
|
11
11
|
include Bulkrax::API
|
12
12
|
include Bulkrax::ValidationHelper
|
@@ -16,14 +16,14 @@ module Bulkrax
|
|
16
16
|
before_action :authenticate_user!, unless: -> { api_request? }
|
17
17
|
before_action :check_permissions
|
18
18
|
before_action :set_importer, only: [:show, :edit, :update, :destroy]
|
19
|
-
with_themed_layout 'dashboard'
|
19
|
+
with_themed_layout 'dashboard' if defined?(::Hyrax)
|
20
20
|
|
21
21
|
# GET /importers
|
22
22
|
def index
|
23
23
|
@importers = Importer.all
|
24
24
|
if api_request?
|
25
25
|
json_response('index')
|
26
|
-
|
26
|
+
elsif defined?(::Hyrax)
|
27
27
|
add_importer_breadcrumbs
|
28
28
|
end
|
29
29
|
end
|
@@ -32,7 +32,7 @@ module Bulkrax
|
|
32
32
|
def show
|
33
33
|
if api_request?
|
34
34
|
json_response('show')
|
35
|
-
|
35
|
+
elsif defined?(::Hyrax)
|
36
36
|
add_importer_breadcrumbs
|
37
37
|
add_breadcrumb @importer.name
|
38
38
|
|
@@ -47,7 +47,7 @@ module Bulkrax
|
|
47
47
|
@importer = Importer.new
|
48
48
|
if api_request?
|
49
49
|
json_response('new')
|
50
|
-
|
50
|
+
elsif defined?(::Hyrax)
|
51
51
|
add_importer_breadcrumbs
|
52
52
|
add_breadcrumb 'New'
|
53
53
|
end
|
@@ -57,7 +57,7 @@ module Bulkrax
|
|
57
57
|
def edit
|
58
58
|
if api_request?
|
59
59
|
json_response('edit')
|
60
|
-
|
60
|
+
elsif defined?(::Hyrax)
|
61
61
|
add_importer_breadcrumbs
|
62
62
|
add_breadcrumb @importer.name, bulkrax.importer_path(@importer.id)
|
63
63
|
add_breadcrumb 'Edit'
|
@@ -159,6 +159,7 @@ module Bulkrax
|
|
159
159
|
# GET /importer/1/upload_corrected_entries
|
160
160
|
def upload_corrected_entries
|
161
161
|
@importer = Importer.find(params[:importer_id])
|
162
|
+
return unless defined?(::Hyrax)
|
162
163
|
add_breadcrumb t(:'hyrax.controls.home'), main_app.root_path
|
163
164
|
add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
|
164
165
|
add_breadcrumb 'Importers', bulkrax.importers_path
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module Bulkrax
|
4
4
|
module ImportersHelper
|
5
|
-
#
|
5
|
+
# borrowed from batch-importer https://github.com/samvera-labs/hyrax-batch_ingest/blob/main/app/controllers/hyrax/batch_ingest/batches_controller.rb
|
6
6
|
def available_admin_sets
|
7
|
-
# Restrict available_admin_sets to only those current user can
|
7
|
+
# Restrict available_admin_sets to only those current user can deposit to.
|
8
8
|
@available_admin_sets ||= Hyrax::Collections::PermissionsService.source_ids_for_deposit(ability: current_ability, source_type: 'admin_set').map do |admin_set_id|
|
9
9
|
[AdminSet.find(admin_set_id).title.first, admin_set_id]
|
10
10
|
end
|
@@ -17,12 +17,29 @@ module Bulkrax
|
|
17
17
|
# NOTE: In the context of this job, "identifier" is used to generically refer
|
18
18
|
# to either a record's ID or an Bulkrax::Entry's source_identifier.
|
19
19
|
class CreateRelationshipsJob < ApplicationJob
|
20
|
+
##
|
21
|
+
# @api public
|
22
|
+
# @since v5.0.1
|
23
|
+
#
|
24
|
+
# Once we've created the relationships, should we then index the works's file_sets to ensure
|
25
|
+
# that we have the proper indexed values. This can help set things like `is_page_of_ssim` for
|
26
|
+
# IIIF manifest and search results of file sets.
|
27
|
+
#
|
28
|
+
# @note As of v5.0.1 the default behavior is to not perform this. That preserves past
|
29
|
+
# implementations. However, we might determine that we want to change the default
|
30
|
+
# behavior. Which would likely mean a major version change.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# # In config/initializers/bulkrax.rb
|
34
|
+
# Bulkrax::CreateRelationshipsJob.update_child_records_works_file_sets = true
|
35
|
+
#
|
36
|
+
# @see https://github.com/scientist-softserv/louisville-hyku/commit/128a9ef
|
37
|
+
class_attribute :update_child_records_works_file_sets, default: false
|
38
|
+
|
20
39
|
include DynamicRecordLookup
|
21
40
|
|
22
41
|
queue_as :import
|
23
42
|
|
24
|
-
attr_accessor :child_records, :child_entry, :parent_record, :parent_entry, :importer_run_id
|
25
|
-
|
26
43
|
# @param parent_identifier [String] Work/Collection ID or Bulkrax::Entry source_identifiers
|
27
44
|
# @param importer_run [Bulkrax::ImporterRun] current importer run (needed to properly update counters)
|
28
45
|
#
|
@@ -31,82 +48,81 @@ module Bulkrax
|
|
31
48
|
# Whether the @base_entry is the parent or the child in the relationship is determined by the presence of a
|
32
49
|
# parent_identifier or child_identifier param. For example, if a parent_identifier is passed, we know @base_entry
|
33
50
|
# is the child in the relationship, and vice versa if a child_identifier is passed.
|
51
|
+
#
|
52
|
+
# rubocop:disable Metrics/MethodLength
|
34
53
|
def perform(parent_identifier:, importer_run_id:) # rubocop:disable Metrics/AbcSize
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
54
|
+
importer_run = Bulkrax::ImporterRun.find(importer_run_id)
|
55
|
+
ability = Ability.new(importer_run.user)
|
56
|
+
|
57
|
+
parent_entry, parent_record = find_record(parent_identifier, importer_run_id)
|
58
|
+
|
59
|
+
number_of_successes = 0
|
60
|
+
number_of_failures = 0
|
61
|
+
errors = []
|
62
|
+
|
63
|
+
ActiveRecord::Base.uncached do
|
64
|
+
Bulkrax::PendingRelationship.where(parent_id: parent_identifier, importer_run_id: importer_run_id)
|
65
|
+
.ordered.find_each do |rel|
|
66
|
+
process(relationship: rel, importer_run_id: importer_run_id, parent_record: parent_record, ability: ability)
|
67
|
+
number_of_successes += 1
|
68
|
+
rescue => e
|
69
|
+
number_of_failures += 1
|
70
|
+
errors << e
|
47
71
|
end
|
48
72
|
end
|
49
73
|
|
50
|
-
|
74
|
+
# save record if members were added
|
75
|
+
parent_record.save! if @parent_record_members_added
|
76
|
+
|
77
|
+
# rubocop:disable Rails/SkipsModelValidations
|
78
|
+
if errors.present?
|
79
|
+
importer_run.increment!(:failed_relationships, number_of_failures)
|
80
|
+
parent_entry&.set_status_info(errors.last, importer_run)
|
81
|
+
|
82
|
+
# TODO: This can create an infinite job cycle, consider a time to live tracker.
|
51
83
|
reschedule({ parent_identifier: parent_identifier, importer_run_id: importer_run_id })
|
52
84
|
return false # stop current job from continuing to run after rescheduling
|
85
|
+
else
|
86
|
+
Bulkrax::ImporterRun.find(importer_run_id).increment!(:processed_relationships, number_of_successes)
|
53
87
|
end
|
54
|
-
|
55
|
-
importerexporter_id: ImporterRun.find(importer_run_id).importer_id,
|
56
|
-
importerexporter_type: "Bulkrax::Importer").first
|
57
|
-
create_relationships
|
58
|
-
pending_relationships.each(&:destroy)
|
59
|
-
rescue ::StandardError => e
|
60
|
-
parent_entry ? parent_entry.status_info(e) : child_entry.status_info(e)
|
61
|
-
Bulkrax::ImporterRun.find(importer_run_id).increment!(:failed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
88
|
+
# rubocop:enable Rails/SkipsModelValidations
|
62
89
|
end
|
90
|
+
# rubocop:enable Metrics/MethodLength
|
63
91
|
|
64
92
|
private
|
65
93
|
|
66
|
-
def
|
67
|
-
if
|
68
|
-
|
69
|
-
collection_parent_collection_child unless child_records[:collections].empty?
|
70
|
-
else
|
71
|
-
work_parent_work_child unless child_records[:works].empty?
|
72
|
-
raise ::StandardError, 'a Collection may not be assigned as a child of a Work' if child_records[:collections].present?
|
73
|
-
end
|
74
|
-
end
|
94
|
+
def process(relationship:, importer_run_id:, parent_record:, ability:)
|
95
|
+
raise "#{relationship} needs a child to create relationship" if relationship.child_id.nil?
|
96
|
+
raise "#{relationship} needs a parent to create relationship" if relationship.parent_id.nil?
|
75
97
|
|
76
|
-
|
77
|
-
|
78
|
-
end
|
98
|
+
_child_entry, child_record = find_record(relationship.child_id, importer_run_id)
|
99
|
+
raise "#{relationship} could not find child record" unless child_record
|
79
100
|
|
80
|
-
|
81
|
-
# This is adding the reverse relationship, from the child to the parent
|
82
|
-
def collection_parent_work_child
|
83
|
-
child_work_ids = child_records[:works].map(&:id)
|
84
|
-
parent_record.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX)
|
101
|
+
raise "Cannot add child collection (ID=#{relationship.child_id}) to parent work (ID=#{relationship.parent_id})" if child_record.collection? && parent_record.work?
|
85
102
|
|
86
|
-
|
87
|
-
|
103
|
+
ability.authorize!(:edit, child_record)
|
104
|
+
|
105
|
+
# We could do this outside of the loop, but that could lead to odd counter failures.
|
106
|
+
ability.authorize!(:edit, parent_record)
|
107
|
+
|
108
|
+
parent_record.is_a?(Collection) ? add_to_collection(child_record, parent_record) : add_to_work(child_record, parent_record)
|
109
|
+
|
110
|
+
child_record.file_sets.each(&:update_index) if update_child_records_works_file_sets? && child_record.respond_to?(:file_sets)
|
111
|
+
relationship.destroy
|
88
112
|
end
|
89
113
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
::Hyrax::Collections::NestedCollectionPersistenceService.persist_nested_collection_for(parent: parent_record, child: child_record)
|
94
|
-
ImporterRun.find(importer_run_id).increment!(:processed_relationships) # rubocop:disable Rails/SkipsModelValidations
|
95
|
-
end
|
114
|
+
def add_to_collection(child_record, parent_record)
|
115
|
+
child_record.member_of_collections << parent_record
|
116
|
+
child_record.save!
|
96
117
|
end
|
97
118
|
|
98
|
-
|
99
|
-
|
100
|
-
records_hash = {}
|
101
|
-
child_records[:works].each_with_index do |child_record, i|
|
102
|
-
records_hash[i] = { id: child_record.id }
|
103
|
-
end
|
104
|
-
attrs = { work_members_attributes: records_hash }
|
105
|
-
parent_record.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX)
|
106
|
-
env = Hyrax::Actors::Environment.new(parent_record, Ability.new(user), attrs)
|
119
|
+
def add_to_work(child_record, parent_record)
|
120
|
+
return true if parent_record.ordered_members.to_a.include?(child_record)
|
107
121
|
|
108
|
-
|
109
|
-
|
122
|
+
parent_record.ordered_members << child_record
|
123
|
+
@parent_record_members_added = true
|
124
|
+
# TODO: Do we need to save the child record?
|
125
|
+
child_record.save!
|
110
126
|
end
|
111
127
|
|
112
128
|
def reschedule(parent_identifier:, importer_run_id:)
|
@@ -13,7 +13,7 @@ module Bulkrax
|
|
13
13
|
entry.save!
|
14
14
|
entry.importer.current_run = ImporterRun.find(importer_run.id)
|
15
15
|
entry.importer.record_status
|
16
|
-
entry.
|
16
|
+
entry.set_status_info("Deleted", ImporterRun.find(importer_run.id))
|
17
17
|
end
|
18
18
|
# rubocop:enable Rails/SkipsModelValidations
|
19
19
|
end
|
@@ -29,9 +29,9 @@ module Bulkrax
|
|
29
29
|
return entry if exporter_run.enqueued_records.positive?
|
30
30
|
|
31
31
|
if exporter_run.failed_records.positive?
|
32
|
-
exporter_run.exporter.
|
32
|
+
exporter_run.exporter.set_status_info('Complete (with failures)')
|
33
33
|
else
|
34
|
-
exporter_run.exporter.
|
34
|
+
exporter_run.exporter.set_status_info('Complete')
|
35
35
|
end
|
36
36
|
|
37
37
|
return entry
|
@@ -41,7 +41,7 @@ module Bulkrax
|
|
41
41
|
ImportFileSetJob.set(wait: (entry.import_attempts + 1).minutes).perform_later(entry_id, importer_run_id)
|
42
42
|
else
|
43
43
|
ImporterRun.find(importer_run_id).decrement!(:enqueued_records) # rubocop:disable Rails/SkipsModelValidations
|
44
|
-
entry.
|
44
|
+
entry.set_status_info(e)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -13,7 +13,7 @@ module Bulkrax
|
|
13
13
|
update_current_run_counters(importer)
|
14
14
|
schedule(importer) if importer.schedulable?
|
15
15
|
rescue CSV::MalformedCSVError => e
|
16
|
-
importer.
|
16
|
+
importer.set_status_info(e)
|
17
17
|
end
|
18
18
|
|
19
19
|
def import(importer, only_updates_since_last_import)
|
@@ -69,7 +69,7 @@ module Bulkrax
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def workflow_status_list
|
72
|
-
Sipity::WorkflowState.all.map { |s| [s.name&.titleize, s.name] }.uniq
|
72
|
+
Sipity::WorkflowState.all.map { |s| [s.name&.titleize, s.name] }.uniq if defined?(::Hyrax)
|
73
73
|
end
|
74
74
|
|
75
75
|
# If field_mapping is empty, setup a default based on the export_properties
|
@@ -84,12 +84,20 @@ module Bulkrax
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def export_from_list
|
87
|
-
|
88
|
-
[
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
87
|
+
if defined?(::Hyrax)
|
88
|
+
[
|
89
|
+
[I18n.t('bulkrax.exporter.labels.importer'), 'importer'],
|
90
|
+
[I18n.t('bulkrax.exporter.labels.collection'), 'collection'],
|
91
|
+
[I18n.t('bulkrax.exporter.labels.worktype'), 'worktype'],
|
92
|
+
[I18n.t('bulkrax.exporter.labels.all'), 'all']
|
93
|
+
]
|
94
|
+
else
|
95
|
+
[
|
96
|
+
[I18n.t('bulkrax.exporter.labels.importer'), 'importer'],
|
97
|
+
[I18n.t('bulkrax.exporter.labels.collection'), 'collection'],
|
98
|
+
[I18n.t('bulkrax.exporter.labels.all'), 'all']
|
99
|
+
]
|
100
|
+
end
|
93
101
|
end
|
94
102
|
|
95
103
|
def export_type_list
|
@@ -15,7 +15,7 @@ module Bulkrax
|
|
15
15
|
has_many :entries, as: :importerexporter, dependent: :destroy
|
16
16
|
|
17
17
|
validates :name, presence: true
|
18
|
-
validates :admin_set_id, presence: true
|
18
|
+
validates :admin_set_id, presence: true if defined?(::Hyrax)
|
19
19
|
validates :parser_klass, presence: true
|
20
20
|
|
21
21
|
delegate :valid_import?, :write_errored_entries_file, :visibility, to: :parser
|
@@ -47,12 +47,12 @@ module Bulkrax
|
|
47
47
|
if importer_run.failed_records.positive?
|
48
48
|
if importer_run.invalid_records.present?
|
49
49
|
e = Bulkrax::ImportFailed.new('Failed with Invalid Records', importer_run.invalid_records.split("\n"))
|
50
|
-
importer_run.importer.
|
50
|
+
importer_run.importer.set_status_info(e)
|
51
51
|
else
|
52
|
-
importer_run.importer.
|
52
|
+
importer_run.importer.set_status_info('Complete (with failures)')
|
53
53
|
end
|
54
54
|
else
|
55
|
-
importer_run.importer.
|
55
|
+
importer_run.importer.set_status_info('Complete')
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -9,5 +9,11 @@ module Bulkrax
|
|
9
9
|
def parents
|
10
10
|
pending_relationships.pluck(:parent_id).uniq
|
11
11
|
end
|
12
|
+
|
13
|
+
def user
|
14
|
+
# An importer might not have a user, the CLI ingest need not assign a user. As such, we
|
15
|
+
# fallback to the configured user.
|
16
|
+
importer.user || Bulkrax.fallback_user_for_importer_exporter_processing
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
@@ -9,6 +9,15 @@ module Bulkrax
|
|
9
9
|
|
10
10
|
delegate :record, to: :raw_record
|
11
11
|
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
# Included to assist in testing; namely so that you can copy down an OAI entry, store it locally,
|
15
|
+
# and then manually construct an {OAI::GetRecordResponse}.
|
16
|
+
#
|
17
|
+
# @see Bulkrax::EntrySpecHelper.oai_entry_for
|
18
|
+
attr_writer :raw_record
|
19
|
+
|
20
|
+
# @return [OAI::GetRecordResponse]
|
12
21
|
def raw_record
|
13
22
|
@raw_record ||= client.get_record(identifier: identifier, metadata_prefix: parser.parser_fields['metadata_prefix'])
|
14
23
|
end
|
@@ -28,7 +37,7 @@ module Bulkrax
|
|
28
37
|
def build_metadata
|
29
38
|
self.parsed_metadata = {}
|
30
39
|
self.parsed_metadata[work_identifier] = [record.header.identifier]
|
31
|
-
self.raw_metadata = {
|
40
|
+
self.raw_metadata = { record: record.metadata.to_s, header: record.header.to_s }
|
32
41
|
|
33
42
|
# We need to establish the #factory_class before we proceed with the metadata. See
|
34
43
|
# https://github.com/samvera-labs/bulkrax/issues/702 for further details.
|
@@ -91,7 +100,8 @@ module Bulkrax
|
|
91
100
|
# If OAI-PMH doesn't return setSpec in the headers for GetRecord, use parser.collection_name
|
92
101
|
# in this case, if 'All' is selected, records will not be added to a collection.
|
93
102
|
def find_collection_ids
|
94
|
-
return self.collection_ids if
|
103
|
+
return self.collection_ids if defined?(@called_find_collection_ids)
|
104
|
+
|
95
105
|
if sets.blank? || parser.collection_name != 'all'
|
96
106
|
collection = find_collection(importerexporter.unique_collection_identifier(parser.collection_name))
|
97
107
|
self.collection_ids << collection.id if collection.present? && !self.collection_ids.include?(collection.id)
|
@@ -101,6 +111,8 @@ module Bulkrax
|
|
101
111
|
self.collection_ids << c.id if c.present? && !self.collection_ids.include?(c.id)
|
102
112
|
end
|
103
113
|
end
|
114
|
+
|
115
|
+
@called_find_collection_ids = true
|
104
116
|
return self.collection_ids
|
105
117
|
end
|
106
118
|
end
|
@@ -3,5 +3,9 @@
|
|
3
3
|
module Bulkrax
|
4
4
|
class PendingRelationship < ApplicationRecord
|
5
5
|
belongs_to :importer_run
|
6
|
+
|
7
|
+
# Ideally we wouldn't have a column named "order", as it is a reserved SQL term. However, if we
|
8
|
+
# quote the column, all is well...for the application.
|
9
|
+
scope :ordered, -> { order("#{quoted_table_name}.#{connection.quote_column_name('order')}") }
|
6
10
|
end
|
7
11
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Bulkrax
|
4
|
+
# TODO: Extract methods to class methods; there's no reason for these methods to be a mixin.
|
5
|
+
# TODO: Add specs to test in isolation
|
4
6
|
module DynamicRecordLookup
|
5
7
|
# Search entries, collections, and every available work type for a record that
|
6
8
|
# has the provided identifier.
|
@@ -33,16 +33,21 @@ module Bulkrax
|
|
33
33
|
current_status&.created_at
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def set_status_info(e = nil, current_run = nil)
|
37
|
+
runnable = current_run || last_run
|
37
38
|
if e.nil?
|
38
|
-
self.statuses.create!(status_message: 'Complete', runnable:
|
39
|
+
self.statuses.create!(status_message: 'Complete', runnable: runnable)
|
39
40
|
elsif e.is_a?(String)
|
40
|
-
self.statuses.create!(status_message: e, runnable:
|
41
|
+
self.statuses.create!(status_message: e, runnable: runnable)
|
41
42
|
else
|
42
|
-
self.statuses.create!(status_message: 'Failed', runnable:
|
43
|
+
self.statuses.create!(status_message: 'Failed', runnable: runnable, error_class: e.class.to_s, error_message: e.message, error_backtrace: e.backtrace)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
47
|
+
alias status_info set_status_info
|
48
|
+
|
49
|
+
deprecation_deprecate status_info: "Favor Bulkrax::StatusInfo.set_status_info. We will be removing .status_info in Bulkrax v6.0.0"
|
50
|
+
|
46
51
|
# api compatible with previous error structure
|
47
52
|
def last_error
|
48
53
|
return unless current_status && current_status.error_class.present?
|
@@ -11,7 +11,7 @@
|
|
11
11
|
</div>
|
12
12
|
<% end %>
|
13
13
|
|
14
|
-
<%= form.input :name, label: t('bulkrax.exporter.labels.name') %>
|
14
|
+
<%= form.input :name, label: t('bulkrax.exporter.labels.name'), input_html: { class: 'form-control' } %>
|
15
15
|
|
16
16
|
<%= form.hidden_field :user_id, value: current_user.id %>
|
17
17
|
|
@@ -19,20 +19,22 @@
|
|
19
19
|
collection: form.object.export_type_list,
|
20
20
|
label: t('bulkrax.exporter.labels.export_type'),
|
21
21
|
required: true,
|
22
|
-
prompt: 'Please select an export type'
|
22
|
+
prompt: 'Please select an export type',
|
23
|
+
input_html: { class: 'form-control' } %>
|
23
24
|
|
24
25
|
<%= form.input :export_from,
|
25
26
|
collection: form.object.export_from_list,
|
26
27
|
label: t('bulkrax.exporter.labels.export_from'),
|
27
28
|
required: true,
|
28
|
-
prompt: 'Please select an export source'
|
29
|
+
prompt: 'Please select an export source',
|
30
|
+
input_html: { class: 'form-control' } %>
|
29
31
|
|
30
32
|
<%= form.input :export_source_importer,
|
31
33
|
label: t('bulkrax.exporter.labels.importer'),
|
32
34
|
required: true,
|
33
35
|
prompt: 'Select from the list',
|
34
36
|
label_html: { class: 'importer export-source-option hidden' },
|
35
|
-
input_html: { class: 'importer export-source-option hidden' },
|
37
|
+
input_html: { class: 'importer export-source-option hidden form-control' },
|
36
38
|
collection: form.object.importers_list.sort %>
|
37
39
|
|
38
40
|
<%= form.input :export_source_collection,
|
@@ -42,7 +44,7 @@
|
|
42
44
|
placeholder: @collection&.title&.first,
|
43
45
|
label_html: { class: 'collection export-source-option hidden' },
|
44
46
|
input_html: {
|
45
|
-
class: 'collection export-source-option hidden',
|
47
|
+
class: 'collection export-source-option hidden form-control',
|
46
48
|
data: {
|
47
49
|
'autocomplete-url' => '/authorities/search/collections',
|
48
50
|
'autocomplete' => 'collection'
|
@@ -50,18 +52,22 @@
|
|
50
52
|
}
|
51
53
|
%>
|
52
54
|
|
53
|
-
|
55
|
+
<% if defined?(::Hyrax) %>
|
56
|
+
<%= form.input :export_source_worktype,
|
54
57
|
label: t('bulkrax.exporter.labels.worktype'),
|
55
58
|
required: true,
|
56
59
|
prompt: 'Select from the list',
|
57
60
|
label_html: { class: 'worktype export-source-option hidden' },
|
58
|
-
input_html: { class: 'worktype export-source-option hidden' },
|
61
|
+
input_html: { class: 'worktype export-source-option hidden form-control' },
|
59
62
|
collection: Hyrax.config.curation_concerns.map {|cc| [cc.to_s, cc.to_s] } %>
|
63
|
+
<% end %>
|
64
|
+
|
60
65
|
|
61
66
|
<%= form.input :limit,
|
62
67
|
as: :integer,
|
63
68
|
hint: 'leave blank or 0 for all records',
|
64
|
-
label: t('bulkrax.exporter.labels.limit')
|
69
|
+
label: t('bulkrax.exporter.labels.limit'),
|
70
|
+
input_html: { class: 'form-control' } %>
|
65
71
|
|
66
72
|
<%= form.input :generated_metadata?,
|
67
73
|
as: :boolean,
|
@@ -76,26 +82,36 @@
|
|
76
82
|
<%= form.input :date_filter,
|
77
83
|
as: :boolean,
|
78
84
|
label: t('bulkrax.exporter.labels.filter_by_date') %>
|
85
|
+
|
79
86
|
<div id="date_filter_picker" class="hidden">
|
80
87
|
<%= form.input :start_date,
|
81
88
|
as: :date,
|
82
|
-
label: t('bulkrax.exporter.labels.start_date')
|
89
|
+
label: t('bulkrax.exporter.labels.start_date'),
|
90
|
+
input_html: { class: 'form-control' } %>
|
83
91
|
|
84
92
|
<%= form.input :finish_date,
|
85
93
|
as: :date,
|
86
|
-
label: t('bulkrax.exporter.labels.finish_date')
|
94
|
+
label: t('bulkrax.exporter.labels.finish_date'),
|
95
|
+
input_html: { class: 'form-control' } %>
|
87
96
|
</div>
|
88
|
-
|
89
|
-
|
90
|
-
|
97
|
+
<% if defined?(::Hyrax) %>
|
98
|
+
<%= form.input :work_visibility,
|
99
|
+
collection: form.object.work_visibility_list,
|
100
|
+
label: t('bulkrax.exporter.labels.visibility'),
|
101
|
+
input_html: { class: 'form-control' } %>
|
102
|
+
<% end %>
|
91
103
|
|
92
|
-
|
93
|
-
|
94
|
-
|
104
|
+
<% if defined?(::Hyrax) %>
|
105
|
+
<%= form.input :workflow_status,
|
106
|
+
collection: form.object.workflow_status_list,
|
107
|
+
label: t('bulkrax.exporter.labels.status'),
|
108
|
+
input_html: { class: 'form-control' } %>
|
109
|
+
<% end %>
|
95
110
|
|
96
111
|
<%= form.input :parser_klass,
|
97
112
|
collection: Bulkrax.parsers.map {|p| [p[:name], p[:class_name], {'data-partial' => p[:partial]}] if p[:class_name].constantize.export_supported? }.compact,
|
98
|
-
label: t('bulkrax.exporter.labels.export_format')
|
113
|
+
label: t('bulkrax.exporter.labels.export_format'),
|
114
|
+
input_html: { class: 'form-control' } %>
|
99
115
|
</div>
|
100
116
|
|
101
117
|
<%# Find definitions for the functions called in this script in
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
<div class="row">
|
6
6
|
<div class="col-md-12">
|
7
|
-
<div class="panel panel-default tabs">
|
7
|
+
<div class="panel panel-default tabs exporter-form">
|
8
8
|
<%= simple_form_for @exporter do |form| %>
|
9
9
|
<%= render 'form', exporter: @exporter, form: form %>
|
10
10
|
<div class="panel-footer">
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
<div class="row">
|
6
6
|
<div class="col-md-12">
|
7
|
-
<div class="panel panel-default tabs">
|
7
|
+
<div class="panel panel-default tabs exporter-form">
|
8
8
|
<%= simple_form_for @exporter do |form| %>
|
9
9
|
<%= render 'form', exporter: @exporter, form: form %>
|
10
10
|
<div class="panel-footer">
|
@@ -11,17 +11,17 @@
|
|
11
11
|
</div>
|
12
12
|
<% end %>
|
13
13
|
|
14
|
-
<%= form.input :name %>
|
14
|
+
<%= form.input :name, input_html: { class: 'form-control' } %>
|
15
15
|
|
16
|
-
<%= form.input :admin_set_id, collection: available_admin_sets %>
|
16
|
+
<%= form.input :admin_set_id, collection: available_admin_sets if defined?(::Hyrax) %>
|
17
17
|
|
18
18
|
<%= form.hidden_field :user_id, value: current_user.id %>
|
19
19
|
|
20
|
-
<%= form.input :frequency, collection: form.object.class.frequency_enums %>
|
20
|
+
<%= form.input :frequency, collection: form.object.class.frequency_enums, input_html: { class: 'form-control' } %>
|
21
21
|
|
22
|
-
<%= form.input :limit, as: :integer, hint: 'leave blank or 0 for all records' %>
|
22
|
+
<%= form.input :limit, as: :integer, hint: 'leave blank or 0 for all records', input_html: { class: 'form-control'} %>
|
23
23
|
|
24
|
-
<%= form.input :parser_klass, collection: Bulkrax.parsers.map {|p| [p[:name], p[:class_name], {'data-partial' => p[:partial]}]}, label: "Parser" %>
|
24
|
+
<%= form.input :parser_klass, collection: Bulkrax.parsers.map {|p| [p[:name], p[:class_name], {'data-partial' => p[:partial]}]}, label: "Parser", input_html: { class: 'form-control' } %>
|
25
25
|
|
26
26
|
<%= form.fields_for :parser_fields do |fi| %>
|
27
27
|
<div class='parser_fields'>
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oai'
|
4
|
+
require 'xml/libxml'
|
5
|
+
|
6
|
+
module Bulkrax
|
7
|
+
##
|
8
|
+
# The purpose of this module is to provide some testing facilities for those that include the
|
9
|
+
# Bulkrax gem in their application.
|
10
|
+
#
|
11
|
+
# This module came about through a desire to expose a quick means of vetting the accuracy of the
|
12
|
+
# different parsers.
|
13
|
+
module EntrySpecHelper
|
14
|
+
##
|
15
|
+
# @api public
|
16
|
+
# @since v5.0.1
|
17
|
+
#
|
18
|
+
# The purpose of this method is encapsulate the logic of creating the appropriate Bulkrax::Entry
|
19
|
+
# object based on the given data, identifier, and parser_class_name.
|
20
|
+
#
|
21
|
+
# From that entry, you should be able to test how {Bulkrax::Entry#build_metadata} populates the
|
22
|
+
# {Bulkrax::Entry#parsed_metadata} variable. Other uses may emerge.
|
23
|
+
#
|
24
|
+
# @param data [Object] the data that we use to populate the raw metadata. Due to implementation
|
25
|
+
# details of each entry, the data will be of different formats.
|
26
|
+
#
|
27
|
+
# @param identifier [String, Integer] The identifier of the entry. This might also be found in
|
28
|
+
# the metadata of the entry, but for instantiation purposes we need this value.
|
29
|
+
# @param parser_class_name [String] The name of the parser class you're wanting to test.
|
30
|
+
# @param type [Sybmol] The type of entry (e.g. :entry, :collection, :file_set) for testing.
|
31
|
+
# @param options [Hash<Symbol,Object>] these are to be passed along into the instantiation of
|
32
|
+
# the various classes. See implementation details.
|
33
|
+
#
|
34
|
+
# @return [Bulkrax::Entry]
|
35
|
+
def self.entry_for(data:, identifier:, parser_class_name:, type: :entry, **options)
|
36
|
+
importer = importer_for(parser_class_name: parser_class_name, **options)
|
37
|
+
entry_type_method_name = ENTRY_TYPE_TO_METHOD_NAME_MAP.fetch(type)
|
38
|
+
entry_class = importer.parser.public_send(entry_type_method_name)
|
39
|
+
|
40
|
+
# Using an instance of the entry_class to dispatch to different
|
41
|
+
entry_for_dispatch = entry_class.new
|
42
|
+
|
43
|
+
# Using the {is_a?} test we get the benefit of inspecting an object's inheritance path
|
44
|
+
# (e.g. ancestry). The logic, as implemented, also provides a mechanism for folks in their
|
45
|
+
# applications to add a {class_name_entry_for}; something that I suspect isn't likely
|
46
|
+
# but given the wide variety of underlying needs I could see happening and I want to encourage
|
47
|
+
# patterned thinking to fold that different build method into this structure.
|
48
|
+
key = entry_class_to_symbol_map.keys.detect { |class_name| entry_for_dispatch.is_a?(class_name.constantize) }
|
49
|
+
|
50
|
+
# Yes, we'll raise an error if we didn't find a corresponding key. And that's okay.
|
51
|
+
symbol = entry_class_to_symbol_map.fetch(key)
|
52
|
+
|
53
|
+
send("build_#{symbol}_entry_for",
|
54
|
+
importer: importer,
|
55
|
+
identifier: identifier,
|
56
|
+
entry_class: entry_class,
|
57
|
+
data: data,
|
58
|
+
**options)
|
59
|
+
end
|
60
|
+
|
61
|
+
ENTRY_TYPE_TO_METHOD_NAME_MAP = {
|
62
|
+
entry: :entry_class,
|
63
|
+
collection: :collection_entry_class,
|
64
|
+
file_set: :file_set_entry_class
|
65
|
+
}.freeze
|
66
|
+
|
67
|
+
DEFAULT_ENTRY_CLASS_TO_SYMBOL_MAP = {
|
68
|
+
'Bulkrax::OaiEntry' => :oai,
|
69
|
+
'Bulkrax::XmlEntry' => :xml,
|
70
|
+
'Bulkrax::CsvEntry' => :csv
|
71
|
+
}.freeze
|
72
|
+
|
73
|
+
# Present implementations of entry classes tend to inherit from the below listed class names.
|
74
|
+
# We're not looking to register all descendents of the {Bulkrax::Entry} class, but instead find
|
75
|
+
# the ancestor where there is significant deviation.
|
76
|
+
def self.entry_class_to_symbol_map
|
77
|
+
@entry_class_to_symbol_map || DEFAULT_ENTRY_CLASS_TO_SYMBOL_MAP
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.entry_class_to_symbol_map=(value)
|
81
|
+
@entry_class_to_symbol_map = value
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.importer_for(parser_class_name:, parser_fields: {}, **options)
|
85
|
+
# Ideally, we could pass in the field_mapping. However, there is logic that ignores the
|
86
|
+
# parser's field_mapping and directly asks for Bulkrax's field_mapping (e.g. model_mapping
|
87
|
+
# method).
|
88
|
+
Rails.logger.warn("You passed :importer_field_mapping as an option. This may not fully work as desired.") if options.key?(:importer_field_mapping)
|
89
|
+
Bulkrax::Importer.new(
|
90
|
+
name: options.fetch(:importer_name, "Test importer for identifier"),
|
91
|
+
admin_set_id: options.fetch(:importer_admin_set_id, "admin_set/default"),
|
92
|
+
user: options.fetch(:importer_user, User.new(email: "hello@world.com")),
|
93
|
+
limit: options.fetch(:importer_limits, 1),
|
94
|
+
parser_klass: parser_class_name,
|
95
|
+
field_mapping: options.fetch(:importer_field_mappings) { Bulkrax.field_mappings.fetch(parser_class_name) },
|
96
|
+
parser_fields: parser_fields
|
97
|
+
).tap do |importer|
|
98
|
+
# Why are we saving the importer and a run? We might want to delve deeper into the call
|
99
|
+
# stack. See https://github.com/scientist-softserv/adventist-dl/pull/266
|
100
|
+
importer.save!
|
101
|
+
# Later on, we might to want a current run
|
102
|
+
importer.importer_runs.create!
|
103
|
+
end
|
104
|
+
end
|
105
|
+
private_class_method :importer_for
|
106
|
+
|
107
|
+
##
|
108
|
+
# @api private
|
109
|
+
#
|
110
|
+
# @param data [Hash<Symbol,String>] we're expecting a hash with keys that are symbols and then
|
111
|
+
# values that are strings.
|
112
|
+
#
|
113
|
+
# @return [Bulkrax::CsvEntry]
|
114
|
+
#
|
115
|
+
# @note As a foible of this implementation, you'll need to include along a CSV to establish the
|
116
|
+
# columns that you'll parse (e.g. the first row
|
117
|
+
def self.build_csv_entry_for(importer:, data:, identifier:, entry_class:, **_options)
|
118
|
+
entry_class.new(
|
119
|
+
importerexporter: importer,
|
120
|
+
identifier: identifier,
|
121
|
+
raw_metadata: data
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# @api private
|
127
|
+
#
|
128
|
+
# @param data [String] we're expecting a string that is well-formed XML for OAI parsing.
|
129
|
+
#
|
130
|
+
# @return [Bulkrax::OaiEntry]
|
131
|
+
def self.build_oai_entry_for(importer:, data:, identifier:, entry_class:, **options)
|
132
|
+
# The raw record assumes we take the XML data, parse it and then send that to the
|
133
|
+
# OAI::GetRecordResponse object.
|
134
|
+
doc = XML::Parser.string(data)
|
135
|
+
raw_record = OAI::GetRecordResponse.new(doc.parse)
|
136
|
+
|
137
|
+
raw_metadata = {
|
138
|
+
importer.parser.source_identifier.to_s => identifier,
|
139
|
+
"data" => data,
|
140
|
+
"collections" => options.fetch(:raw_metadata_collections, []),
|
141
|
+
"children" => options.fetch(:raw_metadata_children, [])
|
142
|
+
}
|
143
|
+
|
144
|
+
entry_class.new(
|
145
|
+
raw_record: raw_record,
|
146
|
+
importerexporter: importer,
|
147
|
+
identifier: identifier,
|
148
|
+
raw_metadata: raw_metadata
|
149
|
+
)
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# @api private
|
154
|
+
#
|
155
|
+
# @param data [String] we're expecting a string that is well-formed XML.
|
156
|
+
#
|
157
|
+
# @return [Bulkrax::XmlEntry]
|
158
|
+
def self.build_xml_entry_for(importer:, data:, identifier:, entry_class:, **options)
|
159
|
+
raw_metadata = {
|
160
|
+
importer.parser.source_identifier.to_s => identifier,
|
161
|
+
"data" => data,
|
162
|
+
"collections" => options.fetch(:raw_metadata_collections, []),
|
163
|
+
"children" => options.fetch(:raw_metadata_children, [])
|
164
|
+
}
|
165
|
+
|
166
|
+
entry_class.new(
|
167
|
+
importerexporter: importer,
|
168
|
+
identifier: identifier,
|
169
|
+
raw_metadata: raw_metadata
|
170
|
+
)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/lib/bulkrax/version.rb
CHANGED
data/lib/bulkrax.rb
CHANGED
@@ -185,6 +185,12 @@ module Bulkrax
|
|
185
185
|
value.to_s.delete("\xEF\xBB\xBF")
|
186
186
|
end
|
187
187
|
|
188
|
+
def self.fallback_user_for_importer_exporter_processing
|
189
|
+
return User.batch_user if defined?(Hyrax) && User.respond_to?(:batch_user)
|
190
|
+
|
191
|
+
raise "We have no fallback user available for Bulkrax.fallback_user_for_importer_exporter_processing"
|
192
|
+
end
|
193
|
+
|
188
194
|
# This class confirms to the Active::Support.serialze interface. It's job is to ensure that we
|
189
195
|
# don't have keys with the tricksy Byte Order Mark character.
|
190
196
|
#
|
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: 5.
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Kaufman
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -396,6 +396,7 @@ files:
|
|
396
396
|
- db/migrate/20220609001128_rename_bulkrax_importer_run_to_importer_run.rb
|
397
397
|
- lib/bulkrax.rb
|
398
398
|
- lib/bulkrax/engine.rb
|
399
|
+
- lib/bulkrax/entry_spec_helper.rb
|
399
400
|
- lib/bulkrax/version.rb
|
400
401
|
- lib/generators/bulkrax/install_generator.rb
|
401
402
|
- lib/generators/bulkrax/templates/README
|
@@ -410,7 +411,7 @@ homepage: https://github.com/samvera-labs/bulkrax
|
|
410
411
|
licenses:
|
411
412
|
- Apache-2.0
|
412
413
|
metadata: {}
|
413
|
-
post_install_message:
|
414
|
+
post_install_message:
|
414
415
|
rdoc_options: []
|
415
416
|
require_paths:
|
416
417
|
- lib
|
@@ -425,8 +426,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
425
426
|
- !ruby/object:Gem::Version
|
426
427
|
version: '0'
|
427
428
|
requirements: []
|
428
|
-
rubygems_version: 3.0.3
|
429
|
-
signing_key:
|
429
|
+
rubygems_version: 3.0.3.1
|
430
|
+
signing_key:
|
430
431
|
specification_version: 4
|
431
432
|
summary: Import and export tool for Hyrax and Hyku
|
432
433
|
test_files: []
|