geoblacklight_admin 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -11
- data/Rakefile +83 -47
- data/app/assets/javascripts/geoblacklight_admin/chosen.js +1 -0
- data/app/assets/stylesheets/geoblacklight_admin/_core.scss +24 -0
- data/app/assets/stylesheets/geoblacklight_admin/modules/_nav.scss +0 -5
- data/app/assets/stylesheets/geoblacklight_admin/modules/_tables.scss +1 -1
- data/app/controllers/admin/admin_controller.rb +16 -0
- data/app/controllers/admin/advanced_search_controller.rb +7 -1
- data/app/controllers/admin/assets_controller.rb +47 -32
- data/app/controllers/admin/bookmarks_controller.rb +17 -5
- data/app/controllers/admin/bulk_actions_controller.rb +32 -1
- data/app/controllers/admin/document_accesses_controller.rb +38 -0
- data/app/controllers/admin/document_assets_controller.rb +47 -89
- data/app/controllers/admin/document_distributions_controller.rb +172 -0
- data/app/controllers/admin/documents_controller.rb +43 -57
- data/app/controllers/admin/elements_controller.rb +24 -0
- data/app/controllers/admin/form_elements_controller.rb +33 -0
- data/app/controllers/admin/ids_controller.rb +6 -0
- data/app/controllers/admin/import_documents_controller.rb +11 -1
- data/app/controllers/admin/imports_controller.rb +34 -4
- data/app/controllers/admin/mappings_controller.rb +15 -0
- data/app/controllers/admin/notifications_controller.rb +27 -0
- data/app/controllers/admin/reference_types_controller.rb +106 -0
- data/app/controllers/admin/search_controller.rb +7 -0
- data/app/controllers/admin/users_controller.rb +10 -0
- data/app/helpers/asset_helper.rb +6 -0
- data/app/helpers/bulk_actions_helper.rb +10 -1
- data/app/helpers/document_helper.rb +36 -0
- data/app/helpers/geoblacklight_admin_helper.rb +88 -8
- data/app/helpers/mappings_helper.rb +26 -0
- data/app/indexers/document_indexer.rb +22 -2
- data/app/javascript/channels/consumer.js +6 -0
- data/app/javascript/channels/export_channel.js +30 -0
- data/app/javascript/channels/index.js +3 -0
- data/app/javascript/controllers/results_controller.js +14 -0
- data/app/javascript/index.js +8 -2
- data/app/jobs/bulk_action_revert_document_job.rb +4 -12
- data/app/jobs/bulk_action_run_document_job.rb +2 -10
- data/app/jobs/export_job.rb +35 -8
- data/app/jobs/geoblacklight_admin/delete_thumbnail_job.rb +19 -0
- data/app/jobs/geoblacklight_admin/remove_parent_dct_references_uri_job.rb +16 -0
- data/app/jobs/geoblacklight_admin/set_parent_dct_references_uri_job.rb +17 -0
- data/app/jobs/geoblacklight_admin/store_image_job.rb +22 -0
- data/app/jobs/import_document_job.rb +1 -4
- data/app/jobs/import_run_job.rb +1 -1
- data/app/models/admin/bookmark.rb +1 -1
- data/app/models/asset.rb +20 -0
- data/app/models/bulk_action.rb +2 -1
- data/app/models/bulk_actions/change_publication_state.rb +0 -25
- data/app/models/bulk_actions/delete_thumbnails.rb +6 -0
- data/app/models/bulk_actions/draft_document.rb +6 -0
- data/app/models/bulk_actions/harvest_thumbnails.rb +6 -0
- data/app/models/bulk_actions/publish_document.rb +6 -0
- data/app/models/bulk_actions/unpublish_document.rb +6 -0
- data/app/models/document/geom_validator.rb +8 -0
- data/app/models/document/reference.rb +65 -65
- data/app/models/document.rb +129 -72
- data/app/models/document_distribution.rb +145 -0
- data/app/models/element.rb +2 -0
- data/app/models/geoblacklight_admin/schema.rb +10 -2
- data/app/models/import/csv_duplicates_validator.rb +2 -0
- data/app/models/import/csv_header_validator.rb +3 -1
- data/app/models/import_btaa_aardvark.rb +2 -2
- data/app/models/import_document_state_machine.rb +1 -0
- data/app/models/import_gblv1.rb +2 -2
- data/app/models/reference_type.rb +40 -0
- data/app/models/user.rb +4 -2
- data/app/services/export_csv_document_distributions_service.rb +61 -0
- data/app/services/geoblacklight_admin/image_service/iiif_manifest.rb +39 -43
- data/app/services/geoblacklight_admin/image_service/tms.rb +0 -8
- data/app/services/geoblacklight_admin/image_service.rb +1 -1
- data/app/services/geoblacklight_admin/item_viewer.rb +4 -4
- data/app/views/admin/bookmarks/index.html.erb +19 -14
- data/app/views/admin/bulk_actions/show.html.erb +1 -1
- data/app/views/admin/document_accesses/import.html.erb +6 -2
- data/app/views/admin/document_assets/_assets_table.html.erb +49 -0
- data/app/views/admin/document_assets/_form.html.erb +2 -3
- data/app/views/admin/document_assets/index.html.erb +1 -47
- data/app/views/admin/document_distributions/_document_distribution.html.erb +39 -0
- data/app/views/admin/document_distributions/_document_distribution.json.jbuilder +2 -0
- data/app/views/admin/document_distributions/_form.html.erb +34 -0
- data/app/views/admin/document_distributions/destroy_all.html.erb +82 -0
- data/app/views/admin/document_distributions/edit.html.erb +12 -0
- data/app/views/admin/document_distributions/import.html.erb +80 -0
- data/app/views/admin/document_distributions/index.html.erb +143 -0
- data/app/views/admin/document_distributions/index.json.jbuilder +1 -0
- data/app/views/admin/document_distributions/new.html.erb +11 -0
- data/app/views/admin/document_distributions/show.html.erb +10 -0
- data/app/views/admin/document_distributions/show.json.jbuilder +1 -0
- data/app/views/admin/documents/_document.html.erb +1 -3
- data/app/views/admin/documents/_form.html.erb +2 -4
- data/app/views/admin/documents/_form_control.html.erb +5 -2
- data/app/views/admin/documents/_form_nav.html.erb +14 -5
- data/app/views/admin/documents/_form_nav_kithe.html.erb +4 -1
- data/app/views/admin/documents/_json_aardvark.jbuilder +1 -1
- data/app/views/admin/documents/_json_gbl_v1.jbuilder +1 -1
- data/app/views/admin/documents/_result_selected_options.html.erb +5 -2
- data/app/views/admin/documents/admin.html.erb +5 -5
- data/app/views/admin/documents/features/_document_references.html.erb +23 -0
- data/app/views/admin/documents/features/_multiple_download_links.html.erb +29 -26
- data/app/views/admin/ids/fetch.json.jbuilder +0 -2
- data/app/views/admin/ids/index.json.jbuilder +0 -2
- data/app/views/admin/imports/_form.html.erb +1 -1
- data/app/views/admin/imports/show.html.erb +1 -1
- data/app/views/admin/layouts/application.html.erb +4 -2
- data/app/views/admin/mappings/index.html.erb +1 -1
- data/app/views/admin/notifications/_notification.html.haml +29 -28
- data/app/views/admin/reference_types/_form.html.erb +25 -0
- data/app/views/admin/reference_types/_reference_type.html.erb +52 -0
- data/app/views/admin/reference_types/_reference_type.json.jbuilder +2 -0
- data/app/views/admin/reference_types/edit.html.erb +12 -0
- data/app/views/admin/reference_types/index.html.erb +52 -0
- data/app/views/admin/reference_types/index.json.jbuilder +1 -0
- data/app/views/admin/reference_types/new.html.erb +11 -0
- data/app/views/admin/reference_types/show.html.erb +3 -0
- data/app/views/admin/reference_types/show.json.jbuilder +1 -0
- data/app/views/admin/shared/_footer.html.erb +5 -2
- data/app/views/admin/shared/_js_behaviors.html.erb +2 -3
- data/app/views/admin/shared/_navbar.html.erb +9 -2
- data/app/views/admin/users/index.html.erb +0 -1
- data/app/views/catalog/_show_gbl_admin.html.erb +1 -1
- data/config/initializers/defaults.yml +310 -0
- data/config/initializers/rails_config.rb +8 -0
- data/config/locales/documents.en.yml +14 -0
- data/config/routes.rb +30 -5
- data/db/import_references_schema_support.numbers +0 -0
- data/db/migrate/20230316183001_add_geoblacklight_admin_gem.rb +0 -12
- data/db/migrate/20241009200524_create_admin_reference_types.rb +13 -0
- data/db/migrate/20241010161420_create_document_references.rb +14 -0
- data/db/migrate/20241120238823_rename_references_to_distributions.rb +5 -0
- data/db/seeds.rb +5 -0
- data/db/seeds_elements.csv +1 -1
- data/db/seeds_elements.numbers +0 -0
- data/db/seeds_reference_types.csv +29 -0
- data/db/seeds_reference_types.numbers +0 -0
- data/db/structure.sql +1 -38
- data/lib/compose.yml +31 -0
- data/lib/generators/geoblacklight_admin/config_generator.rb +53 -12
- data/lib/generators/geoblacklight_admin/install_generator.rb +8 -0
- data/lib/generators/geoblacklight_admin/templates/btaa_sample_records.csv +5 -0
- data/lib/generators/geoblacklight_admin/templates/config/database.yml +1 -1
- data/lib/generators/geoblacklight_admin/templates/config/initializers/devise.rb +0 -2
- data/lib/generators/geoblacklight_admin/templates/config/initializers/mime_types.rb +1 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/Dockerfile +31 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/compose.yml +42 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/start-server.sh +21 -0
- data/lib/geoblacklight_admin/engine.rb +4 -0
- data/lib/geoblacklight_admin/rake_task.rb +2 -0
- data/lib/geoblacklight_admin/tasks/distributions.rake +69 -0
- data/lib/geoblacklight_admin/tasks/images.rake +1 -0
- data/lib/geoblacklight_admin/tasks/solr.rake +31 -0
- data/lib/geoblacklight_admin/version.rb +1 -1
- data/lib/geoblacklight_admin.rb +4 -0
- metadata +137 -53
- data/app/helpers/import_documents_helper.rb +0 -5
- data/app/javascript/entrypoints/engine.js +0 -8
- data/config/locales/devise_invitable.en.yml +0 -31
- data/lib/generators/geoblacklight_admin/templates/devise/invitations/edit.html.erb +0 -15
- data/lib/generators/geoblacklight_admin/templates/devise/invitations/new.html.erb +0 -15
- data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.html.erb +0 -11
- data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.text.erb +0 -11
data/app/models/document.rb
CHANGED
|
@@ -9,7 +9,7 @@ class Document < Kithe::Work
|
|
|
9
9
|
delegate :viewer_endpoint, to: :item_viewer
|
|
10
10
|
|
|
11
11
|
def item_viewer
|
|
12
|
-
GeoblacklightAdmin::ItemViewer.new(
|
|
12
|
+
GeoblacklightAdmin::ItemViewer.new(distributions)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
attr_accessor :skip_callbacks
|
|
@@ -34,18 +34,20 @@ class Document < Kithe::Work
|
|
|
34
34
|
has_many :document_downloads, primary_key: "friendlier_id", foreign_key: "friendlier_id", autosave: false, dependent: :destroy,
|
|
35
35
|
inverse_of: :document
|
|
36
36
|
|
|
37
|
+
# - DocumentDistributions
|
|
38
|
+
has_many :document_distributions, primary_key: "friendlier_id", foreign_key: "friendlier_id", autosave: false, dependent: :destroy,
|
|
39
|
+
inverse_of: :document
|
|
40
|
+
|
|
37
41
|
# DocumentAssets - Thumbnails, Attachments, etc
|
|
38
42
|
# @TODO: Redundant? Kithe also includes a members association
|
|
39
43
|
def document_assets
|
|
40
44
|
scope = Kithe::Asset
|
|
41
|
-
scope = scope.where(parent_id: id)
|
|
42
|
-
|
|
43
|
-
# scope = scope.page(params[:page]).per(20).order(created_at: :desc)
|
|
45
|
+
scope = scope.where(parent_id: id).order(position: :asc)
|
|
44
46
|
scope.includes(:parent)
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
def
|
|
48
|
-
document_assets.select { |a| a.dct_references_uri_key
|
|
49
|
+
def distributable_assets
|
|
50
|
+
document_assets.select { |a| a.dct_references_uri_key.present? }
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
include Statesman::Adapters::ActiveRecordQueries[
|
|
@@ -87,7 +89,7 @@ class Document < Kithe::Work
|
|
|
87
89
|
|
|
88
90
|
# Downloadable Resouce
|
|
89
91
|
def a_downloadable_resource?
|
|
90
|
-
|
|
92
|
+
distributions_json.include?("downloadUrl")
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
validates_with Document::DateValidator
|
|
@@ -96,55 +98,109 @@ class Document < Kithe::Work
|
|
|
96
98
|
validates_with Document::GeomValidator
|
|
97
99
|
|
|
98
100
|
# Definte our AttrJSON attributes
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
if ActiveRecord::Base.connection.table_exists?("elements")
|
|
102
|
+
Element.all.each do |attribute|
|
|
103
|
+
next if attribute.solr_field == "dct_references_s"
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
if attribute.repeatable?
|
|
106
|
+
attr_json attribute.solr_field.to_sym, attribute.field_type.to_sym, array: true, default: -> { [] }
|
|
107
|
+
else
|
|
108
|
+
attr_json attribute.solr_field.to_sym, attribute.field_type.to_sym, default: ""
|
|
109
|
+
end
|
|
106
110
|
end
|
|
107
111
|
end
|
|
108
112
|
|
|
109
113
|
attr_json :dct_references_s, Document::Reference.to_type, array: true, default: -> { [] }
|
|
110
114
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
# Distributions
|
|
116
|
+
# - BEFORE DocumentDistributions
|
|
117
|
+
# - Use dct_references_s
|
|
118
|
+
# - Use multiple downloads
|
|
119
|
+
# - Use distributable assets
|
|
120
|
+
# - AFTER DocumentDistributions
|
|
121
|
+
# - Use document_distributions
|
|
122
|
+
# - Use distributable assets
|
|
123
|
+
# @TODO: Remove BEFORE path once we've migrated to DocumentDistributions
|
|
124
|
+
def distributions
|
|
125
|
+
distributions = ActiveSupport::HashWithIndifferentAccess.new
|
|
126
|
+
|
|
127
|
+
# AFTER - Add DocumentDistributions to distributions
|
|
128
|
+
if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
129
|
+
distributions = document_distributions.to_aardvark_distributions
|
|
130
|
+
end
|
|
114
131
|
|
|
115
|
-
# Prep value arrays
|
|
132
|
+
# BEFORE - Prep value arrays
|
|
133
|
+
# @TODO: Remove this once we've migrated to DocumentDistributions
|
|
116
134
|
send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
|
|
117
|
-
|
|
135
|
+
if ref.category.present?
|
|
136
|
+
distributions[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] = []
|
|
137
|
+
end
|
|
118
138
|
end
|
|
119
139
|
|
|
120
|
-
# Seed value arrays
|
|
140
|
+
# BEFORE - Seed value arrays
|
|
141
|
+
# @TODO: Remove this once we've migrated to DocumentDistributions
|
|
121
142
|
send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
|
|
122
|
-
|
|
123
|
-
|
|
143
|
+
if ref.category.present?
|
|
144
|
+
distributions[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] << ref.value
|
|
145
|
+
end
|
|
124
146
|
end
|
|
147
|
+
logger.debug("\n\nDocument#distributions > seeded: #{distributions}")
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
149
|
+
# BEFORE - Apply Multiple Downloads
|
|
150
|
+
# @TODO: Remove this once we've migrated to DocumentDistributions
|
|
151
|
+
if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "false"
|
|
152
|
+
distributions = apply_downloads(distributions)
|
|
153
|
+
logger.debug("Document#distributions > downloads: #{distributions}")
|
|
154
|
+
end
|
|
130
155
|
|
|
131
|
-
|
|
156
|
+
# BEFORE & AFTER - Apply Distributable Assets
|
|
157
|
+
distributions = apply_assets(distributions)
|
|
158
|
+
logger.debug("Document#distributions > assets: #{distributions}")
|
|
132
159
|
|
|
133
160
|
# Need to flatten the arrays here to avoid the following potential error:
|
|
134
161
|
# - ArgumentError: Please use symbols for polymorphic route arguments.
|
|
135
162
|
# - Via: app/helpers/geoblacklight_helper.rb:224:in `render_references_url'
|
|
136
|
-
|
|
163
|
+
distributions.each do |key, value|
|
|
137
164
|
next if key == "http://schema.org/downloadUrl"
|
|
138
165
|
if value.is_a?(Array) && value.length == 1
|
|
139
|
-
|
|
166
|
+
distributions[key] = value.first
|
|
140
167
|
end
|
|
141
168
|
end
|
|
142
169
|
|
|
143
|
-
|
|
170
|
+
distributions
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Distributions JSON
|
|
174
|
+
# - Indexes to Solr as dct_distributions_s
|
|
175
|
+
def distributions_json
|
|
176
|
+
if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
177
|
+
logger.debug("Document#distributions_json > using document_distributions")
|
|
178
|
+
distributions = document_distributions.to_aardvark_distributions
|
|
179
|
+
distributions = apply_assets(distributions)
|
|
180
|
+
distributions.to_json
|
|
181
|
+
else
|
|
182
|
+
logger.debug("Document#distributions > #{distributions.inspect}")
|
|
183
|
+
logger.debug("Document#distributions_json > using distributions")
|
|
184
|
+
logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
|
|
185
|
+
self.distributions.to_json
|
|
186
|
+
end
|
|
144
187
|
end
|
|
145
188
|
|
|
146
|
-
def
|
|
147
|
-
|
|
189
|
+
def distributions_csv
|
|
190
|
+
# Initialize CSV
|
|
191
|
+
# - [document_id, category, value, label]
|
|
192
|
+
csv = []
|
|
193
|
+
|
|
194
|
+
distributions.each do |key, value|
|
|
195
|
+
if key == "http://schema.org/downloadUrl"
|
|
196
|
+
value.each do |download|
|
|
197
|
+
csv << [friendlier_id, ReferenceType.find_by(reference_uri: key).name, download["url"], download["label"]]
|
|
198
|
+
end
|
|
199
|
+
else
|
|
200
|
+
csv << [friendlier_id, ReferenceType.find_by(reference_uri: key)&.name, value, nil]
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
csv
|
|
148
204
|
end
|
|
149
205
|
|
|
150
206
|
def asset_label(asset)
|
|
@@ -155,14 +211,33 @@ class Document < Kithe::Work
|
|
|
155
211
|
end
|
|
156
212
|
end
|
|
157
213
|
|
|
158
|
-
|
|
214
|
+
def apply_assets(distributions)
|
|
215
|
+
# Distributable Document Assets
|
|
216
|
+
# - Via DocumentAssets (Assets)
|
|
217
|
+
# - With Downloadable URI
|
|
218
|
+
if distributable_assets.present?
|
|
219
|
+
distributable_assets.each do |asset|
|
|
220
|
+
if asset.dct_references_uri_key == "download"
|
|
221
|
+
distributions["http://schema.org/downloadUrl"] ||= []
|
|
222
|
+
distributions["http://schema.org/downloadUrl"] << asset.to_aardvark_reference["http://schema.org/downloadUrl"]
|
|
223
|
+
else
|
|
224
|
+
distributions.merge!(asset.to_aardvark_reference)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
distributions
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# BEFORE - Apply Downloads
|
|
233
|
+
# @TODO: Remove this once we've migrated to DocumentDistributions
|
|
159
234
|
# 1. Native Aardvark Downloads
|
|
160
235
|
# 2. Multiple Document Download Links
|
|
161
236
|
# 3. Downloadable Document Assets
|
|
162
|
-
def apply_downloads(
|
|
237
|
+
def apply_downloads(distributions)
|
|
163
238
|
multiple_downloads = []
|
|
164
239
|
|
|
165
|
-
dct_downloads =
|
|
240
|
+
dct_downloads = distributions["http://schema.org/downloadUrl"]
|
|
166
241
|
|
|
167
242
|
logger.debug("Document#dct_downloads > init: #{dct_downloads}\n\n")
|
|
168
243
|
|
|
@@ -180,35 +255,21 @@ class Document < Kithe::Work
|
|
|
180
255
|
# Multiple Document Download Links
|
|
181
256
|
# - Via DocumentDownloads
|
|
182
257
|
if document_downloads.present?
|
|
183
|
-
|
|
258
|
+
multiple_downloads_array.each do |download|
|
|
259
|
+
multiple_downloads << download
|
|
260
|
+
end
|
|
184
261
|
end
|
|
185
262
|
|
|
186
263
|
logger.debug("Document#dct_downloads > document_downloads: #{multiple_downloads.inspect}\n\n")
|
|
187
264
|
|
|
188
|
-
|
|
189
|
-
# - Via DocumentAssets (Assets)
|
|
190
|
-
# - With Downloadable URI
|
|
191
|
-
if downloadable_assets.present?
|
|
192
|
-
downloadable_assets.each do |asset|
|
|
193
|
-
logger.debug("\n\n Document#dct_downloads > dupe?: #{multiple_downloads.detect { |d| d[:url].include?(asset.file.url) }}\n\n")
|
|
194
|
-
|
|
195
|
-
if multiple_downloads.detect { |d| d[:url].include?(asset.file.url) }
|
|
196
|
-
logger.debug("\n\n Detected duplicate download URL: #{asset.file.url}\n\n")
|
|
197
|
-
index = multiple_downloads.index { |d| d[:url].include?(asset.file.url) }
|
|
198
|
-
multiple_downloads[index] = {label: asset_label(asset), url: asset.file.url}
|
|
199
|
-
else
|
|
200
|
-
logger.debug("\n\n No duplicate found - Adding downloadable asset: #{asset.file.url}\n\n")
|
|
201
|
-
multiple_downloads << {label: asset_label(asset), url: asset.file.url}
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
265
|
+
multiple_downloads = multiple_downloads.uniq { |d| [d[:label], d[:url]] } unless multiple_downloads.empty?
|
|
205
266
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
references[:"http://schema.org/downloadUrl"] = multiple_downloads.flatten unless multiple_downloads.empty?
|
|
209
|
-
references
|
|
267
|
+
distributions[:"http://schema.org/downloadUrl"] = multiple_downloads.flatten unless multiple_downloads.empty?
|
|
268
|
+
distributions
|
|
210
269
|
end
|
|
211
270
|
|
|
271
|
+
# BEFORE - Multiple Downloads Array
|
|
272
|
+
# @TODO: Remove this once we've migrated to DocumentDistributions
|
|
212
273
|
def multiple_downloads_array
|
|
213
274
|
document_downloads.collect { |d| {label: d.label, url: d.value} }
|
|
214
275
|
end
|
|
@@ -230,14 +291,9 @@ class Document < Kithe::Work
|
|
|
230
291
|
#
|
|
231
292
|
def download_text(format)
|
|
232
293
|
download_format = proper_case_format(format)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
rescue
|
|
237
|
-
# Need to rescue if format doesn't exist
|
|
238
|
-
end
|
|
239
|
-
value = prefix + format.to_s
|
|
240
|
-
value.html_safe
|
|
294
|
+
download_format.to_s.html_safe
|
|
295
|
+
rescue
|
|
296
|
+
format.to_s.html_safe
|
|
241
297
|
end
|
|
242
298
|
|
|
243
299
|
##
|
|
@@ -257,7 +313,7 @@ class Document < Kithe::Work
|
|
|
257
313
|
|
|
258
314
|
def local?
|
|
259
315
|
local = send(Settings.FIELDS.PROVIDER) || ""
|
|
260
|
-
local.casecmp(Settings.
|
|
316
|
+
local.casecmp(Settings.INSTITUTION)&.zero?
|
|
261
317
|
end
|
|
262
318
|
|
|
263
319
|
def restricted?
|
|
@@ -273,7 +329,7 @@ class Document < Kithe::Work
|
|
|
273
329
|
end
|
|
274
330
|
|
|
275
331
|
def direct_download
|
|
276
|
-
|
|
332
|
+
distributions.download.to_hash if distributions.download.present?
|
|
277
333
|
end
|
|
278
334
|
|
|
279
335
|
def display_note
|
|
@@ -281,11 +337,11 @@ class Document < Kithe::Work
|
|
|
281
337
|
end
|
|
282
338
|
|
|
283
339
|
def hgl_download
|
|
284
|
-
|
|
340
|
+
distributions.hgl.to_hash if distributions.hgl.present?
|
|
285
341
|
end
|
|
286
342
|
|
|
287
343
|
def oembed
|
|
288
|
-
|
|
344
|
+
distributions.oembed.endpoint if distributions.oembed.present?
|
|
289
345
|
end
|
|
290
346
|
|
|
291
347
|
def same_institution?
|
|
@@ -294,15 +350,15 @@ class Document < Kithe::Work
|
|
|
294
350
|
end
|
|
295
351
|
|
|
296
352
|
def iiif_download
|
|
297
|
-
|
|
353
|
+
distributions.iiif.to_hash if distributions.iiif.present?
|
|
298
354
|
end
|
|
299
355
|
|
|
300
356
|
def data_dictionary_download
|
|
301
|
-
|
|
357
|
+
distributions.data_dictionary.to_hash if distributions.data_dictionary.present?
|
|
302
358
|
end
|
|
303
359
|
|
|
304
360
|
def external_url
|
|
305
|
-
|
|
361
|
+
distributions.url&.endpoint
|
|
306
362
|
end
|
|
307
363
|
|
|
308
364
|
def itemtype
|
|
@@ -332,7 +388,7 @@ class Document < Kithe::Work
|
|
|
332
388
|
# :type => a string which if its a Geoblacklight::Constants::URI key
|
|
333
389
|
# will return a coresponding Geoblacklight::Reference
|
|
334
390
|
def checked_endpoint(type)
|
|
335
|
-
type =
|
|
391
|
+
type = distributions.send(type)
|
|
336
392
|
type.endpoint if type.present?
|
|
337
393
|
end
|
|
338
394
|
|
|
@@ -397,6 +453,7 @@ class Document < Kithe::Work
|
|
|
397
453
|
elsif value[:destination] == "b1g_publication_state_s"
|
|
398
454
|
send(:current_state)
|
|
399
455
|
else
|
|
456
|
+
next if send(value[:destination]).blank?
|
|
400
457
|
send(value[:destination])
|
|
401
458
|
end
|
|
402
459
|
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
|
|
5
|
+
# DocumentDistribution
|
|
6
|
+
#
|
|
7
|
+
# This class represents a distribution of a document, which includes a URL and a distribution type.
|
|
8
|
+
# It belongs to a document and a reference type, and it supports CSV import and export.
|
|
9
|
+
#
|
|
10
|
+
# Associations:
|
|
11
|
+
# - belongs_to :document
|
|
12
|
+
# - belongs_to :reference_type
|
|
13
|
+
#
|
|
14
|
+
# Callbacks:
|
|
15
|
+
# - after_save :reindex_document
|
|
16
|
+
#
|
|
17
|
+
# Validations:
|
|
18
|
+
# - Validates presence of :friendlier_id, :reference_type_id, :url
|
|
19
|
+
# - Validates uniqueness of :url scoped to :friendlier_id and :reference_type_id
|
|
20
|
+
#
|
|
21
|
+
# Scopes:
|
|
22
|
+
# - to_aardvark_distributions: Converts distributions to aardvark format
|
|
23
|
+
# - to_csv: Converts distributions to CSV format
|
|
24
|
+
class DocumentDistribution < ApplicationRecord
|
|
25
|
+
belongs_to :document, foreign_key: :friendlier_id, primary_key: :friendlier_id
|
|
26
|
+
belongs_to :reference_type
|
|
27
|
+
after_save :reindex_document
|
|
28
|
+
|
|
29
|
+
# Validations
|
|
30
|
+
validates :friendlier_id, :reference_type_id, :url, presence: true
|
|
31
|
+
validates :url, uniqueness: {scope: [:friendlier_id, :reference_type_id]}
|
|
32
|
+
|
|
33
|
+
# Scopes
|
|
34
|
+
scope :to_aardvark_distributions, -> {
|
|
35
|
+
distributions = where(friendlier_id: pluck(:friendlier_id)).map(&:to_aardvark_distribution)
|
|
36
|
+
merged = {}
|
|
37
|
+
distributions.each do |dist|
|
|
38
|
+
if dist.keys.first == "http://schema.org/downloadUrl"
|
|
39
|
+
merged["http://schema.org/downloadUrl"] ||= []
|
|
40
|
+
merged["http://schema.org/downloadUrl"] << {
|
|
41
|
+
"url" => dist.values.first,
|
|
42
|
+
"label" => dist[:label]
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
merged[dist.keys.first] = dist.values.first
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
merged
|
|
49
|
+
}
|
|
50
|
+
scope :to_csv, -> { where(friendlier_id: pluck(:friendlier_id)).map(&:to_csv) }
|
|
51
|
+
|
|
52
|
+
# CSV Column Names
|
|
53
|
+
#
|
|
54
|
+
# Returns an array of column names for CSV export.
|
|
55
|
+
#
|
|
56
|
+
# @return [Array<String>] the CSV column names
|
|
57
|
+
def self.csv_column_names
|
|
58
|
+
["friendlier_id", "reference_type", "distribution_url", "label"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Import
|
|
62
|
+
#
|
|
63
|
+
# Imports document distributions from a CSV file.
|
|
64
|
+
#
|
|
65
|
+
# @param file [File] the CSV file to import
|
|
66
|
+
# @return [Boolean] true if import is successful
|
|
67
|
+
def self.import(file)
|
|
68
|
+
logger.debug("CSV Import")
|
|
69
|
+
::CSV.foreach(file.path, headers: true) do |row|
|
|
70
|
+
logger.debug("CSV Row: #{row.to_hash}")
|
|
71
|
+
document_distribution = DocumentDistribution.find_or_initialize_by(
|
|
72
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
73
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
74
|
+
url: row.to_hash["distribution_url"],
|
|
75
|
+
label: row.to_hash["label"]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
logger.debug("Document Distribution: #{document_distribution.inspect}")
|
|
79
|
+
|
|
80
|
+
document_distribution.update!(
|
|
81
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
82
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
83
|
+
url: row.to_hash["distribution_url"],
|
|
84
|
+
label: row.to_hash["label"]
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Destroy All
|
|
91
|
+
#
|
|
92
|
+
# Destroys document distributions based on a CSV file.
|
|
93
|
+
#
|
|
94
|
+
# @param file [File] the CSV file to process
|
|
95
|
+
# @return [Boolean] true if destroy is successful
|
|
96
|
+
def self.destroy_all(file)
|
|
97
|
+
logger.debug("CSV Destroy")
|
|
98
|
+
::CSV.foreach(file.path, headers: true) do |row|
|
|
99
|
+
logger.debug("CSV Row: #{row.to_hash}")
|
|
100
|
+
if DocumentDistribution.destroy_by(
|
|
101
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
102
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
103
|
+
url: row.to_hash["distribution_url"]
|
|
104
|
+
)
|
|
105
|
+
logger.debug("Destroyed: #{row.to_hash}")
|
|
106
|
+
else
|
|
107
|
+
logger.debug("Not Destroyed: #{row.to_hash}")
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# To CSV
|
|
114
|
+
#
|
|
115
|
+
# Converts the document distribution to an array suitable for CSV export.
|
|
116
|
+
#
|
|
117
|
+
# @return [Array<String>] the CSV row data
|
|
118
|
+
def to_csv
|
|
119
|
+
[
|
|
120
|
+
friendlier_id,
|
|
121
|
+
reference_type.name,
|
|
122
|
+
url,
|
|
123
|
+
label
|
|
124
|
+
]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# To Aardvark Reference
|
|
128
|
+
#
|
|
129
|
+
# Converts the document distribution to an aardvark distribution format.
|
|
130
|
+
#
|
|
131
|
+
# @return [Hash] the aardvark reference
|
|
132
|
+
def to_aardvark_distribution
|
|
133
|
+
hash = {}
|
|
134
|
+
hash[reference_type.reference_uri.to_s] = url
|
|
135
|
+
hash[:label] = label if reference_type.reference_uri.to_s == "http://schema.org/downloadUrl"
|
|
136
|
+
hash
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Reindex Document
|
|
140
|
+
#
|
|
141
|
+
# Reindexes the associated document.
|
|
142
|
+
def reindex_document
|
|
143
|
+
document.save
|
|
144
|
+
end
|
|
145
|
+
end
|
data/app/models/element.rb
CHANGED
|
@@ -31,7 +31,11 @@ module GeoblacklightAdmin
|
|
|
31
31
|
}
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
unless ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
35
|
+
Rails.logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
|
|
36
|
+
@fields = @fields.merge(dct_references_import_mappings)
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
@fields
|
|
36
40
|
end
|
|
37
41
|
|
|
@@ -63,7 +67,11 @@ module GeoblacklightAdmin
|
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
unless ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
71
|
+
Rails.logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
|
|
72
|
+
@fields = @fields.merge(dct_references_import_mappings)
|
|
73
|
+
end
|
|
74
|
+
|
|
67
75
|
@fields = @fields.merge(object_metadata)
|
|
68
76
|
@fields
|
|
69
77
|
end
|
|
@@ -8,7 +8,7 @@ class Import
|
|
|
8
8
|
class CsvHeaderValidator < ActiveModel::Validator
|
|
9
9
|
def validate(record)
|
|
10
10
|
valid_csv_header = true
|
|
11
|
-
unless valid_csv_headers?(record
|
|
11
|
+
unless valid_csv_headers?(record&.csv_file)
|
|
12
12
|
valid_csv_header = false
|
|
13
13
|
record.errors.add(:csv_file,
|
|
14
14
|
"Missing a required CSV header. Title, Resource Class, Access Rights, and ID are required.")
|
|
@@ -20,6 +20,8 @@ class Import
|
|
|
20
20
|
def valid_csv_headers?(csv_file)
|
|
21
21
|
headers = CSV.parse(csv_file.download)[0]
|
|
22
22
|
(["Title", "Resource Class", "Access Rights", "ID"] - headers).empty?
|
|
23
|
+
rescue ArgumentError, ActiveStorage::FileNotFoundError
|
|
24
|
+
false
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -5,7 +5,7 @@ class ImportBtaaAardvark < Import
|
|
|
5
5
|
# validations, constants and methods
|
|
6
6
|
|
|
7
7
|
def mapping_configuration
|
|
8
|
-
|
|
8
|
+
GeoblacklightAdmin::Schema.instance.importable_fields
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def klass_delimiter
|
|
@@ -98,7 +98,7 @@ class ImportBtaaAardvark < Import
|
|
|
98
98
|
json_data.each do |key, value|
|
|
99
99
|
reference = {
|
|
100
100
|
value: value,
|
|
101
|
-
category:
|
|
101
|
+
category: GeoblacklightAdmin::FieldMappingsBtaaAardvark.uri_2_category_references_mappings[key]
|
|
102
102
|
}
|
|
103
103
|
references << reference
|
|
104
104
|
end
|
data/app/models/import_gblv1.rb
CHANGED
|
@@ -5,7 +5,7 @@ class ImportGblv1 < Import
|
|
|
5
5
|
# validations, constants and methods
|
|
6
6
|
|
|
7
7
|
def mapping_configuration
|
|
8
|
-
|
|
8
|
+
GeoblacklightAdmin::Schema.instance.importable_fields
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def klass_delimiter
|
|
@@ -81,7 +81,7 @@ class ImportGblv1 < Import
|
|
|
81
81
|
json_data.each do |key, value|
|
|
82
82
|
reference = {
|
|
83
83
|
value: value,
|
|
84
|
-
category:
|
|
84
|
+
category: GeoblacklightAdmin::FieldMappingsGblv1.uri_2_category_references_mappings[key]
|
|
85
85
|
}
|
|
86
86
|
references << reference
|
|
87
87
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The ReferenceType class represents a reference entity in the application.
|
|
4
|
+
# It includes validations for presence and uniqueness of reference attributes,
|
|
5
|
+
# and manages the position of references within the system.
|
|
6
|
+
class ReferenceType < ApplicationRecord
|
|
7
|
+
has_many :document_distributions, dependent: :destroy
|
|
8
|
+
|
|
9
|
+
# Validations
|
|
10
|
+
# Ensures that both reference_type and reference_uri are present and unique.
|
|
11
|
+
validates :name, :reference_type, :reference_uri, presence: true
|
|
12
|
+
validates :name, :reference_type, uniqueness: true
|
|
13
|
+
|
|
14
|
+
# Callbacks
|
|
15
|
+
# Sets the position of the reference before it is created.
|
|
16
|
+
before_create :set_last_position
|
|
17
|
+
|
|
18
|
+
# Sets the position of the reference to the next available position.
|
|
19
|
+
# If no references exist, it sets the position to 1.
|
|
20
|
+
#
|
|
21
|
+
# @return [void]
|
|
22
|
+
def set_last_position
|
|
23
|
+
position = ReferenceType.all.order(position: :desc)&.first&.position
|
|
24
|
+
self.position = position.blank? ? 1 : position + 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Class method to sort elements based on an array of IDs.
|
|
28
|
+
# Updates the position of each ReferenceType according to the order in the array.
|
|
29
|
+
#
|
|
30
|
+
# @param id_array [Array<Integer>] An array of element IDs to be sorted.
|
|
31
|
+
# @return [void]
|
|
32
|
+
def self.sort_elements(id_array)
|
|
33
|
+
transaction do
|
|
34
|
+
logger.debug { id_array.inspect }
|
|
35
|
+
id_array.each_with_index do |elm_id, i|
|
|
36
|
+
ReferenceType.update(elm_id, position: i)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/app/models/user.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "devise"
|
|
4
|
+
|
|
3
5
|
# User
|
|
4
6
|
class User < ApplicationRecord
|
|
7
|
+
extend Devise::Models
|
|
5
8
|
include Blacklight::User
|
|
6
9
|
|
|
7
10
|
# Include default devise modules. Others available are:
|
|
8
11
|
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
9
|
-
devise :
|
|
10
|
-
:recoverable, :rememberable, :validatable
|
|
12
|
+
devise :database_authenticatable, :recoverable, :rememberable, :validatable
|
|
11
13
|
|
|
12
14
|
has_many :bookmarks, dependent: :destroy, as: :user
|
|
13
15
|
has_many :notifications, dependent: :destroy, as: :recipient
|