geoblacklight_admin 0.4.1 → 0.5.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 +10 -55
- data/Rakefile +3 -0
- data/app/assets/javascripts/geoblacklight_admin/chosen.js +7 -3
- data/app/assets/javascripts/geoblacklight_admin/datepicker.js +2 -2
- data/app/assets/javascripts/geoblacklight_admin/inputmask.js +2 -2
- data/app/assets/javascripts/geoblacklight_admin/truncate.js +2 -2
- data/app/assets/javascripts/geoblacklight_admin.js +1 -4
- data/app/assets/stylesheets/geoblacklight_admin/_core.scss +3 -1
- data/app/assets/stylesheets/geoblacklight_admin/modules/_images.scss +4 -0
- data/app/assets/stylesheets/geoblacklight_admin/modules/_nav.scss +4 -0
- data/app/assets/stylesheets/geoblacklight_admin/modules/_results.scss +5 -0
- data/app/controllers/admin/admin_controller.rb +1 -1
- data/app/controllers/admin/advanced_search_controller.rb +0 -1
- data/app/controllers/admin/assets_controller.rb +142 -0
- data/app/controllers/admin/bulk_actions_controller.rb +1 -1
- data/app/controllers/admin/document_accesses_controller.rb +3 -3
- data/app/controllers/admin/document_assets_controller.rb +33 -23
- data/app/controllers/admin/documents_controller.rb +6 -2
- data/app/controllers/admin/ids_controller.rb +0 -1
- data/app/controllers/admin/imports_controller.rb +2 -2
- data/app/helpers/asset_helper.rb +8 -0
- data/app/helpers/document_helper.rb +4 -0
- data/app/helpers/geoblacklight_admin_helper.rb +11 -1
- data/{lib/generators/geoblacklight_admin/templates → app}/javascript/controllers/results_controller.js +38 -0
- data/app/javascript/entrypoints/engine.js +8 -0
- data/app/javascript/index.js +8 -0
- data/app/jobs/bulk_action_revert_document_job.rb +2 -2
- data/app/jobs/bulk_action_run_document_job.rb +5 -1
- data/app/jobs/bulk_action_run_job.rb +11 -1
- data/app/jobs/geoblacklight_admin/delete_thumbnail_job.rb +17 -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 +19 -0
- data/app/jobs/geoblacklight_admin/store_image_job.rb +21 -2
- data/app/models/asset.rb +38 -0
- data/app/models/blacklight_api.rb +2 -2
- data/app/models/blacklight_api_facets.rb +1 -1
- data/app/models/blacklight_api_ids.rb +2 -2
- data/app/models/bulk_action_document_state_machine.rb +2 -4
- data/app/models/bulk_action_state_machine.rb +3 -3
- data/app/models/bulk_actions/change_publication_state.rb +10 -0
- data/app/models/document/reference.rb +24 -0
- data/app/models/document.rb +122 -11
- data/app/models/document_thumbnail_state_machine.rb +22 -0
- data/app/models/document_thumbnail_transition.rb +26 -0
- data/app/models/element.rb +1 -1
- data/app/models/geoblacklight_admin/field_mappings_btaa_aardvark.rb +7 -1
- data/app/models/geoblacklight_admin/schema.rb +37 -1
- data/app/models/geoblacklight_admin/solr_utils.rb +87 -0
- data/app/models/kithe/vips_cli_image_to_png.rb +114 -0
- data/app/services/geoblacklight_admin/image_service/iiif.rb +2 -2
- data/app/services/geoblacklight_admin/image_service/iiif_manifest.rb +111 -0
- data/app/services/geoblacklight_admin/image_service/tms.rb +50 -0
- data/app/services/geoblacklight_admin/image_service/wms.rb +1 -4
- data/app/services/geoblacklight_admin/image_service.rb +16 -40
- data/app/services/geoblacklight_admin/item_viewer.rb +1 -1
- data/app/uploaders/asset_uploader.rb +6 -11
- data/app/views/admin/assets/_form.html.erb +19 -0
- data/app/views/admin/assets/display_attach_form.html.erb +39 -0
- data/app/views/admin/assets/edit.html.erb +9 -0
- data/app/views/admin/assets/index.html.erb +75 -0
- data/app/views/admin/assets/show.html.erb +100 -0
- data/app/views/admin/bulk_actions/index.html.erb +50 -48
- data/app/views/admin/bulk_actions/show.html.erb +3 -2
- data/app/views/admin/document_accesses/index.html.erb +68 -64
- data/app/views/admin/document_assets/_form.html.erb +17 -0
- data/app/views/admin/document_assets/display_attach_form.html.erb +4 -9
- data/app/views/admin/document_assets/edit.html.erb +5 -0
- data/app/views/admin/document_assets/index.html.erb +88 -72
- data/app/views/admin/document_downloads/index.html.erb +64 -62
- data/app/views/admin/documents/_document.html.erb +37 -16
- data/app/views/admin/documents/_form.html.erb +21 -6
- data/app/views/admin/documents/_form_nav.html.erb +12 -3
- data/app/views/admin/documents/_result_selected_options.html.erb +6 -1
- data/app/views/admin/documents/admin.html.erb +210 -0
- data/app/views/admin/documents/index.html.erb +10 -1
- data/app/views/admin/documents/versions.html.erb +3 -3
- data/app/views/admin/elements/index.html.erb +55 -54
- data/app/views/admin/form_elements/index.html.erb +38 -35
- data/app/views/admin/imports/index.html.erb +52 -50
- data/app/views/admin/layouts/application.html.erb +7 -4
- data/app/views/admin/shared/_js_behaviors.html.erb +6 -3
- data/app/views/admin/shared/_navbar.html.erb +11 -8
- data/config/locales/documents.en.yml +6 -0
- data/config/routes.rb +1 -0
- data/config/vite.json +14 -0
- data/db/migrate/20240619171628_create_document_thumbnail_statesman.rb +18 -0
- data/lib/generators/geoblacklight_admin/config_generator.rb +63 -15
- data/lib/generators/geoblacklight_admin/install_generator.rb +1 -0
- data/lib/generators/geoblacklight_admin/templates/api_controller.rb +0 -2
- data/lib/generators/geoblacklight_admin/templates/base.html.erb +53 -0
- data/lib/generators/geoblacklight_admin/templates/config/initializers/kithe.rb +1 -0
- data/lib/generators/geoblacklight_admin/templates/config/settings.yml +15 -1
- data/lib/generators/geoblacklight_admin/templates/config/vite.json +16 -0
- data/lib/generators/geoblacklight_admin/templates/frontend/entrypoints/application.js +30 -0
- data/lib/generators/geoblacklight_admin/templates/package-test.json +10 -0
- data/lib/generators/geoblacklight_admin/templates/package.json +5 -29
- data/lib/generators/geoblacklight_admin/templates/vite.config.ts +8 -0
- data/lib/geoblacklight_admin/engine.rb +1 -0
- data/lib/geoblacklight_admin/rake_task.rb +5 -0
- data/lib/geoblacklight_admin/tasks/images.rake +33 -0
- data/lib/geoblacklight_admin/tasks/solr.rake +11 -0
- data/lib/geoblacklight_admin/version.rb +1 -1
- metadata +75 -19
- data/lib/generators/geoblacklight_admin/templates/javascript/controllers/application_controller.js +0 -17
- data/lib/generators/geoblacklight_admin/templates/javascript/controllers/document_controller.js +0 -26
- data/lib/generators/geoblacklight_admin/templates/javascript/controllers/index.js +0 -10
- data/lib/tasks/geoblacklight_admin/images.rake +0 -30
- data/lib/tasks/geoblacklight_admin.rake +0 -213
|
@@ -293,6 +293,44 @@ export default class extends Controller {
|
|
|
293
293
|
form.submit();
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
harvestThumbnails(event) {
|
|
297
|
+
var el = document.querySelector('#bulk_action_field_name');
|
|
298
|
+
el.setAttribute('value', "Harvest Thumbnails");
|
|
299
|
+
|
|
300
|
+
// Set field value
|
|
301
|
+
var el = document.querySelector('#bulk_action_field_value');
|
|
302
|
+
el.setAttribute(
|
|
303
|
+
'value',
|
|
304
|
+
event.currentTarget.innerHTML.toLowerCase().trim()
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
// Set scope value
|
|
308
|
+
this.setPubState(event);
|
|
309
|
+
|
|
310
|
+
// Submit form
|
|
311
|
+
var form = document.querySelector('#result-action-form');
|
|
312
|
+
form.submit();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
deleteThumbnails(event) {
|
|
316
|
+
var el = document.querySelector('#bulk_action_field_name');
|
|
317
|
+
el.setAttribute('value', "Delete Thumbnails");
|
|
318
|
+
|
|
319
|
+
// Set field value
|
|
320
|
+
var el = document.querySelector('#bulk_action_field_value');
|
|
321
|
+
el.setAttribute(
|
|
322
|
+
'value',
|
|
323
|
+
event.currentTarget.innerHTML.toLowerCase().trim()
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
// Set scope value
|
|
327
|
+
this.setPubState(event);
|
|
328
|
+
|
|
329
|
+
// Submit form
|
|
330
|
+
var form = document.querySelector('#result-action-form');
|
|
331
|
+
form.submit();
|
|
332
|
+
}
|
|
333
|
+
|
|
296
334
|
bulkActionDelete(event) {
|
|
297
335
|
event.preventDefault();
|
|
298
336
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
console.log('Vite ⚡️ Rails - GBL Admin')
|
|
2
|
+
|
|
3
|
+
// Stimulus
|
|
4
|
+
import { Application } from '@hotwired/stimulus'
|
|
5
|
+
import ResultsController from "../controllers/results_controller"
|
|
6
|
+
|
|
7
|
+
window.Stimulus = Application.start()
|
|
8
|
+
Stimulus.register("results", ResultsController)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
console.log('Vite ⚡️ Rails - GBL Admin')
|
|
2
|
+
|
|
3
|
+
// Stimulus
|
|
4
|
+
import { Application } from '@hotwired/stimulus'
|
|
5
|
+
import ResultsController from "./controllers/results_controller"
|
|
6
|
+
|
|
7
|
+
window.Stimulus = Application.start()
|
|
8
|
+
Stimulus.register("results", ResultsController)
|
|
@@ -22,9 +22,9 @@ class BulkActionRevertDocumentJob < ApplicationJob
|
|
|
22
22
|
|
|
23
23
|
versions = document.versions
|
|
24
24
|
document = versions[doc.version].reify
|
|
25
|
-
document
|
|
25
|
+
document&.skip_callbacks = true
|
|
26
26
|
|
|
27
|
-
if document
|
|
27
|
+
if document&.save
|
|
28
28
|
doc.state_machine.transition_to!(:success)
|
|
29
29
|
else
|
|
30
30
|
doc.state_machine.transition_to!(:failed)
|
|
@@ -10,8 +10,12 @@ class BulkActionRunDocumentJob < ApplicationJob
|
|
|
10
10
|
update_publication_status(doc, field_value)
|
|
11
11
|
when :update_delete
|
|
12
12
|
update_delete(doc, field_value)
|
|
13
|
-
|
|
13
|
+
when :harvest_thumbnails
|
|
14
|
+
GeoblacklightAdmin::StoreImageJob.perform_later(doc.friendlier_id, doc.id, :priority)
|
|
15
|
+
when :delete_thumbnails
|
|
16
|
+
GeoblacklightAdmin::DeleteThumbnailJob.perform_later(doc.friendlier_id, doc.id, :priority)
|
|
14
17
|
else
|
|
18
|
+
# @TODO: Field Level changes
|
|
15
19
|
logger.debug("@TODO - #{field_name} => #{field_value}")
|
|
16
20
|
end
|
|
17
21
|
end
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
class BulkActionRunJob < ApplicationJob
|
|
5
5
|
queue_as :priority
|
|
6
6
|
|
|
7
|
+
after_perform do |job|
|
|
8
|
+
logger.debug("BulkActionRunJob - After Perform - #{job.arguments.first.id}")
|
|
9
|
+
job.arguments.first.state_machine.transition_to!(:complete)
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
def perform(bulk_action)
|
|
8
13
|
action = case bulk_action.field_name
|
|
9
14
|
when "Publication State"
|
|
@@ -12,13 +17,18 @@ class BulkActionRunJob < ApplicationJob
|
|
|
12
17
|
when "Delete"
|
|
13
18
|
logger.debug("BulkAction: Delete")
|
|
14
19
|
:update_delete
|
|
20
|
+
when "Harvest Thumbnails"
|
|
21
|
+
logger.debug("BulkAction: Harvest Thumbnails")
|
|
22
|
+
:harvest_thumbnails
|
|
23
|
+
when "Delete Thumbnails"
|
|
24
|
+
logger.debug("BulkAction: Delete Thumbnails")
|
|
25
|
+
:delete_thumbnails
|
|
15
26
|
else
|
|
16
27
|
:update_field_value
|
|
17
28
|
end
|
|
18
29
|
|
|
19
30
|
bulk_action.documents.each do |doc|
|
|
20
31
|
BulkActionRunDocumentJob.perform_later(action, doc, bulk_action.field_name, bulk_action.field_value)
|
|
21
|
-
doc.state_machine.transition_to!(:queued)
|
|
22
32
|
end
|
|
23
33
|
|
|
24
34
|
# Capture State
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GeoblacklightAdmin
|
|
4
|
+
class DeleteThumbnailJob < ApplicationJob
|
|
5
|
+
queue_as do
|
|
6
|
+
arguments.last
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def perform(solr_document_id, bad_id = nil, queue = :priority)
|
|
10
|
+
document = Document.find_by_friendlier_id(solr_document_id)
|
|
11
|
+
if document.thumbnail.present?
|
|
12
|
+
document.thumbnail.destroy!
|
|
13
|
+
end
|
|
14
|
+
BulkActionDocument.find(bad_id).state_machine.transition_to!(:success) if bad_id.present?
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GeoblacklightAdmin
|
|
4
|
+
class RemoveParentDctReferencesUriJob < ApplicationJob
|
|
5
|
+
queue_as :priority
|
|
6
|
+
|
|
7
|
+
def perform(asset)
|
|
8
|
+
if asset.dct_references_uri_key.present?
|
|
9
|
+
asset.parent.dct_references_s.delete_if { |i| i.value == asset.full_file_url }
|
|
10
|
+
asset.parent.save!
|
|
11
|
+
end
|
|
12
|
+
rescue => e
|
|
13
|
+
Rails.logger.error "\nError - Removing parent dct_references URI: #{e.message} \n"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GeoblacklightAdmin
|
|
4
|
+
class SetParentDctReferencesUriJob < ApplicationJob
|
|
5
|
+
queue_as :priority
|
|
6
|
+
|
|
7
|
+
def perform(asset)
|
|
8
|
+
if asset.dct_references_uri_key.present?
|
|
9
|
+
reference = Document::Reference.new
|
|
10
|
+
reference.category = asset.dct_references_uri_key
|
|
11
|
+
reference.value = asset.full_file_url
|
|
12
|
+
asset.parent.dct_references_s << reference
|
|
13
|
+
asset.parent.save!
|
|
14
|
+
end
|
|
15
|
+
rescue => e
|
|
16
|
+
Rails.logger.error "\nError - Setting parent DCT references URI: #{e.message}\n"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -2,11 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
module GeoblacklightAdmin
|
|
4
4
|
class StoreImageJob < ApplicationJob
|
|
5
|
-
queue_as
|
|
5
|
+
queue_as do
|
|
6
|
+
arguments.last
|
|
7
|
+
end
|
|
6
8
|
|
|
7
|
-
def perform(solr_document_id)
|
|
9
|
+
def perform(solr_document_id, bad_id = nil, queue = :default)
|
|
10
|
+
# Find the document
|
|
8
11
|
document = Document.find_by_friendlier_id(solr_document_id)
|
|
12
|
+
|
|
13
|
+
# Delete thumbnail if already present
|
|
14
|
+
if document&.thumbnail&.present?
|
|
15
|
+
document.thumbnail.destroy!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Statesman
|
|
19
|
+
metadata = {}
|
|
20
|
+
metadata["solr_doc_id"] = solr_document_id
|
|
21
|
+
document.thumbnail_state_machine.transition_to!(:queued, metadata)
|
|
22
|
+
|
|
23
|
+
# Crawl politely
|
|
24
|
+
sleep(rand(1..5))
|
|
25
|
+
|
|
26
|
+
# Store the image
|
|
9
27
|
GeoblacklightAdmin::ImageService.new(document).store
|
|
28
|
+
BulkActionDocument.find(bad_id).state_machine.transition_to!(:success) if bad_id.present?
|
|
10
29
|
end
|
|
11
30
|
end
|
|
12
31
|
end
|
data/app/models/asset.rb
CHANGED
|
@@ -1,13 +1,51 @@
|
|
|
1
1
|
class Asset < Kithe::Asset
|
|
2
2
|
include AttrJson::Record::QueryScopes
|
|
3
|
+
include Rails.application.routes.url_helpers
|
|
4
|
+
|
|
5
|
+
# Default Sort Order
|
|
6
|
+
default_scope { order(parent_id: :desc, created_at: :asc) }
|
|
3
7
|
|
|
4
8
|
set_shrine_uploader(AssetUploader)
|
|
5
9
|
|
|
6
10
|
# AttrJSON
|
|
7
11
|
attr_json :thumbnail, :boolean, default: "false"
|
|
8
12
|
attr_json :derivative_storage_type, :string, default: "public"
|
|
13
|
+
attr_json :dct_references_uri_key, :string
|
|
14
|
+
attr_json :label, :string
|
|
9
15
|
|
|
10
16
|
DERIVATIVE_STORAGE_TYPE_LOCATIONS = {
|
|
11
17
|
"public" => :kithe_derivatives
|
|
12
18
|
}.freeze
|
|
19
|
+
|
|
20
|
+
def full_file_url
|
|
21
|
+
if Rails.env.development?
|
|
22
|
+
"http://localhost:3000" + file.url
|
|
23
|
+
else
|
|
24
|
+
file.url
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# After Promotion Callbacks
|
|
29
|
+
after_promotion :set_parent_dct_references_uri
|
|
30
|
+
|
|
31
|
+
def set_parent_dct_references_uri
|
|
32
|
+
GeoblacklightAdmin::SetParentDctReferencesUriJob.perform_later(self) if parent_id.present?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Before Destroy Callbacks
|
|
36
|
+
before_destroy :remove_parent_dct_references_uri
|
|
37
|
+
|
|
38
|
+
def remove_parent_dct_references_uri
|
|
39
|
+
GeoblacklightAdmin::RemoveParentDctReferencesUriJob.perform_later(self) if parent_id.present?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# After Save Callbacks
|
|
43
|
+
after_save :reindex_parent
|
|
44
|
+
|
|
45
|
+
def reindex_parent
|
|
46
|
+
parent.save if parent.present?
|
|
47
|
+
end
|
|
13
48
|
end
|
|
49
|
+
|
|
50
|
+
# Allow DocumentAsset to be used as a synonym for Asset
|
|
51
|
+
DocumentAsset = Asset
|
|
@@ -30,11 +30,11 @@ class BlacklightApi
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def facets
|
|
33
|
-
fetch["included"]&.
|
|
33
|
+
fetch["included"]&.select { |s| s["type"] == "facet" }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def sorts
|
|
37
|
-
fetch["included"].
|
|
37
|
+
fetch["included"].select { |s| s["type"] == "sort" }
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def meta
|
|
@@ -33,11 +33,11 @@ class BlacklightApiIds
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def facets
|
|
36
|
-
fetch["included"]&.
|
|
36
|
+
fetch["included"]&.select { |s| s["type"] == "facet" }
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def sorts
|
|
40
|
-
fetch["included"].
|
|
40
|
+
fetch["included"].select { |s| s["type"] == "sort" }
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def meta
|
|
@@ -9,8 +9,6 @@ class BulkActionDocumentStateMachine
|
|
|
9
9
|
state :success
|
|
10
10
|
state :failed
|
|
11
11
|
|
|
12
|
-
transition from: :created, to: %i[queued success]
|
|
13
|
-
transition from: :queued, to: %i[
|
|
14
|
-
transition from: :success, to: %i[queued success failed]
|
|
15
|
-
transition from: :failed, to: %i[queued success failed]
|
|
12
|
+
transition from: :created, to: %i[queued success failed]
|
|
13
|
+
transition from: :queued, to: %i[success failed]
|
|
16
14
|
end
|
|
@@ -10,7 +10,7 @@ class BulkActionStateMachine
|
|
|
10
10
|
state :failed
|
|
11
11
|
state :reverted
|
|
12
12
|
|
|
13
|
-
transition from: :created, to: %i[queued
|
|
14
|
-
transition from: :queued, to: %i[created
|
|
15
|
-
transition from: :complete, to: %i[
|
|
13
|
+
transition from: :created, to: %i[queued]
|
|
14
|
+
transition from: :queued, to: %i[created complete failed]
|
|
15
|
+
transition from: :complete, to: %i[reverted]
|
|
16
16
|
end
|
|
@@ -18,4 +18,14 @@ module BulkActions
|
|
|
18
18
|
class DraftDocument < BulkAction
|
|
19
19
|
# Add specific methods and validations for DraftDocument here
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
# Subclass for HarvestThumbnails
|
|
23
|
+
class HarvestThumbnails < BulkAction
|
|
24
|
+
# Add specific methods and validations for HarvestThumbnails here
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Subclass for DeleteThumbnails
|
|
28
|
+
class DeleteThumbnails < BulkAction
|
|
29
|
+
# Add specific methods and validations for DeleteThumbnails here
|
|
30
|
+
end
|
|
21
31
|
end
|
|
@@ -90,6 +90,30 @@ class Document
|
|
|
90
90
|
oembed: {
|
|
91
91
|
label: "oEmbed",
|
|
92
92
|
uri: "https://oembed.com"
|
|
93
|
+
},
|
|
94
|
+
cog: {
|
|
95
|
+
label: "COG",
|
|
96
|
+
uri: "https://github.com/cogeotiff/cog-spec"
|
|
97
|
+
},
|
|
98
|
+
pmtiles: {
|
|
99
|
+
label: "PMTiles",
|
|
100
|
+
uri: "https://github.com/protomaps/PMTiles"
|
|
101
|
+
},
|
|
102
|
+
xyz_tiles: {
|
|
103
|
+
label: "XYZ Tiles",
|
|
104
|
+
uri: "https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames"
|
|
105
|
+
},
|
|
106
|
+
wmts: {
|
|
107
|
+
label: "WMTS",
|
|
108
|
+
uri: "http://www.opengis.net/def/serviceType/ogc/wmts"
|
|
109
|
+
},
|
|
110
|
+
tile_json: {
|
|
111
|
+
label: "TileJSON",
|
|
112
|
+
uri: "https://github.com/mapbox/tilejson-spec"
|
|
113
|
+
},
|
|
114
|
+
tile_map_service: {
|
|
115
|
+
label: "Tile Map Service",
|
|
116
|
+
uri: "https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification"
|
|
93
117
|
}
|
|
94
118
|
}.freeze
|
|
95
119
|
|
data/app/models/document.rb
CHANGED
|
@@ -18,26 +18,59 @@ class Document < Kithe::Work
|
|
|
18
18
|
belongs_to :import, optional: true
|
|
19
19
|
|
|
20
20
|
# Statesman
|
|
21
|
+
# - Publication State
|
|
21
22
|
has_many :document_transitions, foreign_key: "kithe_model_id", autosave: false, dependent: :destroy,
|
|
22
23
|
inverse_of: :document
|
|
24
|
+
# - Thumbnail State
|
|
25
|
+
has_many :document_thumbnail_transitions, foreign_key: "kithe_model_id", autosave: false, dependent: :destroy,
|
|
26
|
+
inverse_of: :document
|
|
23
27
|
|
|
24
|
-
#
|
|
28
|
+
# Document Collections
|
|
29
|
+
# - DocumentAccesses
|
|
25
30
|
has_many :document_accesses, primary_key: "friendlier_id", foreign_key: "friendlier_id", autosave: false, dependent: :destroy,
|
|
26
31
|
inverse_of: :document
|
|
27
32
|
|
|
28
|
-
# DocumentDownloads
|
|
33
|
+
# - DocumentDownloads
|
|
29
34
|
has_many :document_downloads, primary_key: "friendlier_id", foreign_key: "friendlier_id", autosave: false, dependent: :destroy,
|
|
30
35
|
inverse_of: :document
|
|
31
36
|
|
|
37
|
+
# DocumentAssets - Thumbnails, Attachments, etc
|
|
38
|
+
# @TODO: Redundant? Kithe also includes a members association
|
|
39
|
+
def document_assets
|
|
40
|
+
scope = Kithe::Asset
|
|
41
|
+
scope = scope.where(parent_id: id)
|
|
42
|
+
|
|
43
|
+
# scope = scope.page(params[:page]).per(20).order(created_at: :desc)
|
|
44
|
+
scope.includes(:parent)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def downloadable_assets
|
|
48
|
+
document_assets.select { |a| a.dct_references_uri_key == "download" }
|
|
49
|
+
end
|
|
50
|
+
|
|
32
51
|
include Statesman::Adapters::ActiveRecordQueries[
|
|
33
52
|
transition_class: DocumentTransition,
|
|
34
53
|
initial_state: :draft
|
|
35
54
|
]
|
|
36
55
|
|
|
56
|
+
# @TODO: Rename this to publication_state_machine
|
|
37
57
|
def state_machine
|
|
38
58
|
@state_machine ||= DocumentStateMachine.new(self, transition_class: DocumentTransition)
|
|
39
59
|
end
|
|
40
60
|
|
|
61
|
+
include Statesman::Adapters::ActiveRecordQueries[
|
|
62
|
+
transition_class: DocumentThumbnailTransition,
|
|
63
|
+
initial_state: :initialized
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
def thumbnail_state_machine
|
|
67
|
+
@thumbnail_state_machine ||= DocumentThumbnailStateMachine.new(self, transition_class: DocumentThumbnailTransition)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def raw_solr_document
|
|
71
|
+
Blacklight.default_index.connection.get("select", {params: {q: "id:\"#{geomg_id_s}\""}})["response"]["docs"][0]
|
|
72
|
+
end
|
|
73
|
+
|
|
41
74
|
delegate :current_state, to: :state_machine
|
|
42
75
|
|
|
43
76
|
before_save :transition_publication_state, unless: :skip_callbacks
|
|
@@ -78,27 +111,101 @@ class Document < Kithe::Work
|
|
|
78
111
|
# Index Transformations - *_json functions
|
|
79
112
|
def references
|
|
80
113
|
references = ActiveSupport::HashWithIndifferentAccess.new
|
|
114
|
+
|
|
115
|
+
# Prep value arrays
|
|
116
|
+
send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
|
|
117
|
+
references[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] = []
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Seed value arrays
|
|
81
121
|
send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
|
|
82
|
-
|
|
122
|
+
# @TODO: Need to support multiple entries per key here
|
|
123
|
+
references[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] << ref.value
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
logger.debug("\n\nDocument#references > seeded: #{references}")
|
|
127
|
+
|
|
128
|
+
# Apply Downloads
|
|
129
|
+
references = apply_downloads(references)
|
|
130
|
+
|
|
131
|
+
logger.debug("Document#references > downloads: #{references}\n\n")
|
|
132
|
+
|
|
133
|
+
# Need to flatten the arrays here to avoid the following potential error:
|
|
134
|
+
# - ArgumentError: Please use symbols for polymorphic route arguments.
|
|
135
|
+
# - Via: app/helpers/geoblacklight_helper.rb:224:in `render_references_url'
|
|
136
|
+
references.each do |key, value|
|
|
137
|
+
next if key == "http://schema.org/downloadUrl"
|
|
138
|
+
if value.is_a?(Array) && value.length == 1
|
|
139
|
+
references[key] = value.first
|
|
140
|
+
end
|
|
83
141
|
end
|
|
84
|
-
|
|
142
|
+
|
|
143
|
+
references
|
|
85
144
|
end
|
|
86
145
|
|
|
87
146
|
def references_json
|
|
88
147
|
references.to_json
|
|
89
148
|
end
|
|
90
149
|
|
|
150
|
+
def asset_label(asset)
|
|
151
|
+
if asset.label.present?
|
|
152
|
+
asset.label
|
|
153
|
+
else
|
|
154
|
+
asset.title
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Apply Downloads
|
|
159
|
+
# 1. Native Aardvark Downloads
|
|
160
|
+
# 2. Multiple Document Download Links
|
|
161
|
+
# 3. Downloadable Document Assets
|
|
91
162
|
def apply_downloads(references)
|
|
163
|
+
multiple_downloads = []
|
|
164
|
+
|
|
92
165
|
dct_downloads = references["http://schema.org/downloadUrl"]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
166
|
+
|
|
167
|
+
logger.debug("Document#dct_downloads > init: #{dct_downloads}\n\n")
|
|
168
|
+
|
|
169
|
+
# Native Aardvark Downloads
|
|
170
|
+
# - Via CSV Import or via the webform
|
|
171
|
+
if dct_downloads.present?
|
|
172
|
+
dct_downloads.each do |download|
|
|
97
173
|
multiple_downloads << {label: download_text(send(GeoblacklightAdmin::Schema.instance.solr_fields[:format])),
|
|
98
|
-
|
|
174
|
+
url: download}
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
logger.debug("Document#multiple_downloads > aardvark: #{multiple_downloads.inspect}\n\n")
|
|
179
|
+
|
|
180
|
+
# Multiple Document Download Links
|
|
181
|
+
# - Via DocumentDownloads
|
|
182
|
+
if document_downloads.present?
|
|
183
|
+
multiple_downloads << multiple_downloads_array
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
logger.debug("Document#dct_downloads > document_downloads: #{multiple_downloads.inspect}\n\n")
|
|
187
|
+
|
|
188
|
+
# Downloadable Document Assets
|
|
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
|
|
99
203
|
end
|
|
100
|
-
references[:"http://schema.org/downloadUrl"] = multiple_downloads
|
|
101
204
|
end
|
|
205
|
+
|
|
206
|
+
logger.debug("Document#dct_downloads > downloadable_assets: #{multiple_downloads.inspect}\n\n")
|
|
207
|
+
|
|
208
|
+
references[:"http://schema.org/downloadUrl"] = multiple_downloads.flatten unless multiple_downloads.empty?
|
|
102
209
|
references
|
|
103
210
|
end
|
|
104
211
|
|
|
@@ -231,8 +338,9 @@ class Document < Kithe::Work
|
|
|
231
338
|
|
|
232
339
|
### End / From GBL
|
|
233
340
|
|
|
341
|
+
# Thumbnail is a special case of document_assets
|
|
234
342
|
def thumbnail
|
|
235
|
-
members.find { |m| m.respond_to?(:thumbnail) }
|
|
343
|
+
members.find { |m| m.respond_to?(:thumbnail) && m.thumbnail? }
|
|
236
344
|
end
|
|
237
345
|
|
|
238
346
|
def access_json
|
|
@@ -282,6 +390,9 @@ class Document < Kithe::Work
|
|
|
282
390
|
if value[:delimited]
|
|
283
391
|
send(value[:destination])&.join("|")
|
|
284
392
|
elsif value[:destination] == "dct_references_s"
|
|
393
|
+
# @TODO: Downloads need to be handled differently
|
|
394
|
+
# - Need to support multiple entries per key here
|
|
395
|
+
# - Need to respect label and url
|
|
285
396
|
dct_references_s_to_csv(key, value[:destination])
|
|
286
397
|
elsif value[:destination] == "b1g_publication_state_s"
|
|
287
398
|
send(:current_state)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Document Thumbnail State Machine
|
|
4
|
+
class DocumentThumbnailStateMachine
|
|
5
|
+
include Statesman::Machine
|
|
6
|
+
|
|
7
|
+
state :initialized, initial: true
|
|
8
|
+
state :queued
|
|
9
|
+
state :processing
|
|
10
|
+
state :succeeded
|
|
11
|
+
state :failed
|
|
12
|
+
state :placeheld
|
|
13
|
+
|
|
14
|
+
# Queued => Background Job Init
|
|
15
|
+
# Processing => Failed, Placeheld, Succeeded
|
|
16
|
+
transition from: :initialized, to: %i[queued processing]
|
|
17
|
+
transition from: :queued, to: %i[queued processing]
|
|
18
|
+
transition from: :processing, to: %i[queued processing placeheld succeeded failed]
|
|
19
|
+
transition from: :placeheld, to: %i[queued processing failed]
|
|
20
|
+
transition from: :failed, to: %i[queued processing]
|
|
21
|
+
transition from: :succeeded, to: %i[queued processing]
|
|
22
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add Document Thumbnail State Transitions
|
|
4
|
+
class DocumentThumbnailTransition < ApplicationRecord
|
|
5
|
+
include Statesman::Adapters::ActiveRecordTransition
|
|
6
|
+
|
|
7
|
+
# If your transition table doesn't have the default `updated_at` timestamp column,
|
|
8
|
+
# you'll need to configure the `updated_timestamp_column` option, setting it to
|
|
9
|
+
# another column name (e.g. `:updated_on`) or `nil`.
|
|
10
|
+
#
|
|
11
|
+
# self.updated_timestamp_column = :updated_on
|
|
12
|
+
# self.updated_timestamp_column = nil
|
|
13
|
+
|
|
14
|
+
belongs_to :document, inverse_of: :document_thumbnail_transitions, foreign_key: "kithe_model_id"
|
|
15
|
+
|
|
16
|
+
after_destroy :update_most_recent, if: :most_recent?
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def update_most_recent
|
|
21
|
+
last_transition = document.document_thumbnail_transitions.order(:sort_key).last
|
|
22
|
+
return if last_transition.blank?
|
|
23
|
+
|
|
24
|
+
last_transition.update_column(:most_recent, true)
|
|
25
|
+
end
|
|
26
|
+
end
|
data/app/models/element.rb
CHANGED
|
@@ -372,7 +372,13 @@ module GeoblacklightAdmin
|
|
|
372
372
|
"urn:x-esri:serviceType:ArcGIS#ImageMapLayer": "arcgis_image_map_layer",
|
|
373
373
|
"http://schema.org/DownloadAction": "harvard",
|
|
374
374
|
"https://openindexmaps.org": "open_index_map",
|
|
375
|
-
"https://oembed.com": "oembed"
|
|
375
|
+
"https://oembed.com": "oembed",
|
|
376
|
+
"https://github.com/cogeotiff/cog-spec": "cog",
|
|
377
|
+
"https://github.com/protomaps/PMTiles": "pmtiles",
|
|
378
|
+
"https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames": "xyz_tiles",
|
|
379
|
+
"http://www.opengis.net/def/serviceType/ogc/wmts": "wmts",
|
|
380
|
+
"https://github.com/mapbox/tilejson-spec": "tile_json",
|
|
381
|
+
"https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification": "tile_map_service"
|
|
376
382
|
})
|
|
377
383
|
end
|
|
378
384
|
end
|