iiif_print 3.2.0 → 3.2.1
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/Gemfile.lock +36 -36
- data/app/presenters/iiif_print/work_show_presenter_decorator.rb +13 -0
- data/app/services/iiif_print/manifest_builder_service_decorator.rb +8 -3
- data/app/transactions/hyrax/transactions/steps/delete_all_file_sets_decorator.rb +30 -7
- data/iiif_print.gemspec +0 -1
- data/lib/iiif_print/catalog_search_builder.rb +4 -6
- data/lib/iiif_print/current.rb +10 -0
- data/lib/iiif_print/engine.rb +3 -5
- data/lib/iiif_print/flexibility/compound_values.rb +58 -0
- data/lib/iiif_print/flexibility/fields.rb +1 -0
- data/lib/iiif_print/flexibility/values.rb +5 -14
- data/lib/iiif_print/flexibility.rb +27 -9
- data/lib/iiif_print/homepage_search_builder.rb +4 -6
- data/lib/iiif_print/persistence_layer/active_fedora_adapter.rb +5 -0
- data/lib/iiif_print/persistence_layer/valkyrie_adapter.rb +16 -7
- data/lib/iiif_print/version.rb +1 -1
- data/lib/iiif_print.rb +13 -1
- metadata +8 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ccac310b7d9a84e367cec7ea055b4b2b9af2d9817cbef9ccfaf3c68d467ce40
|
|
4
|
+
data.tar.gz: 621bb63d8990014bd1a4842ef6897628386515e6a3bcc76f0d212ba59a318f0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 687953bee3a35e17c5ed41e34e29324c7166736397356131f40f3e56b7f623004f9c07a8ff55019347288811740e8f3064dd5673f71357e4d6f153a79dcf8bb6
|
|
7
|
+
data.tar.gz: cdb91f7cbe9a6fd603f3ad5e38058dac9e8da93f1d10bd932e0a843deae24cb830f090c533b9e7bfb4dbdd9eb1fcd8509377d5bc34db41df92cd5321e19ee9bc
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: /app/samvera/hyrax-webapp
|
|
3
3
|
specs:
|
|
4
|
-
iiif_print (3.2.
|
|
4
|
+
iiif_print (3.2.1)
|
|
5
5
|
blacklight_iiif_search (>= 1.0, < 3.0)
|
|
6
6
|
derivative-rodeo (~> 0.5)
|
|
7
7
|
hyrax (>= 2.5, < 6)
|
|
8
8
|
nokogiri (>= 1.13.2)
|
|
9
9
|
rdf-vocab (~> 3.0)
|
|
10
|
-
request_store (>= 1.0)
|
|
11
10
|
|
|
12
11
|
GEM
|
|
13
12
|
remote: https://rubygems.org/
|
|
@@ -66,7 +65,7 @@ GEM
|
|
|
66
65
|
activemodel (= 5.2.8.1)
|
|
67
66
|
activesupport (= 5.2.8.1)
|
|
68
67
|
arel (>= 9.0)
|
|
69
|
-
activerecord-import (2.
|
|
68
|
+
activerecord-import (2.3.0)
|
|
70
69
|
activerecord (>= 4.2)
|
|
71
70
|
activestorage (5.2.8.1)
|
|
72
71
|
actionpack (= 5.2.8.1)
|
|
@@ -81,19 +80,19 @@ GEM
|
|
|
81
80
|
public_suffix (>= 2.0.2, < 8.0)
|
|
82
81
|
almond-rails (0.3.0)
|
|
83
82
|
rails (>= 4.2)
|
|
84
|
-
anonymous_loader (0.1.
|
|
85
|
-
version_gem (~> 1.1, >= 1.1.
|
|
83
|
+
anonymous_loader (0.1.3)
|
|
84
|
+
version_gem (~> 1.1, >= 1.1.14)
|
|
86
85
|
arel (9.0.0)
|
|
87
86
|
ast (2.4.2)
|
|
88
|
-
auth-sanitizer (0.2.
|
|
89
|
-
version_gem (~> 1.1, >= 1.1.
|
|
87
|
+
auth-sanitizer (0.2.3)
|
|
88
|
+
version_gem (~> 1.1, >= 1.1.14)
|
|
90
89
|
autoprefixer-rails (10.4.16.0)
|
|
91
90
|
execjs (~> 2)
|
|
92
91
|
awesome_nested_set (3.9.0)
|
|
93
92
|
activerecord (>= 4.0.0, < 8.2)
|
|
94
93
|
aws-eventstream (1.4.0)
|
|
95
|
-
aws-partitions (1.
|
|
96
|
-
aws-sdk-core (3.
|
|
94
|
+
aws-partitions (1.1293.0)
|
|
95
|
+
aws-sdk-core (3.254.1)
|
|
97
96
|
aws-eventstream (~> 1, >= 1.3.0)
|
|
98
97
|
aws-partitions (~> 1, >= 1.992.0)
|
|
99
98
|
aws-sigv4 (~> 1.9)
|
|
@@ -101,15 +100,15 @@ GEM
|
|
|
101
100
|
bigdecimal
|
|
102
101
|
jmespath (~> 1, >= 1.6.1)
|
|
103
102
|
logger
|
|
104
|
-
aws-sdk-kms (1.
|
|
105
|
-
aws-sdk-core (~> 3, >= 3.
|
|
103
|
+
aws-sdk-kms (1.130.0)
|
|
104
|
+
aws-sdk-core (~> 3, >= 3.254.0)
|
|
106
105
|
aws-sigv4 (~> 1.5)
|
|
107
|
-
aws-sdk-s3 (1.
|
|
108
|
-
aws-sdk-core (~> 3, >= 3.
|
|
106
|
+
aws-sdk-s3 (1.230.0)
|
|
107
|
+
aws-sdk-core (~> 3, >= 3.254.1)
|
|
109
108
|
aws-sdk-kms (~> 1)
|
|
110
109
|
aws-sigv4 (~> 1.5)
|
|
111
|
-
aws-sdk-sqs (1.
|
|
112
|
-
aws-sdk-core (~> 3, >= 3.
|
|
110
|
+
aws-sdk-sqs (1.117.0)
|
|
111
|
+
aws-sdk-core (~> 3, >= 3.254.0)
|
|
113
112
|
aws-sigv4 (~> 1.5)
|
|
114
113
|
aws-sigv4 (1.12.1)
|
|
115
114
|
aws-eventstream (~> 1, >= 1.0.2)
|
|
@@ -123,7 +122,7 @@ GEM
|
|
|
123
122
|
i18n
|
|
124
123
|
bcrypt (3.1.21)
|
|
125
124
|
benchmark (0.3.0)
|
|
126
|
-
bigdecimal (4.1.
|
|
125
|
+
bigdecimal (4.1.3)
|
|
127
126
|
bindex (0.8.1)
|
|
128
127
|
bixby (5.0.2)
|
|
129
128
|
rubocop (= 1.28.2)
|
|
@@ -193,7 +192,7 @@ GEM
|
|
|
193
192
|
thor (>= 0.19.4, < 2.0)
|
|
194
193
|
tins (~> 1.6)
|
|
195
194
|
crass (1.0.6)
|
|
196
|
-
csv (3.3.
|
|
195
|
+
csv (3.3.6)
|
|
197
196
|
database_cleaner (1.99.0)
|
|
198
197
|
date (3.3.4)
|
|
199
198
|
declarative (0.0.20)
|
|
@@ -354,8 +353,8 @@ GEM
|
|
|
354
353
|
logger
|
|
355
354
|
hiredis (0.6.3)
|
|
356
355
|
htmlentities (4.4.2)
|
|
357
|
-
http_logger (1.0.
|
|
358
|
-
httparty (0.24.
|
|
356
|
+
http_logger (1.0.3)
|
|
357
|
+
httparty (0.24.3)
|
|
359
358
|
csv
|
|
360
359
|
mini_mime (>= 1.0.0)
|
|
361
360
|
multi_xml (>= 0.5.2)
|
|
@@ -468,7 +467,7 @@ GEM
|
|
|
468
467
|
activesupport (>= 3.2.18)
|
|
469
468
|
faraday (>= 0.9)
|
|
470
469
|
json
|
|
471
|
-
iiif_manifest (1.
|
|
470
|
+
iiif_manifest (1.7.0)
|
|
472
471
|
activesupport (>= 4)
|
|
473
472
|
jaro_winkler (1.5.6)
|
|
474
473
|
jbuilder (2.12.0)
|
|
@@ -498,7 +497,7 @@ GEM
|
|
|
498
497
|
json-ld-preloaded (3.1.6)
|
|
499
498
|
json-ld (~> 3.1)
|
|
500
499
|
rdf (~> 3.1)
|
|
501
|
-
json-schema (6.2.
|
|
500
|
+
json-schema (6.2.1)
|
|
502
501
|
addressable (~> 2.8)
|
|
503
502
|
bigdecimal (>= 3.1, < 5)
|
|
504
503
|
jwt (2.10.3)
|
|
@@ -590,7 +589,7 @@ GEM
|
|
|
590
589
|
mime-types (3.7.0)
|
|
591
590
|
logger
|
|
592
591
|
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
|
593
|
-
mime-types-data (3.2026.
|
|
592
|
+
mime-types-data (3.2026.1006)
|
|
594
593
|
mini_magick (4.13.2)
|
|
595
594
|
mini_mime (1.1.5)
|
|
596
595
|
mini_portile2 (2.8.5)
|
|
@@ -622,16 +621,17 @@ GEM
|
|
|
622
621
|
nokogiri (1.15.5)
|
|
623
622
|
mini_portile2 (~> 2.8.2)
|
|
624
623
|
racc (~> 1.4)
|
|
625
|
-
oauth (1.1.
|
|
626
|
-
|
|
624
|
+
oauth (1.1.8)
|
|
625
|
+
anonymous_loader (~> 0.1, >= 0.1.3)
|
|
626
|
+
auth-sanitizer (~> 0.2, >= 0.2.3)
|
|
627
627
|
base64 (~> 0.1)
|
|
628
|
-
oauth-tty (~> 1.0, >= 1.0.
|
|
629
|
-
snaky_hash (~> 2.0, >= 2.0.
|
|
630
|
-
version_gem (~> 1.1, >= 1.1.
|
|
631
|
-
oauth-tty (1.0.
|
|
632
|
-
anonymous_loader (~> 0.1, >= 0.1.
|
|
633
|
-
auth-sanitizer (~> 0.2, >= 0.2.
|
|
634
|
-
version_gem (~> 1.1, >= 1.1.
|
|
628
|
+
oauth-tty (~> 1.0, >= 1.0.13)
|
|
629
|
+
snaky_hash (~> 2.0, >= 2.0.7)
|
|
630
|
+
version_gem (~> 1.1, >= 1.1.14)
|
|
631
|
+
oauth-tty (1.0.13)
|
|
632
|
+
anonymous_loader (~> 0.1, >= 0.1.3)
|
|
633
|
+
auth-sanitizer (~> 0.2, >= 0.2.3)
|
|
634
|
+
version_gem (~> 1.1, >= 1.1.14)
|
|
635
635
|
oauth2 (1.4.11)
|
|
636
636
|
faraday (>= 0.17.3, < 3.0)
|
|
637
637
|
jwt (>= 1.0, < 3.0)
|
|
@@ -891,9 +891,9 @@ GEM
|
|
|
891
891
|
simplecov-html (~> 0.10.0)
|
|
892
892
|
simplecov-html (0.10.2)
|
|
893
893
|
slop (4.10.1)
|
|
894
|
-
snaky_hash (2.0.
|
|
894
|
+
snaky_hash (2.0.7)
|
|
895
895
|
hashie (>= 0.1.0, < 6)
|
|
896
|
-
version_gem (
|
|
896
|
+
version_gem (~> 1.1, >= 1.1.14)
|
|
897
897
|
solargraph (0.48.0)
|
|
898
898
|
backport (~> 1.2)
|
|
899
899
|
benchmark
|
|
@@ -944,7 +944,7 @@ GEM
|
|
|
944
944
|
matrix (~> 0.4)
|
|
945
945
|
rdf (~> 3.2)
|
|
946
946
|
sync (0.5.0)
|
|
947
|
-
temple (0.10.
|
|
947
|
+
temple (0.10.7)
|
|
948
948
|
term-ansicolor (1.7.1)
|
|
949
949
|
tins (~> 1.0)
|
|
950
950
|
terminal-table (4.0.0)
|
|
@@ -972,7 +972,7 @@ GEM
|
|
|
972
972
|
uglifier (4.2.0)
|
|
973
973
|
execjs (>= 0.3.0, < 3)
|
|
974
974
|
unicode-display_width (2.5.0)
|
|
975
|
-
unicode-types (1.
|
|
975
|
+
unicode-types (1.12.0)
|
|
976
976
|
valkyrie (2.2.0)
|
|
977
977
|
activemodel
|
|
978
978
|
activesupport
|
|
@@ -988,7 +988,7 @@ GEM
|
|
|
988
988
|
rdf-vocab
|
|
989
989
|
reform (~> 2.2)
|
|
990
990
|
reform-rails
|
|
991
|
-
version_gem (1.1.
|
|
991
|
+
version_gem (1.1.15)
|
|
992
992
|
warden (1.2.9)
|
|
993
993
|
rack (>= 2.0.9)
|
|
994
994
|
web-console (3.7.0)
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module IiifPrint
|
|
4
|
+
# @deprecated IiifPrint has not applied this since 3.0; Hyrax::WorkShowPresenter#iiif_viewer? now counts
|
|
5
|
+
# images on child works. Removed in IiifPrint 4.0.
|
|
4
6
|
module WorkShowPresenterDecorator
|
|
7
|
+
DEPRECATION_MESSAGE = "IiifPrint::WorkShowPresenterDecorator is deprecated and will be removed in IiifPrint 4.0; " \
|
|
8
|
+
"Hyrax::WorkShowPresenter#iiif_viewer? now counts images on child works."
|
|
9
|
+
|
|
10
|
+
def self.prepended(_base)
|
|
11
|
+
Deprecation.warn(self, DEPRECATION_MESSAGE)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.included(_base)
|
|
15
|
+
Deprecation.warn(self, DEPRECATION_MESSAGE)
|
|
16
|
+
end
|
|
17
|
+
|
|
5
18
|
delegate :member_ids, to: :solr_document
|
|
6
19
|
alias file_set_ids member_ids
|
|
7
20
|
|
|
@@ -65,14 +65,19 @@ module IiifPrint
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def sanitize_v3(hash:, presenter:, solr_doc_hits:)
|
|
68
|
-
|
|
68
|
+
sanitize_v3_label(hash)
|
|
69
69
|
hash['items'].each do |canvas|
|
|
70
|
-
canvas
|
|
70
|
+
sanitize_v3_label(canvas)
|
|
71
71
|
apply_metadata_to_canvas(canvas: canvas, presenter: presenter, solr_doc_hits: solr_doc_hits)
|
|
72
72
|
end
|
|
73
73
|
hash
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
# A v3 label is a language map: { 'none' => [...] }, { 'en' => [...] }, ...
|
|
77
|
+
def sanitize_v3_label(node)
|
|
78
|
+
node['label']&.each_value { |texts| texts.map! { |text| CGI.unescapeHTML(sanitize_value(text)) } }
|
|
79
|
+
end
|
|
80
|
+
|
|
76
81
|
def apply_metadata_to_canvas(canvas:, presenter:, solr_doc_hits:)
|
|
77
82
|
return if @child_works.empty?
|
|
78
83
|
|
|
@@ -152,6 +157,6 @@ module IiifPrint
|
|
|
152
157
|
results
|
|
153
158
|
end
|
|
154
159
|
end
|
|
155
|
-
# rubocop:enable Metrics/
|
|
160
|
+
# rubocop:enable Metrics/ModuleLength
|
|
156
161
|
end
|
|
157
162
|
Hyrax::ManifestBuilderService.prepend(IiifPrint::ManifestBuilderServiceDecorator)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# OVERRIDE Hyrax 5.
|
|
3
|
+
# OVERRIDE Hyrax 5.3.1
|
|
4
|
+
# - add file_set.iiif_print_conditionally_destroy_spawned_children with user args
|
|
5
|
+
# - skip file_set.remove_from_work when WorkDestroy can repair the work itself (samvera/hyrax#7682)
|
|
6
|
+
# - fail without a user, as Hyrax does from samvera/hyrax#7682
|
|
4
7
|
|
|
5
8
|
module Hyrax
|
|
6
9
|
module Transactions
|
|
@@ -16,19 +19,39 @@ module Hyrax
|
|
|
16
19
|
def call(resource, user: nil)
|
|
17
20
|
return Failure(:resource_not_persisted) unless resource.persisted?
|
|
18
21
|
|
|
22
|
+
# OVERRIDE: iiif_print step args, and remove_from_work only when needed
|
|
23
|
+
destroy = iiif_print_file_set_destroy(user: user)
|
|
19
24
|
@query_service.custom_queries.find_child_file_sets(resource: resource).each do |file_set|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.with_step_args('file_set.remove_from_work' => { user: user },
|
|
23
|
-
'file_set.delete' => { user: user },
|
|
24
|
-
'file_set.iiif_print_conditionally_destroy_spawned_children' => { user: user })
|
|
25
|
-
.call(file_set).success?
|
|
25
|
+
# OVERRIDE: require a user
|
|
26
|
+
return Failure[:failed_to_delete_file_set, file_set] unless user && destroy.call(file_set).success?
|
|
26
27
|
rescue ::Ldp::Gone
|
|
27
28
|
nil
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
Success(resource)
|
|
31
32
|
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def iiif_print_file_set_destroy(user:)
|
|
37
|
+
transaction = Hyrax::Transactions::Container['file_set.destroy'].dup
|
|
38
|
+
step_args = { 'file_set.delete' => { user: user },
|
|
39
|
+
'file_set.iiif_print_conditionally_destroy_spawned_children' => { user: user } }
|
|
40
|
+
if work_destroy_repairs_members?
|
|
41
|
+
# The work is about to be deleted; removing each file set from it would only re-save
|
|
42
|
+
# and re-index it, and queue update events for an object that will be gone.
|
|
43
|
+
transaction.steps -= ['file_set.remove_from_work']
|
|
44
|
+
else
|
|
45
|
+
step_args['file_set.remove_from_work'] = { user: user }
|
|
46
|
+
end
|
|
47
|
+
transaction.with_step_args(**step_args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Without this repair, a failed later step would leave the surviving work listing
|
|
51
|
+
# file sets that no longer exist, so they must be removed from it as they go.
|
|
52
|
+
def work_destroy_repairs_members?
|
|
53
|
+
Hyrax::Transactions::WorkDestroy.private_method_defined?(:remove_missing_members)
|
|
54
|
+
end
|
|
32
55
|
end
|
|
33
56
|
end
|
|
34
57
|
end
|
data/iiif_print.gemspec
CHANGED
|
@@ -25,7 +25,6 @@ SUMMARY
|
|
|
25
25
|
spec.add_dependency 'hyrax', '>= 2.5', '< 6'
|
|
26
26
|
spec.add_dependency 'nokogiri', '>=1.13.2'
|
|
27
27
|
spec.add_dependency 'rdf-vocab', '~> 3.0'
|
|
28
|
-
spec.add_dependency 'request_store', '>= 1.0'
|
|
29
28
|
|
|
30
29
|
spec.add_development_dependency 'bixby'
|
|
31
30
|
spec.add_development_dependency 'database_cleaner', '~> 1.3'
|
|
@@ -24,12 +24,10 @@ module IiifPrint
|
|
|
24
24
|
|
|
25
25
|
# rubocop:enable Naming/PredicateName
|
|
26
26
|
def show_parents_only(solr_parameters)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
solr_parameters[:fq] += [query]
|
|
27
|
+
return if blacklight_params["include_child_works"] == 'true'
|
|
28
|
+
|
|
29
|
+
# Only child works are left out; a work indexed with is_child_bsi false is not a child.
|
|
30
|
+
solr_parameters[:fq] += ['-is_child_bsi:true']
|
|
33
31
|
end
|
|
34
32
|
end
|
|
35
33
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IiifPrint
|
|
4
|
+
##
|
|
5
|
+
# Per-request state. Rails resets it around every request and job, where RequestStore was only cleared by its
|
|
6
|
+
# Rack middleware and so lived as long as a job's thread.
|
|
7
|
+
class Current < ActiveSupport::CurrentAttributes
|
|
8
|
+
attribute :anonymous_ability, :presenters, :view_definitions
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/iiif_print/engine.rb
CHANGED
|
@@ -2,7 +2,6 @@ require 'active_fedora'
|
|
|
2
2
|
require 'hyrax'
|
|
3
3
|
require 'blacklight_iiif_search'
|
|
4
4
|
require 'derivative_rodeo'
|
|
5
|
-
require 'request_store'
|
|
6
5
|
|
|
7
6
|
module IiifPrint
|
|
8
7
|
# module constants:
|
|
@@ -43,11 +42,10 @@ module IiifPrint
|
|
|
43
42
|
# To configure specific services, inject each service, in desired order
|
|
44
43
|
# to IiifPrint::PluggableDerivativeService.plugins array.
|
|
45
44
|
|
|
46
|
-
Hyrax::DerivativeService.services
|
|
47
|
-
|
|
48
|
-
)
|
|
45
|
+
derivative_services = Hyrax::DerivativeService.services
|
|
46
|
+
derivative_services.unshift(IiifPrint::PluggableDerivativeService) unless derivative_services.include?(IiifPrint::PluggableDerivativeService)
|
|
49
47
|
|
|
50
|
-
|
|
48
|
+
IiifPrint.subscribe_listener if Hyrax.respond_to?(:publisher)
|
|
51
49
|
|
|
52
50
|
# Load locales early so decorators can use them during initialization
|
|
53
51
|
I18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.yml'),
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IiifPrint
|
|
4
|
+
module Flexibility
|
|
5
|
+
##
|
|
6
|
+
# A compound field's entries, one paragraph each, rendered the way its show page renders them.
|
|
7
|
+
class CompoundValues
|
|
8
|
+
# @return [Boolean] whether the entry has no value to show
|
|
9
|
+
def self.blank_entry?(entry)
|
|
10
|
+
Array(entry.try(:values) || entry).none?(&:present?)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @param field_name [Symbol]
|
|
14
|
+
# @param presenter [#solr_document] the record's show presenter
|
|
15
|
+
# @param sanitize [#call] makes rendered html IIIF-safe
|
|
16
|
+
def initialize(field_name, presenter:, sanitize:)
|
|
17
|
+
@field_name = field_name
|
|
18
|
+
@presenter = presenter
|
|
19
|
+
@sanitize = sanitize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param entries [Array<Hash>]
|
|
23
|
+
# @return [String] html
|
|
24
|
+
def to_html(entries)
|
|
25
|
+
subproperties = compound_subproperties
|
|
26
|
+
entries.reject { |entry| self.class.blank_entry?(entry) }
|
|
27
|
+
.map { |entry| "<p>#{entry_html(entry, subproperties)}</p>" }.join
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# As Hyrax's compound renderer, and any decorator the app gives it, renders the entry, with a line break where
|
|
33
|
+
# each innermost block ended, since IIIF allows no blocks.
|
|
34
|
+
def entry_html(entry, subproperties)
|
|
35
|
+
return plain_html(entry) unless defined?(Hyrax::Renderers::CompoundAttributeRenderer)
|
|
36
|
+
|
|
37
|
+
renderer = Hyrax::Renderers::CompoundAttributeRenderer.new(@field_name, [entry], subproperties: subproperties)
|
|
38
|
+
fragment = Nokogiri::HTML.fragment(renderer.render_value)
|
|
39
|
+
fragment.css('div').each { |div| div.add_next_sibling('<br>') unless div.at_css('div') }
|
|
40
|
+
@sanitize.call(fragment.to_html).gsub(/\s*<br>\s*/, '<br>').sub(/(<br>)+\z/, '')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def plain_html(entry)
|
|
44
|
+
Array(entry.try(:values) || entry).reject(&:blank?).map { |value| ERB::Util.h(value) }.join('<br>')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The lookup Hyrax's PresentsAttributes#compound_subproperties_for makes, which is private.
|
|
48
|
+
def compound_subproperties
|
|
49
|
+
return unless defined?(Hyrax::CompoundSchema) && @presenter.respond_to?(:solr_document)
|
|
50
|
+
|
|
51
|
+
Hyrax::CompoundSchema.for_solr_document(@presenter.solr_document).definition_for(@field_name)&.fetch(:subproperties, nil)
|
|
52
|
+
rescue StandardError => e
|
|
53
|
+
Rails.logger.debug("IiifPrint could not read #{@field_name}'s compound sub-properties: #{e.message}")
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -52,6 +52,7 @@ module IiifPrint
|
|
|
52
52
|
!(options[:admin_only] || options[:editor_only] || options[:show_page] == false)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
# Mirrors Hyrax's AttributesHelper#conform_options, so a field is labeled as its show page labels it.
|
|
55
56
|
def label(name, options)
|
|
56
57
|
labels = options[:display_label] || {}
|
|
57
58
|
label = (labels[I18n.locale.to_s] || labels['default'] || name).to_s
|
|
@@ -22,16 +22,16 @@ module IiifPrint
|
|
|
22
22
|
@autolink = autolink
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
# @return [Array] the field's values as stored, blanks dropped
|
|
25
|
+
# @return [Array] the field's values as stored, blanks and all-blank compound entries dropped
|
|
26
26
|
def raw(field_name)
|
|
27
|
-
Array(@presenter.try(field_name)).reject(
|
|
27
|
+
Array(@presenter.try(field_name)).reject { |value| CompoundValues.blank_entry?(value) }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# @return [Array<String>] the field's values as html
|
|
31
31
|
def rendered(field_name, options)
|
|
32
32
|
options ||= {}
|
|
33
33
|
values = Array(@presenter.try(field_name)).reject(&:blank?)
|
|
34
|
-
return [
|
|
34
|
+
return [compound_values(field_name, values)] if options[:render_as].to_s == 'compound'
|
|
35
35
|
|
|
36
36
|
labels = labels_for(field_name, values)
|
|
37
37
|
values.map { |value| value(field_name, value.to_s, labels[value.to_s], options) }
|
|
@@ -127,17 +127,8 @@ module IiifPrint
|
|
|
127
127
|
url
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def compound_value(field_name, entry)
|
|
133
|
-
renderer = Hyrax::Renderers::CompoundAttributeRenderer.new(field_name, [entry], subproperties: compound_subproperties(field_name))
|
|
134
|
-
fragment = Nokogiri::HTML.fragment(renderer.render_value)
|
|
135
|
-
fragment.css('div').each { |div| div.add_next_sibling('<br>') unless div.at_css('div') }
|
|
136
|
-
sanitize_html(fragment.to_html).gsub(/\s*<br>\s*/, '<br>').sub(/(<br>)+\z/, '')
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def compound_subproperties(field_name)
|
|
140
|
-
@presenter.send(:compound_subproperties_for, field_name) if @presenter.respond_to?(:compound_subproperties_for, true)
|
|
130
|
+
def compound_values(field_name, entries)
|
|
131
|
+
CompoundValues.new(field_name, presenter: @presenter, sanitize: method(:sanitize_html)).to_html(entries)
|
|
141
132
|
end
|
|
142
133
|
|
|
143
134
|
def link(href, text)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "iiif_print/flexibility/fields"
|
|
4
|
+
require "iiif_print/flexibility/compound_values"
|
|
4
5
|
require "iiif_print/flexibility/values"
|
|
5
6
|
|
|
6
7
|
module IiifPrint
|
|
@@ -15,40 +16,57 @@ module IiifPrint
|
|
|
15
16
|
Hyrax.config.try(:flexible?) && document.try(:flexible?)
|
|
16
17
|
end
|
|
17
18
|
|
|
19
|
+
##
|
|
20
|
+
# One per request for each record and ability, since both the fields and their values read from it.
|
|
18
21
|
def presenter_for(document, ability)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
controller = "Hyrax::#{document.hydra_model.model_name.collection.camelize}Controller".safe_constantize
|
|
22
|
-
(controller&.show_presenter || Hyrax::WorkShowPresenter).new(document, ability)
|
|
22
|
+
presenters = Current.presenters ||= {}
|
|
23
|
+
presenters[[document.id, ability]] ||= build_presenter(document, ability)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
##
|
|
26
27
|
# The profile's view definitions for the record, plus its title, description and abstract when the profile
|
|
27
|
-
# gives them no view block, since the show page shows those outside
|
|
28
|
+
# gives them no view block and allows them in the record's contexts, since the show page shows those outside
|
|
29
|
+
# its field list. Read once per request
|
|
28
30
|
# for each tenant, schema, version and context; each tenant numbers its own profile versions.
|
|
29
31
|
def view_definitions_for(document)
|
|
30
|
-
cache =
|
|
32
|
+
cache = Current.view_definitions ||= {}
|
|
31
33
|
version = document.try(:schema_version)
|
|
32
34
|
contexts = document.try(:contexts)
|
|
33
35
|
tenant = Apartment::Tenant.current if defined?(Apartment::Tenant)
|
|
34
36
|
cache[[tenant, schema_name(document), version, contexts]] ||= begin
|
|
35
37
|
definitions = Hyrax::Schema.m3_schema_loader.view_definitions_for(schema: schema_name(document), version: version, contexts: contexts)
|
|
36
|
-
lead_definitions(document, definitions).merge(definitions.to_h.symbolize_keys)
|
|
38
|
+
lead_definitions(document, definitions, contexts).merge(definitions.to_h.symbolize_keys)
|
|
37
39
|
end
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
private
|
|
41
43
|
|
|
44
|
+
def build_presenter(document, ability)
|
|
45
|
+
return Hyrax::FileSetPresenter.new(document, ability) if document.file_set?
|
|
46
|
+
|
|
47
|
+
controller = "Hyrax::#{document.hydra_model.model_name.collection.camelize}Controller".safe_constantize
|
|
48
|
+
(controller&.show_presenter || Hyrax::WorkShowPresenter).new(document, ability)
|
|
49
|
+
end
|
|
50
|
+
|
|
42
51
|
LEAD_FIELDS = %i[title description abstract].freeze
|
|
43
52
|
|
|
44
|
-
def lead_definitions(document, definitions)
|
|
53
|
+
def lead_definitions(document, definitions, contexts)
|
|
45
54
|
attributes = profile_attributes(document)
|
|
46
55
|
(LEAD_FIELDS - definitions.to_h.keys.map(&:to_sym)).each_with_object({}) do |name, lead|
|
|
47
56
|
config = attributes[name.to_s]
|
|
48
|
-
|
|
57
|
+
next unless config && in_context?(config, contexts)
|
|
58
|
+
|
|
59
|
+
lead[name] = Hyrax::SchemaLoader::AttributeDefinition.new(name.to_s, config).view_options
|
|
49
60
|
end
|
|
50
61
|
end
|
|
51
62
|
|
|
63
|
+
# The filter Hyrax's M3SchemaLoader applies to every field the profile gives a view block.
|
|
64
|
+
def in_context?(config, contexts)
|
|
65
|
+
return true if config['context'].blank?
|
|
66
|
+
|
|
67
|
+
(Array(contexts) & Array(config['context'])).any?
|
|
68
|
+
end
|
|
69
|
+
|
|
52
70
|
def profile_attributes(document)
|
|
53
71
|
schema = Hyrax::FlexibleSchema.find_by(id: document.try(:schema_version)) || Hyrax::FlexibleSchema.order(:created_at).last
|
|
54
72
|
schema.try(:attributes_for, schema_name(document)) || {}
|
|
@@ -6,12 +6,10 @@ module IiifPrint
|
|
|
6
6
|
self.default_processor_chain += [:show_parents_only]
|
|
7
7
|
|
|
8
8
|
def show_parents_only(solr_parameters)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
end
|
|
14
|
-
solr_parameters[:fq] += [query]
|
|
9
|
+
return if blacklight_params["include_child_works"] == 'true'
|
|
10
|
+
|
|
11
|
+
# Only child works are left out; a work indexed with is_child_bsi false is not a child.
|
|
12
|
+
solr_parameters[:fq] += ['-is_child_bsi:true']
|
|
15
13
|
end
|
|
16
14
|
end
|
|
17
15
|
end
|
|
@@ -60,7 +60,12 @@ module IiifPrint
|
|
|
60
60
|
parent_of_file_set&.member_of&.find(&:work?)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
# @deprecated Use Hyrax::SolrQueryBuilderService.construct_query, or ActiveFedora::SolrQueryBuilder.construct_query
|
|
64
|
+
# on a Hyrax without it; removed in IiifPrint 4.0.
|
|
63
65
|
def self.solr_construct_query(*args)
|
|
66
|
+
Deprecation.warn(self, "solr_construct_query is deprecated and will be removed in IiifPrint 4.0; " \
|
|
67
|
+
"use Hyrax::SolrQueryBuilderService.construct_query instead, or " \
|
|
68
|
+
"ActiveFedora::SolrQueryBuilder.construct_query on a Hyrax without it.")
|
|
64
69
|
if defined?(Hyrax::SolrQueryBuilderService)
|
|
65
70
|
Hyrax::SolrQueryBuilderService.construct_query(*args)
|
|
66
71
|
else
|
|
@@ -68,7 +68,10 @@ module IiifPrint
|
|
|
68
68
|
Hyrax.query_service.find_parents(resource: parent).first
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
# @deprecated Use Hyrax::SolrQueryBuilderService.construct_query; removed in IiifPrint 4.0.
|
|
71
72
|
def self.solr_construct_query(*args)
|
|
73
|
+
Deprecation.warn(self, "solr_construct_query is deprecated and will be removed in IiifPrint 4.0; " \
|
|
74
|
+
"use Hyrax::SolrQueryBuilderService.construct_query instead.")
|
|
72
75
|
Hyrax::SolrQueryBuilderService.construct_query(*args)
|
|
73
76
|
end
|
|
74
77
|
|
|
@@ -94,7 +97,7 @@ module IiifPrint
|
|
|
94
97
|
# Building a custom query to find these child works directly via the attribute would be more efficient.
|
|
95
98
|
# However, it would require more effort for a lesser-used feature, and would not allow for the fallback
|
|
96
99
|
# of finding child works by title.
|
|
97
|
-
# rubocop:disable Lint/UnusedMethodArgument
|
|
100
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
|
98
101
|
def self.destroy_children_split_from(file_set:, work:, model:, user:)
|
|
99
102
|
all_child_works = Hyrax.custom_queries.find_child_works(resource: work).to_a
|
|
100
103
|
return if all_child_works.blank?
|
|
@@ -114,14 +117,20 @@ module IiifPrint
|
|
|
114
117
|
Hyrax.index_adapter.save(resource: work)
|
|
115
118
|
Hyrax.publisher.publish('object.membership.updated', object: work, user: user)
|
|
116
119
|
|
|
117
|
-
children.each
|
|
118
|
-
Hyrax.persister.delete(resource: rcd)
|
|
119
|
-
Hyrax.index_adapter.delete(resource: rcd)
|
|
120
|
-
Hyrax.publisher.publish('object.deleted', object: rcd, user: user)
|
|
121
|
-
end
|
|
120
|
+
children.each { |child| destroy_child_work(child, user: user || ::User.system_user) }
|
|
122
121
|
true
|
|
123
122
|
end
|
|
124
|
-
# rubocop:enable Lint/UnusedMethodArgument
|
|
123
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
|
124
|
+
|
|
125
|
+
# Not persister.delete: the work transaction also deletes the child's own file sets.
|
|
126
|
+
def self.destroy_child_work(child, user:)
|
|
127
|
+
result = Hyrax::Transactions::Container['work_resource.destroy']
|
|
128
|
+
.with_step_args('work_resource.delete_all_file_sets' => { user: user },
|
|
129
|
+
'work_resource.delete' => { user: user })
|
|
130
|
+
.call(child)
|
|
131
|
+
Rails.logger.error("IiifPrint could not destroy split child work #{child.id}: #{result.failure.inspect}") if result.failure?
|
|
132
|
+
result
|
|
133
|
+
end
|
|
125
134
|
|
|
126
135
|
def self.pdf?(file_set)
|
|
127
136
|
file_set.original_file&.pdf?
|
data/lib/iiif_print/version.rb
CHANGED
data/lib/iiif_print.rb
CHANGED
|
@@ -13,6 +13,8 @@ require "iiif_print/text_formats_from_alto_service"
|
|
|
13
13
|
require "iiif_print/tiff_derivative_service"
|
|
14
14
|
require "iiif_print/lineage_service"
|
|
15
15
|
require "iiif_print/metadata"
|
|
16
|
+
# ActiveSupport::CurrentAttributes arrived in Rails 5.2; only the flexible metadata path, which needs a newer Hyrax, uses it.
|
|
17
|
+
require "iiif_print/current" if defined?(ActiveSupport::CurrentAttributes)
|
|
16
18
|
require "iiif_print/flexibility"
|
|
17
19
|
require "iiif_print/split_pdfs/base_splitter"
|
|
18
20
|
require "iiif_print/split_pdfs/child_work_creation_from_pdf_service"
|
|
@@ -42,6 +44,16 @@ module IiifPrint
|
|
|
42
44
|
@config
|
|
43
45
|
end
|
|
44
46
|
|
|
47
|
+
##
|
|
48
|
+
# Subscribes a new IiifPrint::Listener in place of the one an earlier prepare subscribed.
|
|
49
|
+
# Dry::Events neither deduplicates subscriptions nor unsubscribes by class, and after a code
|
|
50
|
+
# reload the earlier listener's class is the unloaded one, so it is tracked here.
|
|
51
|
+
def self.subscribe_listener(publisher: Hyrax.publisher)
|
|
52
|
+
publisher.unsubscribe(@listener) if @listener
|
|
53
|
+
@listener = IiifPrint::Listener.new
|
|
54
|
+
publisher.subscribe(@listener)
|
|
55
|
+
end
|
|
56
|
+
|
|
45
57
|
class << self
|
|
46
58
|
delegate(
|
|
47
59
|
:persistence_adapter,
|
|
@@ -221,7 +233,7 @@ module IiifPrint
|
|
|
221
233
|
|
|
222
234
|
# One per request: an Ability is costly to build, and a manifest can ask once for every page.
|
|
223
235
|
def self.anonymous_ability
|
|
224
|
-
|
|
236
|
+
Current.anonymous_ability ||= ::Ability.new(nil)
|
|
225
237
|
end
|
|
226
238
|
private_class_method :flexible_manifest_metadata_for, :anonymous_ability
|
|
227
239
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iiif_print
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.2.
|
|
4
|
+
version: 3.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sean Upton
|
|
@@ -11,9 +11,10 @@ authors:
|
|
|
11
11
|
- Kirk Wang
|
|
12
12
|
- LaRita Robinson
|
|
13
13
|
- Jeremy Friesen
|
|
14
|
+
autorequire:
|
|
14
15
|
bindir: bin
|
|
15
16
|
cert_chain: []
|
|
16
|
-
date:
|
|
17
|
+
date: 2026-10-09 00:00:00.000000000 Z
|
|
17
18
|
dependencies:
|
|
18
19
|
- !ruby/object:Gem::Dependency
|
|
19
20
|
name: blacklight_iiif_search
|
|
@@ -97,20 +98,6 @@ dependencies:
|
|
|
97
98
|
- - "~>"
|
|
98
99
|
- !ruby/object:Gem::Version
|
|
99
100
|
version: '3.0'
|
|
100
|
-
- !ruby/object:Gem::Dependency
|
|
101
|
-
name: request_store
|
|
102
|
-
requirement: !ruby/object:Gem::Requirement
|
|
103
|
-
requirements:
|
|
104
|
-
- - ">="
|
|
105
|
-
- !ruby/object:Gem::Version
|
|
106
|
-
version: '1.0'
|
|
107
|
-
type: :runtime
|
|
108
|
-
prerelease: false
|
|
109
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
110
|
-
requirements:
|
|
111
|
-
- - ">="
|
|
112
|
-
- !ruby/object:Gem::Version
|
|
113
|
-
version: '1.0'
|
|
114
101
|
- !ruby/object:Gem::Dependency
|
|
115
102
|
name: bixby
|
|
116
103
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -462,6 +449,7 @@ files:
|
|
|
462
449
|
- lib/iiif_print/blacklight_iiif_search/annotation_decorator.rb
|
|
463
450
|
- lib/iiif_print/catalog_search_builder.rb
|
|
464
451
|
- lib/iiif_print/configuration.rb
|
|
452
|
+
- lib/iiif_print/current.rb
|
|
465
453
|
- lib/iiif_print/data.rb
|
|
466
454
|
- lib/iiif_print/data/fileset_helper.rb
|
|
467
455
|
- lib/iiif_print/data/path_helper.rb
|
|
@@ -471,6 +459,7 @@ files:
|
|
|
471
459
|
- lib/iiif_print/engine.rb
|
|
472
460
|
- lib/iiif_print/errors.rb
|
|
473
461
|
- lib/iiif_print/flexibility.rb
|
|
462
|
+
- lib/iiif_print/flexibility/compound_values.rb
|
|
474
463
|
- lib/iiif_print/flexibility/fields.rb
|
|
475
464
|
- lib/iiif_print/flexibility/values.rb
|
|
476
465
|
- lib/iiif_print/homepage_search_builder.rb
|
|
@@ -513,6 +502,7 @@ homepage: https://github.com/notch8/iiif_print/
|
|
|
513
502
|
licenses:
|
|
514
503
|
- Apache-2.0
|
|
515
504
|
metadata: {}
|
|
505
|
+
post_install_message:
|
|
516
506
|
rdoc_options: []
|
|
517
507
|
require_paths:
|
|
518
508
|
- lib
|
|
@@ -527,7 +517,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
527
517
|
- !ruby/object:Gem::Version
|
|
528
518
|
version: '0'
|
|
529
519
|
requirements: []
|
|
530
|
-
rubygems_version: 3.
|
|
520
|
+
rubygems_version: 3.3.20
|
|
521
|
+
signing_key:
|
|
531
522
|
specification_version: 4
|
|
532
523
|
summary: IiifPrint is a gem (Rails "engine") for Hyrax-based digital repository applications
|
|
533
524
|
to support displaying parent/child works in the same viewer (Universal Viewer) and
|