bulkrax 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +205 -0
  3. data/README.md +202 -0
  4. data/Rakefile +42 -0
  5. data/app/assets/config/bulkrax_manifest.js +2 -0
  6. data/app/assets/javascripts/bulkrax/application.js +14 -0
  7. data/app/assets/javascripts/bulkrax/bulkrax.js +11 -0
  8. data/app/assets/javascripts/bulkrax/entries.js +15 -0
  9. data/app/assets/javascripts/bulkrax/exporters.js +60 -0
  10. data/app/assets/javascripts/bulkrax/importers.js.erb +166 -0
  11. data/app/assets/stylesheets/bulkrax/accordion.scss +40 -0
  12. data/app/assets/stylesheets/bulkrax/application.css +15 -0
  13. data/app/assets/stylesheets/bulkrax/coderay.scss +264 -0
  14. data/app/assets/stylesheets/bulkrax/import_export.scss +37 -0
  15. data/app/controllers/bulkrax/application_controller.rb +8 -0
  16. data/app/controllers/bulkrax/entries_controller.rb +44 -0
  17. data/app/controllers/bulkrax/exporters_controller.rb +125 -0
  18. data/app/controllers/bulkrax/importers_controller.rb +315 -0
  19. data/app/controllers/concerns/bulkrax/api.rb +29 -0
  20. data/app/factories/bulkrax/object_factory.rb +230 -0
  21. data/app/helpers/bulkrax/application_helper.rb +15 -0
  22. data/app/helpers/bulkrax/exporters_helper.rb +6 -0
  23. data/app/helpers/bulkrax/importers_helper.rb +13 -0
  24. data/app/helpers/bulkrax/validation_helper.rb +153 -0
  25. data/app/jobs/bulkrax/application_job.rb +6 -0
  26. data/app/jobs/bulkrax/child_relationships_job.rb +128 -0
  27. data/app/jobs/bulkrax/delete_work_job.rb +16 -0
  28. data/app/jobs/bulkrax/download_cloud_file_job.rb +18 -0
  29. data/app/jobs/bulkrax/export_work_job.rb +37 -0
  30. data/app/jobs/bulkrax/exporter_job.rb +14 -0
  31. data/app/jobs/bulkrax/import_work_collection_job.rb +41 -0
  32. data/app/jobs/bulkrax/import_work_job.rb +32 -0
  33. data/app/jobs/bulkrax/importer_job.rb +26 -0
  34. data/app/mailers/bulkrax/application_mailer.rb +8 -0
  35. data/app/matchers/bulkrax/application_matcher.rb +113 -0
  36. data/app/matchers/bulkrax/bagit_matcher.rb +6 -0
  37. data/app/matchers/bulkrax/csv_matcher.rb +6 -0
  38. data/app/matchers/bulkrax/oai_matcher.rb +6 -0
  39. data/app/models/bulkrax/application_record.rb +7 -0
  40. data/app/models/bulkrax/csv_collection_entry.rb +19 -0
  41. data/app/models/bulkrax/csv_entry.rb +163 -0
  42. data/app/models/bulkrax/entry.rb +104 -0
  43. data/app/models/bulkrax/exporter.rb +122 -0
  44. data/app/models/bulkrax/exporter_run.rb +7 -0
  45. data/app/models/bulkrax/import_failed.rb +13 -0
  46. data/app/models/bulkrax/importer.rb +155 -0
  47. data/app/models/bulkrax/importer_run.rb +8 -0
  48. data/app/models/bulkrax/oai_dc_entry.rb +6 -0
  49. data/app/models/bulkrax/oai_entry.rb +74 -0
  50. data/app/models/bulkrax/oai_qualified_dc_entry.rb +6 -0
  51. data/app/models/bulkrax/oai_set_entry.rb +19 -0
  52. data/app/models/bulkrax/rdf_collection_entry.rb +19 -0
  53. data/app/models/bulkrax/rdf_entry.rb +90 -0
  54. data/app/models/bulkrax/status.rb +25 -0
  55. data/app/models/bulkrax/xml_entry.rb +73 -0
  56. data/app/models/concerns/bulkrax/download_behavior.rb +61 -0
  57. data/app/models/concerns/bulkrax/errored_entries.rb +45 -0
  58. data/app/models/concerns/bulkrax/export_behavior.rb +58 -0
  59. data/app/models/concerns/bulkrax/file_factory.rb +140 -0
  60. data/app/models/concerns/bulkrax/has_local_processing.rb +7 -0
  61. data/app/models/concerns/bulkrax/has_matchers.rb +155 -0
  62. data/app/models/concerns/bulkrax/import_behavior.rb +90 -0
  63. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +34 -0
  64. data/app/models/concerns/bulkrax/status_info.rb +56 -0
  65. data/app/parsers/bulkrax/application_parser.rb +299 -0
  66. data/app/parsers/bulkrax/bagit_parser.rb +157 -0
  67. data/app/parsers/bulkrax/csv_parser.rb +266 -0
  68. data/app/parsers/bulkrax/oai_dc_parser.rb +130 -0
  69. data/app/parsers/bulkrax/oai_qualified_dc_parser.rb +9 -0
  70. data/app/parsers/bulkrax/xml_parser.rb +103 -0
  71. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +19 -0
  72. data/app/views/bulkrax/entries/_raw_metadata.html.erb +19 -0
  73. data/app/views/bulkrax/entries/show.html.erb +63 -0
  74. data/app/views/bulkrax/exporters/_form.html.erb +120 -0
  75. data/app/views/bulkrax/exporters/edit.html.erb +23 -0
  76. data/app/views/bulkrax/exporters/index.html.erb +67 -0
  77. data/app/views/bulkrax/exporters/new.html.erb +23 -0
  78. data/app/views/bulkrax/exporters/show.html.erb +124 -0
  79. data/app/views/bulkrax/importers/_bagit_fields.html.erb +54 -0
  80. data/app/views/bulkrax/importers/_browse_everything.html.erb +12 -0
  81. data/app/views/bulkrax/importers/_csv_fields.html.erb +39 -0
  82. data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +16 -0
  83. data/app/views/bulkrax/importers/_form.html.erb +35 -0
  84. data/app/views/bulkrax/importers/_oai_fields.html.erb +42 -0
  85. data/app/views/bulkrax/importers/_xml_fields.html.erb +60 -0
  86. data/app/views/bulkrax/importers/edit.html.erb +20 -0
  87. data/app/views/bulkrax/importers/index.html.erb +77 -0
  88. data/app/views/bulkrax/importers/new.html.erb +25 -0
  89. data/app/views/bulkrax/importers/show.html.erb +175 -0
  90. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +37 -0
  91. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +52 -0
  92. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +39 -0
  93. data/app/views/hyrax/dashboard/sidebar/_bulkrax_sidebar_additions.html.erb +6 -0
  94. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +19 -0
  95. data/app/views/layouts/bulkrax/application.html.erb +14 -0
  96. data/config/locales/bulkrax.en.yml +36 -0
  97. data/config/routes.rb +18 -0
  98. data/db/migrate/20181011230201_create_bulkrax_importers.rb +18 -0
  99. data/db/migrate/20181011230228_create_bulkrax_importer_runs.rb +16 -0
  100. data/db/migrate/20190325183136_create_bulkrax_entries.rb +16 -0
  101. data/db/migrate/20190601221109_add_status_to_entry.rb +9 -0
  102. data/db/migrate/20190715161939_add_collections_to_importer_runs.rb +6 -0
  103. data/db/migrate/20190715162044_change_collection_ids_on_entries.rb +5 -0
  104. data/db/migrate/20190729124607_create_bulkrax_exporters.rb +19 -0
  105. data/db/migrate/20190729134158_create_bulkrax_exporter_runs.rb +14 -0
  106. data/db/migrate/20190731114016_change_importer_and_exporter_to_polymorphic.rb +12 -0
  107. data/db/migrate/20191203225129_add_total_collection_records_to_importer_runs.rb +5 -0
  108. data/db/migrate/20191204191623_add_children_to_importer_runs.rb +6 -0
  109. data/db/migrate/20191204223857_change_total_records_to_total_work_entries.rb +6 -0
  110. data/db/migrate/20191212155530_change_entry_last_error.rb +19 -0
  111. data/db/migrate/20200108194557_add_validate_only_to_bulkrax_importers.rb +5 -0
  112. data/db/migrate/20200301232856_add_status_to_importers.rb +9 -0
  113. data/db/migrate/20200312190638_remove_foreign_key_from_bulkrax_entries.rb +5 -0
  114. data/db/migrate/20200326235838_add_status_to_exporters.rb +7 -0
  115. data/db/migrate/20200601204556_add_invalid_record_to_importer_run.rb +5 -0
  116. data/db/migrate/20200818055819_create_bulkrax_statuses.rb +18 -0
  117. data/db/migrate/20200819054016_move_to_statuses.rb +30 -0
  118. data/db/migrate/20201106014204_add_date_filter_and_status_to_bulkrax_exporters.rb +7 -0
  119. data/db/migrate/20201117220007_add_workflow_status_to_bulkrax_exporter.rb +5 -0
  120. data/db/migrate/20210806044408_remove_unused_last_error.rb +7 -0
  121. data/db/migrate/20210806065737_increase_text_sizes.rb +12 -0
  122. data/lib/bulkrax.rb +161 -0
  123. data/lib/bulkrax/engine.rb +37 -0
  124. data/lib/bulkrax/version.rb +5 -0
  125. data/lib/generators/bulkrax/install_generator.rb +80 -0
  126. data/lib/generators/bulkrax/templates/README +3 -0
  127. data/lib/generators/bulkrax/templates/app/assets/images/bulkrax/removed.png +0 -0
  128. data/lib/generators/bulkrax/templates/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  129. data/lib/generators/bulkrax/templates/bin/importer +140 -0
  130. data/lib/generators/bulkrax/templates/config/bulkrax_api.yml +84 -0
  131. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +72 -0
  132. data/lib/tasks/bulkrax_tasks.rake +6 -0
  133. metadata +388 -0
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class BagitMatcher < ApplicationMatcher
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class CsvMatcher < ApplicationMatcher
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class OaiMatcher < ApplicationMatcher
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class CsvCollectionEntry < CsvEntry
5
+ def factory_class
6
+ Collection
7
+ end
8
+
9
+ def build_metadata
10
+ self.parsed_metadata = self.raw_metadata
11
+ add_local
12
+ return self.parsed_metadata
13
+ end
14
+
15
+ def collections_created?
16
+ true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'csv'
4
+
5
+ module Bulkrax
6
+ class CsvEntry < Entry
7
+ serialize :raw_metadata, JSON
8
+
9
+ def self.fields_from_data(data)
10
+ data.headers.flatten.compact.uniq
11
+ end
12
+
13
+ # there's a risk that this reads the whole file into memory and could cause a memory leak
14
+ def self.read_data(path)
15
+ raise StandardError, 'CSV path empty' if path.blank?
16
+ CSV.read(path,
17
+ headers: true,
18
+ header_converters: :symbol,
19
+ encoding: 'utf-8')
20
+ end
21
+
22
+ def self.data_for_entry(data, _source_id)
23
+ # If a multi-line CSV data is passed, grab the first row
24
+ data = data.first if data.is_a?(CSV::Table)
25
+ # model has to be separated so that it doesn't get mistranslated by to_h
26
+ raw_data = data.to_h
27
+ raw_data[:model] = data[:model]
28
+ # If the collection field mapping is not 'collection', add 'collection' - the parser needs it
29
+ raw_data[:collection] = raw_data[collection_field.to_sym] if raw_data.keys.include?(collection_field.to_sym) && collection_field != 'collection'
30
+ # If the children field mapping is not 'children', add 'children' - the parser needs it
31
+ raw_data[:children] = raw_data[collection_field.to_sym] if raw_data.keys.include?(children_field.to_sym) && children_field != 'children'
32
+ return raw_data
33
+ end
34
+
35
+ def self.collection_field
36
+ Bulkrax.collection_field_mapping[self.class.to_s] || 'collection'
37
+ end
38
+
39
+ def self.children_field
40
+ Bulkrax.parent_child_field_mapping[self.to_s] || 'children'
41
+ end
42
+
43
+ def keys_without_numbers(keys)
44
+ keys.map { |key| key_without_numbers(key) }
45
+ end
46
+
47
+ def key_without_numbers(key)
48
+ key.gsub(/_\d+/, '').sub(/^\d+_/, '')
49
+ end
50
+
51
+ def build_metadata
52
+ raise StandardError, 'Record not found' if record.nil?
53
+ raise StandardError, "Missing required elements, missing element(s) are: #{importerexporter.parser.missing_elements(keys_without_numbers(record.keys)).join(', ')}" unless importerexporter.parser.required_elements?(keys_without_numbers(record.keys))
54
+
55
+ self.parsed_metadata = {}
56
+ self.parsed_metadata[work_identifier] = [record[source_identifier]]
57
+ record.each do |key, value|
58
+ next if key == 'collection'
59
+
60
+ index = key[/\d+/].to_i - 1 if key[/\d+/].to_i != 0
61
+ add_metadata(key_without_numbers(key), value, index)
62
+ end
63
+ add_file
64
+ add_visibility
65
+ add_rights_statement
66
+ add_admin_set_id
67
+ add_collections
68
+ add_local
69
+ self.parsed_metadata
70
+ end
71
+
72
+ def add_file
73
+ self.parsed_metadata['file'] ||= []
74
+ if record['file']&.is_a?(String)
75
+ self.parsed_metadata['file'] = record['file'].split(/\s*[;|]\s*/)
76
+ elsif record['file'].is_a?(Array)
77
+ self.parsed_metadata['file'] = record['file']
78
+ end
79
+ self.parsed_metadata['file'] = self.parsed_metadata['file'].map { |f| path_to_file(f.tr(' ', '_')) }
80
+ end
81
+
82
+ def build_export_metadata
83
+ # make_round_trippable
84
+ self.parsed_metadata = {}
85
+ self.parsed_metadata['id'] = hyrax_record.id
86
+ self.parsed_metadata[source_identifier] = hyrax_record.send(work_identifier)
87
+ self.parsed_metadata['model'] = hyrax_record.has_model.first
88
+ build_mapping_metadata
89
+ self.parsed_metadata['collections'] = hyrax_record.member_of_collection_ids.join('; ')
90
+ unless hyrax_record.is_a?(Collection)
91
+ self.parsed_metadata['file'] = hyrax_record.file_sets.map { |fs| filename(fs).to_s if filename(fs).present? }.compact.join('; ')
92
+ end
93
+ self.parsed_metadata
94
+ end
95
+
96
+ def build_mapping_metadata
97
+ mapping.each do |key, value|
98
+ next if Bulkrax.reserved_properties.include?(key) && !field_supported?(key)
99
+ next if key == "model"
100
+ next unless hyrax_record.respond_to?(key.to_s)
101
+ data = hyrax_record.send(key.to_s)
102
+ if data.is_a?(ActiveTriples::Relation)
103
+ self.parsed_metadata[key] = data.map { |d| prepare_export_data(d) }.join('; ').to_s unless value[:excluded]
104
+ else
105
+ self.parsed_metadata[key] = prepare_export_data(data)
106
+ end
107
+ end
108
+ end
109
+
110
+ def prepare_export_data(datum)
111
+ if datum.is_a?(ActiveTriples::Resource)
112
+ datum.to_uri.to_s
113
+ else
114
+ datum
115
+ end
116
+ end
117
+
118
+ # In order for the existing exported hyrax_record, to be updated by a re-import
119
+ # we need a unique value in system_identifier
120
+ # add the existing hyrax_record id to system_identifier
121
+ def make_round_trippable
122
+ values = hyrax_record.send(work_identifier.to_s).to_a
123
+ values << hyrax_record.id
124
+ hyrax_record.send("#{work_identifier}=", values)
125
+ hyrax_record.save
126
+ end
127
+
128
+ def record
129
+ @record ||= raw_metadata
130
+ end
131
+
132
+ def self.matcher_class
133
+ Bulkrax::CsvMatcher
134
+ end
135
+
136
+ def collections_created?
137
+ return true if record[self.class.collection_field].blank?
138
+ record[self.class.collection_field].split(/\s*[:;|]\s*/).length == self.collection_ids.length
139
+ end
140
+
141
+ def find_or_create_collection_ids
142
+ return self.collection_ids if collections_created?
143
+ valid_system_id(Collection)
144
+ if record[self.class.collection_field].present?
145
+ record[self.class.collection_field].split(/\s*[:;|]\s*/).each do |collection|
146
+ c = find_collection(collection)
147
+ self.collection_ids << c.id unless c.blank? || self.collection_ids.include?(c.id)
148
+ end
149
+ end
150
+ self.collection_ids
151
+ end
152
+
153
+ # If only filename is given, construct the path (/files/my_file)
154
+ def path_to_file(file)
155
+ # return if we already have the full file path
156
+ return file if File.exist?(file)
157
+ path = importerexporter.parser.path_to_files
158
+ f = File.join(path, file)
159
+ return f if File.exist?(f)
160
+ raise "File #{f} does not exist"
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ # Custom error class for collections_created?
5
+ class CollectionsCreatedError < RuntimeError; end
6
+ class OAIError < RuntimeError; end
7
+ class Entry < ApplicationRecord
8
+ include Bulkrax::HasMatchers
9
+ include Bulkrax::ImportBehavior
10
+ include Bulkrax::ExportBehavior
11
+ include Bulkrax::StatusInfo
12
+ include Bulkrax::HasLocalProcessing
13
+
14
+ belongs_to :importerexporter, polymorphic: true
15
+ alias importer importerexporter
16
+ alias exporter importerexporter
17
+
18
+ serialize :parsed_metadata, JSON
19
+ # Do not serialize raw_metadata as so we can support xml or other formats
20
+ serialize :collection_ids, Array
21
+
22
+ paginates_per 5
23
+
24
+ attr_accessor :all_attrs
25
+
26
+ delegate :parser, :mapping, :replace_files, :update_files, to: :importerexporter
27
+
28
+ delegate :client,
29
+ :collection_name,
30
+ :user,
31
+ to: :parser
32
+
33
+ # Retrieve fields from the file
34
+ # @param data - the source data
35
+ # @return Array
36
+ def self.fields_from_data(_data)
37
+ raise StandardError, 'Not Implemented'
38
+ end
39
+
40
+ # Read the data from the supplied path
41
+ # @param path - path to the data file
42
+ # @return the data from the file
43
+ def self.read_data(_path)
44
+ raise StandardError, 'Not Implemented'
45
+ end
46
+
47
+ # Returns formatted data from the given file for a single Entry
48
+ # @param data - the data from the metadata file
49
+ # @param path - the path to the metadata file (used by some entries to get the file_paths for import)
50
+ # @return Hash containing the data (the entry build_metadata method will know what to expect in the hash)
51
+ def self.data_for_entry(_data, _source_id)
52
+ raise StandardError, 'Not Implemented'
53
+ end
54
+
55
+ def source_identifier
56
+ parser&.source_identifier&.to_s || 'source_identifier'
57
+ end
58
+
59
+ def work_identifier
60
+ parser&.work_identifier&.to_s || 'source'
61
+ end
62
+
63
+ def self.collection_field
64
+ Bulkrax.collection_field_mapping[self.to_s]
65
+ end
66
+
67
+ def self.children_field
68
+ Bulkrax.parent_child_field_mapping[self.to_s]
69
+ end
70
+
71
+ def build
72
+ return if type.nil?
73
+ self.save if self.new_record? # must be saved for statuses
74
+
75
+ return build_for_importer if importer?
76
+ return build_for_exporter if exporter?
77
+ end
78
+
79
+ def importer?
80
+ self.importerexporter_type == 'Bulkrax::Importer'
81
+ end
82
+
83
+ def exporter?
84
+ self.importerexporter_type == 'Bulkrax::Exporter'
85
+ end
86
+
87
+ def valid_system_id(model_class)
88
+ return true if model_class.properties.keys.include?(work_identifier)
89
+ raise(
90
+ "#{model_class} does not implement the system_identifier_field: #{work_identifier}"
91
+ )
92
+ end
93
+
94
+ def last_run
95
+ self.importerexporter&.last_run
96
+ end
97
+
98
+ def find_collection(collection_identifier)
99
+ Collection.where(
100
+ work_identifier => collection_identifier
101
+ ).detect { |m| m.send(work_identifier).include?(collection_identifier) }
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+ module Bulkrax
3
+ class Exporter < ApplicationRecord
4
+ include Bulkrax::ImporterExporterBehavior
5
+ include Bulkrax::StatusInfo
6
+
7
+ serialize :parser_fields, JSON
8
+ serialize :field_mapping, JSON
9
+
10
+ belongs_to :user
11
+ has_many :exporter_runs, dependent: :destroy
12
+ has_many :entries, as: :importerexporter, dependent: :destroy
13
+
14
+ validates :name, presence: true
15
+ validates :parser_klass, presence: true
16
+
17
+ delegate :write, :create_from_collection, :create_from_importer, :create_from_worktype, to: :parser
18
+
19
+ def export
20
+ current_run && setup_export_path
21
+ case self.export_from
22
+ when 'collection'
23
+ create_from_collection
24
+ when 'importer'
25
+ create_from_importer
26
+ when 'worktype'
27
+ create_from_worktype
28
+ end
29
+ rescue StandardError => e
30
+ status_info(e)
31
+ end
32
+
33
+ # #export_source accessors
34
+ # Used in form to prevent it from getting confused as to which value to populate #export_source with.
35
+ # Also, used to display the correct selected value when rendering edit form.
36
+ def export_source_importer
37
+ self.export_source if self.export_from == 'importer'
38
+ end
39
+
40
+ def export_source_collection
41
+ self.export_source if self.export_from == 'collection'
42
+ end
43
+
44
+ def export_source_worktype
45
+ self.export_source if self.export_from == 'worktype'
46
+ end
47
+
48
+ def date_filter
49
+ self.start_date.present? || self.finish_date.present?
50
+ end
51
+
52
+ def work_visibility_list
53
+ [
54
+ ['Any', ''],
55
+ [I18n.t('hyrax.visibility.open.text'), Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC],
56
+ [I18n.t('hyrax.visibility.restricted.text'), Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE],
57
+ [I18n.t('hyrax.visibility.authenticated.text', institution: I18n.t('hyrax.institution_name')), Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED]
58
+ ]
59
+ end
60
+
61
+ def workflow_status_list
62
+ Sipity::WorkflowState.all.map { |s| [s.name&.titleize, s.name] }.uniq
63
+ end
64
+
65
+ # If field_mapping is empty, setup a default based on the export_properties
66
+ def mapping
67
+ @mapping ||= self.field_mapping ||
68
+ ActiveSupport::HashWithIndifferentAccess.new(
69
+ export_properties.map do |m|
70
+ Bulkrax.default_field_mapping.call(m)
71
+ end.inject(:merge)
72
+ ) ||
73
+ [{}]
74
+ end
75
+
76
+ def export_from_list
77
+ [
78
+ [I18n.t('bulkrax.exporter.labels.importer'), 'importer'],
79
+ [I18n.t('bulkrax.exporter.labels.collection'), 'collection'],
80
+ [I18n.t('bulkrax.exporter.labels.worktype'), 'worktype']
81
+ ]
82
+ end
83
+
84
+ def export_type_list
85
+ [
86
+ [I18n.t('bulkrax.exporter.labels.metadata'), 'metadata'],
87
+ [I18n.t('bulkrax.exporter.labels.full'), 'full']
88
+ ]
89
+ end
90
+
91
+ def importers_list
92
+ Importer.all.map { |i| [i.name, i.id] }
93
+ end
94
+
95
+ def current_run
96
+ @current_run ||= self.exporter_runs.create!(total_work_entries: self.limit || parser.total)
97
+ end
98
+
99
+ def last_run
100
+ @last_run ||= self.exporter_runs.last
101
+ end
102
+
103
+ def setup_export_path
104
+ FileUtils.mkdir_p(exporter_export_path) unless File.exist?(exporter_export_path)
105
+ end
106
+
107
+ def exporter_export_path
108
+ @exporter_export_path ||= File.join(Bulkrax.export_path, self.id.to_s, self.exporter_runs.last.id.to_s)
109
+ end
110
+
111
+ def exporter_export_zip_path
112
+ @exporter_export_zip_path ||= File.join(Bulkrax.export_path, "export_#{self.id}_#{self.exporter_runs.last.id}.zip")
113
+ rescue
114
+ @exporter_export_zip_path ||= File.join(Bulkrax.export_path, "export_#{self.id}_0.zip")
115
+ end
116
+
117
+ def export_properties
118
+ properties = Hyrax.config.registered_curation_concern_types.map { |work| work.constantize.properties.keys }.flatten.uniq.sort
119
+ properties.reject { |prop| Bulkrax.reserved_properties.include?(prop) }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class ExporterRun < ApplicationRecord
5
+ belongs_to :exporter
6
+ end
7
+ end