bulkrax 5.3.0 → 5.4.1
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/factories/bulkrax/object_factory.rb +9 -3
- data/app/views/bulkrax/entries/show.html.erb +5 -5
- data/app/views/bulkrax/importers/_bagit_fields.html.erb +6 -5
- data/app/views/bulkrax/importers/_csv_fields.html.erb +2 -1
- data/app/views/bulkrax/importers/_oai_fields.html.erb +4 -3
- data/app/views/bulkrax/importers/_xml_fields.html.erb +11 -10
- data/config/locales/bulkrax.en.yml +11 -6
- data/db/migrate/20210806044408_remove_unused_last_error.rb +3 -3
- data/db/migrate/20230608153601_add_indices_to_bulkrax.rb +8 -8
- data/lib/bulkrax/engine.rb +10 -9
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +5 -2
- data/lib/tasks/bulkrax_tasks.rake +102 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4561533e5e3bb65767c53d52be32e51848c0c2c81da51eb15709927b3499234f
|
4
|
+
data.tar.gz: 0c35135671a7536ed858246c4e7793c9b0743aef17caeeadd6e045e44b44200f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26c5cd6fd88dd94546b906f64762fb02ebdd1a830683202352616a3e347b7efc18900ba293d42ad162df176731bd7ccd7a7962db3180f16fcbbff95d2e577b46
|
7
|
+
data.tar.gz: 1aa71ab730fff3055537c003e02e3ea19696316f07b70e0c86ef8babc964f1b40c4aa2dc84736e841bfba31457ff8c81f98e4468eb95b174dd6c06522d2dc733
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Bulkrax
|
4
|
-
class ObjectFactory
|
4
|
+
class ObjectFactory # rubocop:disable Metrics/ClassLength
|
5
5
|
extend ActiveModel::Callbacks
|
6
6
|
include Bulkrax::FileFactory
|
7
7
|
include DynamicRecordLookup
|
@@ -87,7 +87,8 @@ module Bulkrax
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def find
|
90
|
-
|
90
|
+
found = find_by_id if attributes[:id].present?
|
91
|
+
return found if found.present?
|
91
92
|
return search_by_identifier if attributes[work_identifier].present?
|
92
93
|
end
|
93
94
|
|
@@ -102,7 +103,12 @@ module Bulkrax
|
|
102
103
|
end
|
103
104
|
|
104
105
|
def search_by_identifier
|
105
|
-
|
106
|
+
# TODO(alishaevn): return the proper `work_index` value below
|
107
|
+
# ref: https://github.com/samvera-labs/bulkrax/issues/866
|
108
|
+
# ref:https://github.com/samvera-labs/bulkrax/issues/867
|
109
|
+
# work_index = ::ActiveFedora.index_field_mapper.solr_name(work_identifier, :facetable)
|
110
|
+
work_index = work_identifier
|
111
|
+
query = { work_index =>
|
106
112
|
source_identifier_value }
|
107
113
|
# Query can return partial matches (something6 matches both something6 and something68)
|
108
114
|
# so we need to weed out any that are not the correct full match. But other items might be
|
@@ -2,17 +2,17 @@
|
|
2
2
|
<div class="panel panel-default">
|
3
3
|
<div class="panel-body">
|
4
4
|
<p class='bulkrax-p-align'>
|
5
|
-
<strong
|
5
|
+
<strong><%= t('bulkrax.importer.labels.identifier') %>:</strong>
|
6
6
|
<%= @entry.identifier %>
|
7
7
|
</p>
|
8
8
|
|
9
9
|
<p class='bulkrax-p-align'>
|
10
|
-
<strong
|
10
|
+
<strong><%= t('bulkrax.importer.labels.entry_id') %>:</strong>
|
11
11
|
<%= @entry.id %>
|
12
12
|
</p>
|
13
13
|
|
14
14
|
<p class='bulkrax-p-align'>
|
15
|
-
<strong
|
15
|
+
<strong><%= t('bulkrax.importer.labels.type') %>:</strong>
|
16
16
|
<%= @entry.factory_class || 'Unknown' %>
|
17
17
|
</p>
|
18
18
|
<%= render partial: 'raw_metadata'%>
|
@@ -23,10 +23,10 @@
|
|
23
23
|
|
24
24
|
<p class="bulkrax-p-align">
|
25
25
|
<% if @importer.present? %>
|
26
|
-
<strong
|
26
|
+
<strong><%= t('bulkrax.importer.labels.importer') %>:</strong>
|
27
27
|
<%= link_to @importer.name, importer_path(@importer) %>
|
28
28
|
<% elsif @exporter.present? %>
|
29
|
-
<strong
|
29
|
+
<strong><%= t('bulkrax.importer.labels.exporter') %>:</strong>
|
30
30
|
<%= link_to @exporter.name, exporter_path(@exporter) %>
|
31
31
|
<% end %>
|
32
32
|
</p>
|
@@ -1,15 +1,15 @@
|
|
1
1
|
<div class='bagit_fields'>
|
2
2
|
|
3
|
-
<%#= fi.input :metadata_type,
|
4
|
-
collection: importer.import_metadata_type,
|
3
|
+
<%#= fi.input :metadata_type,
|
4
|
+
collection: importer.import_metadata_type,
|
5
5
|
selected: importer.parser_fields['metadata_type'],
|
6
6
|
include_blank: true,
|
7
7
|
input_html: { class: 'form-control' }
|
8
8
|
%>
|
9
9
|
<%= fi.input :metadata_file_name, as: :string, input_html: { value: importer.parser_fields['metadata_file_name'] } %>
|
10
10
|
|
11
|
-
<%= fi.input :metadata_format,
|
12
|
-
collection: importer.import_metadata_format,
|
11
|
+
<%= fi.input :metadata_format,
|
12
|
+
collection: importer.import_metadata_format,
|
13
13
|
selected: importer.parser_fields['metadata_format'],
|
14
14
|
include_blank: true,
|
15
15
|
input_html: { class: 'form-control' }
|
@@ -18,7 +18,8 @@
|
|
18
18
|
<%= fi.input :visibility,
|
19
19
|
collection: [
|
20
20
|
['Public', 'open'],
|
21
|
-
['Private', 'restricted']
|
21
|
+
['Private', 'restricted'],
|
22
|
+
['Institution', 'authenticated']
|
22
23
|
],
|
23
24
|
selected: importer.parser_fields['visibility'] || 'open',
|
24
25
|
input_html: { class: 'form-control' }
|
@@ -1,15 +1,16 @@
|
|
1
1
|
<div class='oai_fields'>
|
2
2
|
<%= fi.input :base_url, as: :string, input_html: { value: importer.parser_fields['base_url'] } %>
|
3
|
-
|
3
|
+
|
4
4
|
<%= fi.input :metadata_prefix, as: :string, hint: 'Such as oai_dc, dcterms or oai_qdc', input_html: { value: importer.parser_fields['metadata_prefix'] } %>
|
5
|
-
|
5
|
+
|
6
6
|
<%= fi.input :set, collection: [importer.parser_fields['set']], label: 'Set (source)', selected: importer.parser_fields['set'] %>
|
7
7
|
<button type="button" class="btn btn-default refresh-set-source">Refresh Sets</button>
|
8
8
|
|
9
9
|
<%= fi.input :visibility,
|
10
10
|
collection: [
|
11
11
|
['Public', 'open'],
|
12
|
-
['Private', 'restricted']
|
12
|
+
['Private', 'restricted'],
|
13
|
+
['Institution', 'authenticated']
|
13
14
|
],
|
14
15
|
selected: importer.parser_fields['visibility'] || 'open',
|
15
16
|
input_html: { class: 'form-control' }
|
@@ -1,31 +1,32 @@
|
|
1
1
|
<div class='xml_fields'>
|
2
2
|
|
3
|
-
<%# @todo improve on this implementation.
|
4
|
-
As it stands, it's a hostage to namespaces,
|
5
|
-
eg. dc:title
|
3
|
+
<%# @todo improve on this implementation.
|
4
|
+
As it stands, it's a hostage to namespaces,
|
5
|
+
eg. dc:title
|
6
6
|
if namespaces aren't in the xml, we would have to specify dc:title
|
7
7
|
but if the namespaces ARE present, we remove them so we would need title
|
8
8
|
%>
|
9
|
-
<%= fi.input :record_element,
|
10
|
-
hint: 'Provide the xml element name to use to identify the record, or records, eg. ROW - each record in the attached XML is wrapped in a <ROW> tag.',
|
9
|
+
<%= fi.input :record_element,
|
10
|
+
hint: 'Provide the xml element name to use to identify the record, or records, eg. ROW - each record in the attached XML is wrapped in a <ROW> tag.',
|
11
11
|
input_html: { value: importer.parser_fields['record_element'] }
|
12
12
|
%>
|
13
13
|
|
14
|
-
<%= fi.input :import_type,
|
14
|
+
<%= fi.input :import_type,
|
15
15
|
collection: [
|
16
16
|
['Single Work per Metadata File', 'single'],
|
17
|
-
['Multiple Works per Metadata File', 'multiple']
|
18
|
-
],
|
17
|
+
['Multiple Works per Metadata File', 'multiple']
|
18
|
+
],
|
19
19
|
selected: importer.parser_fields['import_type'],
|
20
20
|
input_html: { class: 'form-control' }
|
21
21
|
%>
|
22
|
-
|
22
|
+
|
23
23
|
<h4>Visiblity</h4>
|
24
24
|
|
25
25
|
<%= fi.input :visibility,
|
26
26
|
collection: [
|
27
27
|
['Public', 'open'],
|
28
|
-
['Private', 'restricted']
|
28
|
+
['Private', 'restricted'],
|
29
|
+
['Institution', 'authenticated']
|
29
30
|
],
|
30
31
|
selected: importer.parser_fields['visibility'] || 'open',
|
31
32
|
input_html: { class: 'form-control' }
|
@@ -46,18 +46,23 @@ en:
|
|
46
46
|
generated_metadata: "These exported fields currently cannot be imported."
|
47
47
|
importer:
|
48
48
|
labels:
|
49
|
-
name: Name
|
50
|
-
user: User
|
51
49
|
admin_set: Admin set
|
50
|
+
collection_entries: Collection Entries
|
51
|
+
entry_id: Entry ID
|
52
|
+
exporter: Exporter
|
53
|
+
file_set_entries: File Set Entries
|
52
54
|
frequency: Frequency
|
53
|
-
|
55
|
+
identifier: Identifier
|
56
|
+
importer: Importer
|
54
57
|
limit: Limit
|
55
|
-
|
58
|
+
name: Name
|
59
|
+
parser_klass: Parser klass
|
56
60
|
total_collections: Total Collections
|
57
61
|
total_file_sets: Total File Sets
|
62
|
+
total_work_entries: Total Works
|
63
|
+
type: Type
|
64
|
+
user: User
|
58
65
|
work_entries: Work Entries
|
59
|
-
collection_entries: Collection Entries
|
60
|
-
file_set_entries: File Set Entries
|
61
66
|
table_header:
|
62
67
|
labels:
|
63
68
|
identifier: Identifier
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class RemoveUnusedLastError < ActiveRecord::Migration[5.1]
|
2
2
|
def change
|
3
|
-
remove_column :bulkrax_entries, :last_error
|
4
|
-
remove_column :bulkrax_exporters, :last_error
|
5
|
-
remove_column :bulkrax_importers, :last_error
|
3
|
+
remove_column :bulkrax_entries, :last_error if column_exists?(:bulkrax_entries, :last_error)
|
4
|
+
remove_column :bulkrax_exporters, :last_error if column_exists?(:bulkrax_exporters, :last_error)
|
5
|
+
remove_column :bulkrax_importers, :last_error if column_exists?(:bulkrax_importers, :last_error)
|
6
6
|
end
|
7
7
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class AddIndicesToBulkrax < ActiveRecord::Migration[5.1]
|
2
2
|
def change
|
3
|
-
add_index :bulkrax_entries, :identifier
|
4
|
-
add_index :bulkrax_entries, :type
|
5
|
-
add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx'
|
3
|
+
add_index :bulkrax_entries, :identifier unless index_exists?(:bulkrax_entries, :identifier)
|
4
|
+
add_index :bulkrax_entries, :type unless index_exists?(:bulkrax_entries, :type)
|
5
|
+
add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx' unless index_exists?(:bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx')
|
6
6
|
|
7
|
-
add_index :bulkrax_pending_relationships, :parent_id
|
8
|
-
add_index :bulkrax_pending_relationships, :child_id
|
7
|
+
add_index :bulkrax_pending_relationships, :parent_id unless index_exists?(:bulkrax_pending_relationships, :parent_id)
|
8
|
+
add_index :bulkrax_pending_relationships, :child_id unless index_exists?(:bulkrax_pending_relationships, :child_id)
|
9
9
|
|
10
|
-
add_index :bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx'
|
11
|
-
add_index :bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx'
|
12
|
-
add_index :bulkrax_statuses, :error_class
|
10
|
+
add_index :bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx' unless index_exists?(:bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx')
|
11
|
+
add_index :bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx' unless index_exists?(:bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx')
|
12
|
+
add_index :bulkrax_statuses, :error_class unless index_exists?(:bulkrax_statuses, :error_class)
|
13
13
|
end
|
14
14
|
end
|
data/lib/bulkrax/engine.rb
CHANGED
@@ -23,15 +23,16 @@ module Bulkrax
|
|
23
23
|
end
|
24
24
|
|
25
25
|
config.after_initialize do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
# We want to ensure that Bulkrax is earlier in the lookup for view_paths than Hyrax. That is
|
27
|
+
# we favor view in Bulkrax over those in Hyrax.
|
28
|
+
if defined?(Hyrax)
|
29
|
+
my_engine_root = Bulkrax::Engine.root.to_s
|
30
|
+
hyrax_engine_root = Hyrax::Engine.root.to_s
|
31
|
+
paths = ActionController::Base.view_paths.collect(&:to_s)
|
32
|
+
hyrax_view_path = paths.detect { |path| path.match(%r{^#{hyrax_engine_root}}) }
|
33
|
+
paths.insert(paths.index(hyrax_view_path), File.join(my_engine_root, 'app', 'views')) if hyrax_view_path
|
34
|
+
ActionController::Base.view_paths = paths.uniq
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
data/lib/bulkrax/version.rb
CHANGED
data/lib/bulkrax.rb
CHANGED
@@ -152,7 +152,7 @@ module Bulkrax
|
|
152
152
|
"publisher" => { from: ["publisher"] },
|
153
153
|
"related_url" => { from: ["relation"] },
|
154
154
|
"rights_statement" => { from: ["rights"] },
|
155
|
-
"source" => { from: ["source"] },
|
155
|
+
# "source" => { from: ["source"], source_identifier: true },
|
156
156
|
"subject" => { from: ["subject"], parsed: true },
|
157
157
|
"title" => { from: ["title"] },
|
158
158
|
"resource_type" => { from: ["type"], parsed: true },
|
@@ -172,7 +172,7 @@ module Bulkrax
|
|
172
172
|
"related_url" => { from: ["relation"] },
|
173
173
|
"rights_holder" => { from: ["rightsHolder"] },
|
174
174
|
"rights_statement" => { from: ["rights"] },
|
175
|
-
"source" => { from: ["source"] },
|
175
|
+
# "source" => { from: ["source"], source_identifier: true },
|
176
176
|
"subject" => { from: ["subject"], parsed: true },
|
177
177
|
"title" => { from: ["title"] },
|
178
178
|
"resource_type" => { from: ["type"], parsed: true },
|
@@ -182,6 +182,9 @@ module Bulkrax
|
|
182
182
|
"Bulkrax::CsvParser" => {},
|
183
183
|
'Bulkrax::BagitParser' => {},
|
184
184
|
'Bulkrax::XmlParser' => {}
|
185
|
+
# "Bulkrax::CsvParser" => { "source" => { from: ["source"], source_identifier: true } },
|
186
|
+
# 'Bulkrax::BagitParser' => { "source" => { from: ["source"], source_identifier: true } },
|
187
|
+
# 'Bulkrax::XmlParser' => { "source" => { from: ["source"], source_identifier: true } }
|
185
188
|
}
|
186
189
|
|
187
190
|
# Lambda to set the default field mapping
|
@@ -1,6 +1,108 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
namespace :bulkrax do
|
4
|
+
# Usage example: rails bulkrax:generate_test_csvs['5','100','GenericWork']
|
5
|
+
desc 'Generate CSVs with fake data for testing purposes'
|
6
|
+
task :generate_test_csvs, [:num_of_csvs, :csv_rows, :record_type] => :environment do |_t, args|
|
7
|
+
# NOTE: If this line throws an error, run `gem install faker` inside your Docker container
|
8
|
+
require 'faker'
|
9
|
+
require 'csv'
|
10
|
+
|
11
|
+
FileUtils.mkdir_p(Rails.root.join('tmp', 'imports'))
|
12
|
+
|
13
|
+
IGNORED_PROPERTIES = %w[
|
14
|
+
admin_set_id
|
15
|
+
alternate_ids
|
16
|
+
arkivo_checksum
|
17
|
+
created_at
|
18
|
+
date_modified
|
19
|
+
date_uploaded
|
20
|
+
depositor
|
21
|
+
embargo
|
22
|
+
has_model
|
23
|
+
head
|
24
|
+
internal_resource
|
25
|
+
label
|
26
|
+
lease
|
27
|
+
member_ids
|
28
|
+
member_of_collection_ids
|
29
|
+
modified_date
|
30
|
+
new_record
|
31
|
+
on_behalf_of
|
32
|
+
owner
|
33
|
+
proxy_depositor
|
34
|
+
rendering_ids
|
35
|
+
representative_id
|
36
|
+
state
|
37
|
+
tail
|
38
|
+
thumbnail_id
|
39
|
+
updated_at
|
40
|
+
].freeze
|
41
|
+
|
42
|
+
BULKRAX_PROPERTIES = %w[
|
43
|
+
source_identifier
|
44
|
+
model
|
45
|
+
].freeze
|
46
|
+
|
47
|
+
num_of_csvs = args.num_of_csvs.presence&.to_i || 5
|
48
|
+
csv_rows = args.csv_rows.presence&.to_i || 100
|
49
|
+
record_type = args.record_type.presence&.constantize || GenericWork
|
50
|
+
|
51
|
+
csv_header = if Hyrax.config.try(:use_valkyrie?)
|
52
|
+
record_type.schema.map { |k| k.name.to_s }
|
53
|
+
else
|
54
|
+
record_type.properties.keys
|
55
|
+
end
|
56
|
+
|
57
|
+
csv_header -= IGNORED_PROPERTIES
|
58
|
+
csv_header.unshift(*BULKRAX_PROPERTIES)
|
59
|
+
|
60
|
+
num_of_csvs.times do |i|
|
61
|
+
CSV.open(Rails.root.join('tmp', 'imports', "importer_#{i}.csv"), 'wb') do |csv|
|
62
|
+
csv << csv_header
|
63
|
+
csv_rows.times do |_index|
|
64
|
+
row = []
|
65
|
+
csv_header.each do |prop_name|
|
66
|
+
row << case prop_name
|
67
|
+
when 'id', 'source_identifier'
|
68
|
+
Faker::Number.number(digits: 4)
|
69
|
+
when 'model'
|
70
|
+
record_type.to_s
|
71
|
+
when 'rights_statement'
|
72
|
+
'http://rightsstatements.org/vocab/CNE/1.0/'
|
73
|
+
when 'license'
|
74
|
+
'https://creativecommons.org/licenses/by-nc/4.0/'
|
75
|
+
when 'based_near'
|
76
|
+
# FIXME: Set a proper :based_near value
|
77
|
+
nil
|
78
|
+
else
|
79
|
+
Faker::Lorem.sentence
|
80
|
+
end
|
81
|
+
end
|
82
|
+
csv << row
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
num_of_csvs.times do |i|
|
88
|
+
Bulkrax::Importer.create(
|
89
|
+
name: "Generated CSV #{i}",
|
90
|
+
admin_set_id: 'admin_set/default',
|
91
|
+
user_id: User.find_by(email: 'admin@example.com').id,
|
92
|
+
frequency: 'PT0S',
|
93
|
+
parser_klass: 'Bulkrax::CsvParser',
|
94
|
+
parser_fields: {
|
95
|
+
'visibility' => 'open',
|
96
|
+
'rights_statement' => '',
|
97
|
+
'override_rights_statement' => '0',
|
98
|
+
'file_style' => 'Specify a Path on the Server',
|
99
|
+
'import_file_path' => "tmp/imports/importer_#{i}.csv",
|
100
|
+
'update_files' => false
|
101
|
+
}
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
4
106
|
desc "Remove old exported zips and create new ones with the new file structure"
|
5
107
|
task rerun_all_exporters: :environment do
|
6
108
|
# delete the existing folders and zip files
|
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.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Kaufman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|