geoblacklight_admin 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|