bulkrax 5.0.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|