bulkrax 5.3.1 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bdc3299c331e345417117694e5da25031db99e181701d6b52db630b5c297470
4
- data.tar.gz: 105119be729e2ea30a5fceb5b2f47557d5edb933b05663b7905e49665ceb3dfa
3
+ metadata.gz: 56ac96f944d880492d7f7aa50870557ba81cf2ed23875751509b3ec23411644b
4
+ data.tar.gz: f18c9fa1d5a968d9214587476f2f949e04015e1402f6cb2ac516616669567c0e
5
5
  SHA512:
6
- metadata.gz: 027d2ea6005df040daebf48bf431e471b1386141e2e13ae5de149f25125f8d2306576accb8300869ab16fb500f5f2b4d3f88ea28e299648bf588bf5f4d9c8264
7
- data.tar.gz: a3924a66c3ca3d8e3a243573cbb44ca41f11f687ca02f17bbfad6403883a516b917248cf0f807088e351cc206a6b18d99d9434643ccebebd06dbb126319c9445
6
+ metadata.gz: 0556a64e91eb41a27597b717fbf9e1de0682d666f116397e64a1b58a64fffaaadfd2dac645fbd256e3bd14ffb9065ce5f0ceaac920296f6623629199a6e130b5
7
+ data.tar.gz: dada612e0ee38d0b74ceacedc5c034cb39e26111edc90c39afd0d04338f77c1e0c0857a4d983bd7bd24fe8d7e601e2b8a6c32242e3142b2faad3a3369cbf82c1
@@ -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
- return find_by_id if attributes[:id].present?
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,8 @@ module Bulkrax
102
103
  end
103
104
 
104
105
  def search_by_identifier
105
- query = { work_identifier =>
106
+ work_index = ::ActiveFedora.index_field_mapper.solr_name(work_identifier, :facetable)
107
+ query = { work_index =>
106
108
  source_identifier_value }
107
109
  # Query can return partial matches (something6 matches both something6 and something68)
108
110
  # so we need to weed out any that are not the correct full match. But other items might be
@@ -40,7 +40,7 @@ module Bulkrax
40
40
 
41
41
  include DynamicRecordLookup
42
42
 
43
- queue_as Bulkrax.config.ingest_queue_name
43
+ queue_as :import
44
44
 
45
45
  # @param parent_identifier [String] Work/Collection ID or Bulkrax::Entry source_identifiers
46
46
  # @param importer_run [Bulkrax::ImporterRun] current importer run (needed to properly update counters)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class DeleteJob < ApplicationJob
5
- queue_as Bulkrax.config.ingest_queue_name
5
+ queue_as :import
6
6
 
7
7
  # rubocop:disable Rails/SkipsModelValidations
8
8
  def perform(entry, importer_run)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class DownloadCloudFileJob < ApplicationJob
5
- queue_as Bulkrax.config.ingest_queue_name
5
+ queue_as :import
6
6
 
7
7
  # Retrieve cloud file and write to the imports directory
8
8
  # Note: if using the file system, the mounted directory in
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class ImportCollectionJob < ApplicationJob
5
- queue_as Bulkrax.config.ingest_queue_name
5
+ queue_as :import
6
6
 
7
7
  # rubocop:disable Rails/SkipsModelValidations
8
8
  def perform(*args)
@@ -6,7 +6,7 @@ module Bulkrax
6
6
  class ImportFileSetJob < ApplicationJob
7
7
  include DynamicRecordLookup
8
8
 
9
- queue_as Bulkrax.config.ingest_queue_name
9
+ queue_as :import
10
10
 
11
11
  attr_reader :importer_run_id
12
12
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class ImportWorkJob < ApplicationJob
5
- queue_as Bulkrax.config.ingest_queue_name
5
+ queue_as :import
6
6
 
7
7
  # rubocop:disable Rails/SkipsModelValidations
8
8
  #
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bulkrax
4
4
  class ImporterJob < ApplicationJob
5
- queue_as Bulkrax.config.ingest_queue_name
5
+ queue_as :import
6
6
 
7
7
  def perform(importer_id, only_updates_since_last_import = false)
8
8
  importer = Importer.find(importer_id)
@@ -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>Identifier:</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>Entry ID:</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>Type:</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>Importer:</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>Exporter:</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' }
@@ -3,7 +3,8 @@
3
3
  <%= fi.input :visibility,
4
4
  collection: [
5
5
  ['Public', 'open'],
6
- ['Private', 'restricted']
6
+ ['Private', 'restricted'],
7
+ ['Institution', 'authenticated']
7
8
  ],
8
9
  selected: importer.parser_fields['visibility'] || 'open',
9
10
  input_html: { class: 'form-control' }
@@ -1,16 +1,17 @@
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']
13
- ],
12
+ ['Private', 'restricted'],
13
+ ['Institution', 'authenticated']
14
+ ],x
14
15
  selected: importer.parser_fields['visibility'] || 'open',
15
16
  input_html: { class: 'form-control' }
16
17
  %>
@@ -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
- parser_klass: Parser klass
55
+ identifier: Identifier
56
+ importer: Importer
54
57
  limit: Limit
55
- total_work_entries: Total Works
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
@@ -23,15 +23,16 @@ module Bulkrax
23
23
  end
24
24
 
25
25
  config.after_initialize do
26
- my_engine_root = Bulkrax::Engine.root.to_s
27
- paths = ActionController::Base.view_paths.collect(&:to_s)
28
- hyrax_path = paths.detect { |path| path.match(/\/hyrax-[\d\.]+.*/) }
29
- paths = if hyrax_path
30
- paths.insert(paths.index(hyrax_path), my_engine_root + '/app/views')
31
- else
32
- paths.insert(0, my_engine_root + '/app/views')
33
- end
34
- ActionController::Base.view_paths = paths
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- VERSION = '5.3.1'
4
+ VERSION = '5.4.0'
5
5
  end
data/lib/bulkrax.rb CHANGED
@@ -1,16 +1,16 @@
1
- # frozen_string_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
- require "bulkrax/version"
4
- require "bulkrax/engine"
5
- require 'active_support/all'
3
+ require "bulkrax/version"
4
+ require "bulkrax/engine"
5
+ require 'active_support/all'
6
6
 
7
- # rubocop:disable Metrics/ModuleLength
7
+ # rubocop:disable Metrics/ModuleLength
8
8
  module Bulkrax
9
- extend self # rubocop:disable Style/ModuleFunction
10
- extend Forwardable
9
+ extend self # rubocop:disable Style/ModuleFunction
10
+ extend Forwardable
11
11
 
12
- ##
13
- # @api public
12
+ ##
13
+ # @api public
14
14
  class Configuration
15
15
  attr_accessor :api_definition,
16
16
  :curation_concerns,
@@ -35,15 +35,6 @@ module Bulkrax
35
35
  :reserved_properties,
36
36
  :server_name
37
37
 
38
- attr_writer :ingest_queue_name
39
- ##
40
- # @return [String, Proc]
41
- def ingest_queue_name
42
- return @ingest_queue_name if @ingest_queue_name.present?
43
- return Hyrax.config.ingest_queue_name if defined?(Hyrax)
44
- :import
45
- end
46
-
47
38
  attr_writer :use_locking
48
39
 
49
40
  def use_locking
@@ -54,61 +45,61 @@ module Bulkrax
54
45
  alias use_locking? use_locking
55
46
  end
56
47
 
57
- def config
58
- @config ||= Configuration.new
59
- yield @config if block_given?
60
- @config
61
- end
62
- alias setup config
48
+ def config
49
+ @config ||= Configuration.new
50
+ yield @config if block_given?
51
+ @config
52
+ end
53
+ alias setup config
63
54
 
64
- def_delegators :@config,
65
- :api_definition,
66
- :api_definition=,
67
- :curation_concerns,
68
- :curation_concerns=,
69
- :default_field_mapping,
70
- :default_field_mapping=,
71
- :default_work_type,
72
- :default_work_type=,
73
- :export_path,
74
- :export_path=,
75
- :field_mappings,
76
- :field_mappings=,
77
- :file_model_class,
78
- :file_model_class=,
79
- :fill_in_blank_source_identifiers,
80
- :fill_in_blank_source_identifiers=,
81
- :generated_metadata_mapping,
82
- :generated_metadata_mapping=,
83
- :import_path,
84
- :import_path=,
85
- :multi_value_element_join_on,
86
- :multi_value_element_join_on=,
87
- :multi_value_element_split_on,
88
- :multi_value_element_split_on=,
89
- :object_factory,
90
- :object_factory=,
91
- :parsers,
92
- :parsers=,
93
- :qa_controlled_properties,
94
- :qa_controlled_properties=,
95
- :related_children_field_mapping,
96
- :related_children_field_mapping=,
97
- :related_parents_field_mapping,
98
- :related_parents_field_mapping=,
99
- :relationship_job_class,
100
- :relationship_job_class=,
101
- :removed_image_path,
102
- :removed_image_path=,
103
- :required_elements,
104
- :required_elements=,
105
- :reserved_properties,
106
- :reserved_properties=,
107
- :server_name,
108
- :server_name=,
109
- :use_locking,
110
- :use_locking=,
111
- :use_locking?
55
+ def_delegators :@config,
56
+ :api_definition,
57
+ :api_definition=,
58
+ :curation_concerns,
59
+ :curation_concerns=,
60
+ :default_field_mapping,
61
+ :default_field_mapping=,
62
+ :default_work_type,
63
+ :default_work_type=,
64
+ :export_path,
65
+ :export_path=,
66
+ :field_mappings,
67
+ :field_mappings=,
68
+ :file_model_class,
69
+ :file_model_class=,
70
+ :fill_in_blank_source_identifiers,
71
+ :fill_in_blank_source_identifiers=,
72
+ :generated_metadata_mapping,
73
+ :generated_metadata_mapping=,
74
+ :import_path,
75
+ :import_path=,
76
+ :multi_value_element_join_on,
77
+ :multi_value_element_join_on=,
78
+ :multi_value_element_split_on,
79
+ :multi_value_element_split_on=,
80
+ :object_factory,
81
+ :object_factory=,
82
+ :parsers,
83
+ :parsers=,
84
+ :qa_controlled_properties,
85
+ :qa_controlled_properties=,
86
+ :related_children_field_mapping,
87
+ :related_children_field_mapping=,
88
+ :related_parents_field_mapping,
89
+ :related_parents_field_mapping=,
90
+ :relationship_job_class,
91
+ :relationship_job_class=,
92
+ :removed_image_path,
93
+ :removed_image_path=,
94
+ :required_elements,
95
+ :required_elements=,
96
+ :reserved_properties,
97
+ :reserved_properties=,
98
+ :server_name,
99
+ :server_name=,
100
+ :use_locking,
101
+ :use_locking=,
102
+ :use_locking?
112
103
 
113
104
  config do |conf|
114
105
  conf.parsers = [
@@ -147,149 +138,149 @@ module Bulkrax
147
138
  # Based on Hyrax CoreMetadata && BasicMetadata
148
139
  # Override at application level to change
149
140
  conf.field_mappings = {
150
- "Bulkrax::OaiDcParser" => {
151
- "contributor" => { from: ["contributor"] },
152
- # no appropriate mapping for coverage (based_near needs id)
153
- # ""=>{:from=>["coverage"]},
154
- "creator" => { from: ["creator"] },
155
- "date_created" => { from: ["date"] },
156
- "description" => { from: ["description"] },
157
- # no appropriate mapping for format
158
- # ""=>{:from=>["format"]},
159
- "identifier" => { from: ["identifier"] },
160
- "language" => { from: ["language"], parsed: true },
161
- "publisher" => { from: ["publisher"] },
162
- "related_url" => { from: ["relation"] },
163
- "rights_statement" => { from: ["rights"] },
164
- "source" => { from: ["source"] },
165
- "subject" => { from: ["subject"], parsed: true },
166
- "title" => { from: ["title"] },
167
- "resource_type" => { from: ["type"], parsed: true },
168
- "remote_files" => { from: ["thumbnail_url"], parsed: true }
141
+ "Bulkrax::OaiDcParser" => {
142
+ "contributor" => { from: ["contributor"] },
143
+ # no appropriate mapping for coverage (based_near needs id)
144
+ # ""=>{:from=>["coverage"]},
145
+ "creator" => { from: ["creator"] },
146
+ "date_created" => { from: ["date"] },
147
+ "description" => { from: ["description"] },
148
+ # no appropriate mapping for format
149
+ # ""=>{:from=>["format"]},
150
+ "identifier" => { from: ["identifier"] },
151
+ "language" => { from: ["language"], parsed: true },
152
+ "publisher" => { from: ["publisher"] },
153
+ "related_url" => { from: ["relation"] },
154
+ "rights_statement" => { from: ["rights"] },
155
+ "source" => { from: ["source"] },
156
+ "subject" => { from: ["subject"], parsed: true },
157
+ "title" => { from: ["title"] },
158
+ "resource_type" => { from: ["type"], parsed: true },
159
+ "remote_files" => { from: ["thumbnail_url"], parsed: true }
169
160
  },
170
- "Bulkrax::OaiQualifiedDcParser" => {
171
- "abstract" => { from: ["abstract"] },
172
- "alternative_title" => { from: ["alternative"] },
161
+ "Bulkrax::OaiQualifiedDcParser" => {
162
+ "abstract" => { from: ["abstract"] },
163
+ "alternative_title" => { from: ["alternative"] },
173
164
  "bibliographic_citation" => { from: ["bibliographicCitation"] },
174
- "contributor" => { from: ["contributor"] },
175
- "creator" => { from: ["creator"] },
176
- "date_created" => { from: ["created"] },
177
- "description" => { from: ["description"] },
178
- "language" => { from: ["language"] },
179
- "license" => { from: ["license"] },
180
- "publisher" => { from: ["publisher"] },
181
- "related_url" => { from: ["relation"] },
182
- "rights_holder" => { from: ["rightsHolder"] },
183
- "rights_statement" => { from: ["rights"] },
184
- "source" => { from: ["source"] },
185
- "subject" => { from: ["subject"], parsed: true },
186
- "title" => { from: ["title"] },
187
- "resource_type" => { from: ["type"], parsed: true },
188
- "remote_files" => { from: ["thumbnail_url"], parsed: true }
189
- },
190
- # When empty, a default_field_mapping will be generated
191
- "Bulkrax::CsvParser" => {},
192
- 'Bulkrax::BagitParser' => {},
193
- 'Bulkrax::XmlParser' => {}
194
- }
165
+ "contributor" => { from: ["contributor"] },
166
+ "creator" => { from: ["creator"] },
167
+ "date_created" => { from: ["created"] },
168
+ "description" => { from: ["description"] },
169
+ "language" => { from: ["language"] },
170
+ "license" => { from: ["license"] },
171
+ "publisher" => { from: ["publisher"] },
172
+ "related_url" => { from: ["relation"] },
173
+ "rights_holder" => { from: ["rightsHolder"] },
174
+ "rights_statement" => { from: ["rights"] },
175
+ "source" => { from: ["source"] },
176
+ "subject" => { from: ["subject"], parsed: true },
177
+ "title" => { from: ["title"] },
178
+ "resource_type" => { from: ["type"], parsed: true },
179
+ "remote_files" => { from: ["thumbnail_url"], parsed: true }
180
+ },
181
+ # When empty, a default_field_mapping will be generated
182
+ "Bulkrax::CsvParser" => {},
183
+ 'Bulkrax::BagitParser' => {},
184
+ 'Bulkrax::XmlParser' => {}
185
+ }
195
186
 
196
- # Lambda to set the default field mapping
197
- conf.default_field_mapping = lambda do |field|
198
- return if field.blank?
199
- {
200
- field.to_s =>
201
- {
202
- from: [field.to_s],
203
- split: false,
204
- parsed: Bulkrax::ApplicationMatcher.method_defined?("parse_#{field}"),
205
- if: nil,
206
- excluded: false
207
- }
208
- }
209
- end
187
+ # Lambda to set the default field mapping
188
+ conf.default_field_mapping = lambda do |field|
189
+ return if field.blank?
190
+ {
191
+ field.to_s =>
192
+ {
193
+ from: [field.to_s],
194
+ split: false,
195
+ parsed: Bulkrax::ApplicationMatcher.method_defined?("parse_#{field}"),
196
+ if: nil,
197
+ excluded: false
198
+ }
199
+ }
200
+ end
210
201
 
211
- # Properties that should not be used in imports. They are reserved for use by Hyrax.
212
- conf.reserved_properties = %w[
213
- create_date
214
- modified_date
215
- date_modified
216
- date_uploaded
217
- depositor
218
- arkivo_checksum
219
- has_model
220
- head
221
- label
222
- import_url
223
- on_behalf_of
224
- proxy_depositor
225
- owner
226
- state
227
- tail
228
- original_url
229
- relative_path
230
- ]
202
+ # Properties that should not be used in imports. They are reserved for use by Hyrax.
203
+ conf.reserved_properties = %w[
204
+ create_date
205
+ modified_date
206
+ date_modified
207
+ date_uploaded
208
+ depositor
209
+ arkivo_checksum
210
+ has_model
211
+ head
212
+ label
213
+ import_url
214
+ on_behalf_of
215
+ proxy_depositor
216
+ owner
217
+ state
218
+ tail
219
+ original_url
220
+ relative_path
221
+ ]
231
222
 
232
- # List of Questioning Authority properties that are controlled via YAML files in
233
- # the config/authorities/ directory. For example, the :rights_statement property
234
- # is controlled by the active terms in config/authorities/rights_statements.yml
235
- conf.qa_controlled_properties = %w[rights_statement license]
236
- end
223
+ # List of Questioning Authority properties that are controlled via YAML files in
224
+ # the config/authorities/ directory. For example, the :rights_statement property
225
+ # is controlled by the active terms in config/authorities/rights_statements.yml
226
+ conf.qa_controlled_properties = %w[rights_statement license]
227
+ end
237
228
 
238
- def api_definition
239
- @api_definition ||= ActiveSupport::HashWithIndifferentAccess.new(
240
- YAML.safe_load(
241
- ERB.new(
242
- File.read(Rails.root.join('config', 'bulkrax_api.yml'))
243
- ).result
244
- )
245
- )
246
- end
229
+ def api_definition
230
+ @api_definition ||= ActiveSupport::HashWithIndifferentAccess.new(
231
+ YAML.safe_load(
232
+ ERB.new(
233
+ File.read(Rails.root.join('config', 'bulkrax_api.yml'))
234
+ ).result
235
+ )
236
+ )
237
+ end
247
238
 
248
- DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON = ' | '
249
- # Specify the delimiter for joining an attribute's multi-value array into a string.
250
- #
251
- # @note the specific delimiter should likely be present in the multi_value_element_split_on
252
- # expression.
253
- def multi_value_element_join_on
254
- @multi_value_element_join_on ||= DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON
255
- end
239
+ DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON = ' | '
240
+ # Specify the delimiter for joining an attribute's multi-value array into a string.
241
+ #
242
+ # @note the specific delimiter should likely be present in the multi_value_element_split_on
243
+ # expression.
244
+ def multi_value_element_join_on
245
+ @multi_value_element_join_on ||= DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON
246
+ end
256
247
 
257
- DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON = /\s*[:;|]\s*/.freeze
258
- # @return [RegexClass] the regular express to use to "split" an attribute's values. If set to
259
- # `true` use the DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON.
260
- #
261
- # @note The "true" value is to preserve backwards compatibility.
262
- # @see DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON
248
+ DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON = /\s*[:;|]\s*/.freeze
249
+ # @return [RegexClass] the regular express to use to "split" an attribute's values. If set to
250
+ # `true` use the DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON.
251
+ #
252
+ # @note The "true" value is to preserve backwards compatibility.
253
+ # @see DEFAULT_MULTI_VALUE_ELEMENT_JOIN_ON
263
254
  def multi_value_element_split_on
264
- if @multi_value_element_join_on.is_a?(TrueClass)
265
- DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON
255
+ if @multi_value_element_join_on.is_a?(TrueClass)
256
+ DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON
266
257
  else
267
- @multi_value_element_split_on ||= DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON
258
+ @multi_value_element_split_on ||= DEFAULT_MULTI_VALUE_ELEMENT_SPLIT_ON
268
259
  end
269
260
  end
270
261
 
271
- # Responsible for stripping hidden characters from the given string.
272
- #
273
- # @param value [#to_s]
274
- # @return [String] with hidden characters removed
275
- #
276
- # @see https://github.com/samvera-labs/bulkrax/issues/688
277
- def normalize_string(value)
278
- # Removing [Byte Order Mark (BOM)](https://en.wikipedia.org/wiki/Byte_order_mark)
279
- value.to_s.delete("\xEF\xBB\xBF")
280
- end
262
+ # Responsible for stripping hidden characters from the given string.
263
+ #
264
+ # @param value [#to_s]
265
+ # @return [String] with hidden characters removed
266
+ #
267
+ # @see https://github.com/samvera-labs/bulkrax/issues/688
268
+ def normalize_string(value)
269
+ # Removing [Byte Order Mark (BOM)](https://en.wikipedia.org/wiki/Byte_order_mark)
270
+ value.to_s.delete("\xEF\xBB\xBF")
271
+ end
281
272
 
282
- def fallback_user_for_importer_exporter_processing
283
- return User.batch_user if defined?(Hyrax) && User.respond_to?(:batch_user)
273
+ def fallback_user_for_importer_exporter_processing
274
+ return User.batch_user if defined?(Hyrax) && User.respond_to?(:batch_user)
284
275
 
285
- raise "We have no fallback user available for Bulkrax.fallback_user_for_importer_exporter_processing"
286
- end
276
+ raise "We have no fallback user available for Bulkrax.fallback_user_for_importer_exporter_processing"
277
+ end
287
278
 
288
- # This class confirms to the Active::Support.serialize interface. It's job is to ensure that we
289
- # don't have keys with the tricksy Byte Order Mark character.
290
- #
291
- # @see https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize
292
- class NormalizedJson
279
+ # This class confirms to the Active::Support.serialize interface. It's job is to ensure that we
280
+ # don't have keys with the tricksy Byte Order Mark character.
281
+ #
282
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize
283
+ class NormalizedJson
293
284
  def self.normalize_keys(hash)
294
285
  return hash unless hash.respond_to?(:each_pair)
295
286
  returning_value = {}
@@ -301,18 +292,18 @@ module Bulkrax
301
292
 
302
293
  # When we write the serialized data to the database, we "dump" the value into that database
303
294
  # column.
304
- def self.dump(value)
305
- JSON.dump(normalize_keys(value))
306
- end
295
+ def self.dump(value)
296
+ JSON.dump(normalize_keys(value))
297
+ end
307
298
 
308
299
  # When we load the serialized data from the database, we pass the database's value into "load"
309
300
  # function.
310
301
  #
311
302
  # rubocop:disable Security/JSONLoad
312
- def self.load(string)
313
- normalize_keys(JSON.load(string))
314
- end
303
+ def self.load(string)
304
+ normalize_keys(JSON.load(string))
305
+ end
315
306
  # rubocop:enable Security/JSONLoad
316
- end
307
+ end
317
308
  end
318
- # rubocop:disable Metrics/ModuleLength
309
+ # rubocop:disable Metrics/ModuleLength
@@ -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.3.1
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Kaufman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-14 00:00:00.000000000 Z
11
+ date: 2023-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails