Skip to content

Commit 933cc84

Browse files
authored
Merge pull request #648 from IU-Libraries-Joint-Development/essi-2062_collection_thumbnails_in_s3
[ESSI-2062] fix iiif urls unaware of external_storage
2 parents 6effee7 + 40113a2 commit 933cc84

14 files changed

+223
-75
lines changed

app/controllers/purl_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def rescue_url
7676

7777
def jp2_url(solr_hit)
7878
begin
79-
Hyrax.config.iiif_image_url_builder.call(solr_hit['original_file_id_ssi'], nil, '!600,600')
79+
IIIFFileSetPathService.new(solr_hit).iiif_image_url(size: '!600,600')
8080
rescue StandardError
8181
nil
8282
end

app/helpers/catalog_helper.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ def thumbnail_url document
1515
else
1616
representative_document = ::SolrDocument.find(document.thumbnail_id)
1717
end
18-
19-
thumbnail_file_id = representative_document&.content_location
20-
thumbnail_file_id ||= representative_document.original_file_id
21-
if thumbnail_file_id
22-
Hyrax.config.iiif_image_url_builder.call(thumbnail_file_id, nil, '250,')
18+
iiif_path_service = IIIFFileSetPathService.new(representative_document)
19+
if iiif_path_service.lookup_id
20+
iiif_path_service.iiif_image_url(size: '250,')
2321
else
2422
raise 'thumbnail_file_id is nil'
2523
end

app/models/collection_branding_info.rb

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,19 @@ def find_local_dir_name(collection_id, role)
9595
File.join(Hyrax.config.branding_path, collection_id.to_s, role.to_s)
9696
end
9797

98-
# this passes a nil value for request base_url, as our custom url builder
99-
# does not use that argument, and the model also doesn't have a request
10098
def generate_image_path!
101-
if image_path.blank? && file_set_versions.any?
102-
original_uri = file_set_versions.all.last.uri
103-
uri_to_id = ActiveFedora::File.uri_to_id(original_uri.sub(/\/fcr.versions.*/,''))
104-
self.image_path = \
105-
Hyrax.config.iiif_image_url_builder.call(uri_to_id,
106-
nil,
107-
ESSI.config.dig(:essi, :collection_banner_size) || Hyrax.config.iiif_image_size_default)
99+
if image_path.blank? && iiif_path_service.lookup_id.present?
100+
self.image_path = iiif_path_service.iiif_image_url(size: ESSI.config.dig(:essi, :collection_banner_size))
108101
save
109102
end
110103
end
111104

112-
def file_set_versions
113-
file_set&.reload&.original_file&.versions || []
114-
end
115-
116105
def uploaded_files(uploaded_file_ids)
117106
return [] if uploaded_file_ids.empty?
118107
Hyrax::UploadedFile.find(uploaded_file_ids)
119108
end
109+
110+
def iiif_path_service
111+
@iiif_path_service ||= IIIFFileSetPathService.new(file_set || {})
112+
end
120113
end

app/models/file_set.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,9 @@ def ocr_language
2222
ESSI.config.dig(:essi, :ocr_language),
2323
'eng'].map { |l| Tesseract.try_languages(l) }.select(&:present?).first
2424
end
25+
26+
# @todo revisit after Hyrax 3.x upgrade
27+
def original_file_id
28+
@original_file_id ||= self.original_file&.id
29+
end
2530
end

app/presenters/hyrax/displays_image.rb

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,31 @@ module Hyrax
88
module DisplaysImage
99
extend ActiveSupport::Concern
1010

11-
delegate :content_location, to: :solr_document
12-
1311
# Creates a display image only where FileSet is an image.
1412
#
1513
# @return [IIIFManifest::DisplayImage] the display image required by the manifest builder.
1614
def display_image
1715
return nil unless solr_document.image? && current_ability.can?(:read, id)
18-
19-
latest_file_id = lookup_original_file_id
20-
21-
return nil unless latest_file_id
22-
23-
url = Hyrax.config.iiif_image_url_builder.call(
24-
latest_file_id,
25-
request.base_url,
26-
Hyrax.config.iiif_image_size_default
27-
)
16+
return nil unless iiif_path_service.lookup_id
2817

2918
# @see https://github.com/samvera-labs/iiif_manifest
30-
IIIFManifest::DisplayImage.new(url,
19+
IIIFManifest::DisplayImage.new(iiif_path_service.iiif_image_url,
3120
width: width,
3221
height: height,
33-
iiif_endpoint: iiif_endpoint(latest_file_id))
34-
end
35-
36-
def lookup_original_file_id
37-
return content_location if content_location&.start_with?('s3://')
38-
result = original_file_id
39-
if result.blank?
40-
Rails.logger.warn "original_file_id for #{id} not found, falling back to Fedora."
41-
# result = Hyrax::VersioningService.versioned_file_id ::FileSet.find(id).original_file
42-
result = versioned_file_id ::FileSet.find(id).original_file
43-
end
44-
result
22+
iiif_endpoint: iiif_endpoint)
4523
end
4624

4725
private
26+
def iiif_path_service
27+
@iiif_path_service ||= IIIFFileSetPathService.new(solr_document)
28+
end
4829

49-
def iiif_endpoint(file_id)
30+
def iiif_endpoint
5031
return unless Hyrax.config.iiif_image_server?
5132
IIIFManifest::IIIFEndpoint.new(
52-
Hyrax.config.iiif_info_url_builder.call(file_id, request.base_url),
33+
iiif_path_service.iiif_info_url(request.base_url),
5334
profile: Hyrax.config.iiif_image_compliance_level_uri
5435
)
5536
end
56-
57-
# @todo remove after upgrade to Hyrax 3.x
58-
# cherry-picked from Hyrax 3.x VersioningService
59-
# @param [ActiveFedora::File | Hyrax::FileMetadata] content
60-
def versioned_file_id(file)
61-
versions = file.versions.all
62-
if versions.present?
63-
ActiveFedora::File.uri_to_id versions.last.uri
64-
else
65-
file.id
66-
end
67-
end
6837
end
6938
end

app/services/essi/generate_pdf_service.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ def create_tmp_files(pdf)
4444
fs_solr = SolrDocument.find(fs)
4545
image_width = get_image_width(fs_solr).to_i
4646
raise StandardError, 'Image width unavailable' unless image_width > 0 # IIIF server call requires a positive integer value
47-
uri = Hyrax.config.iiif_image_url_builder.call(fs_solr.original_file_id, nil, render_dimensions(image_width))
47+
iiif_path_service = IIIFFileSetPathService.new(fs_solr)
48+
raise StandardError, 'Source image file unavailable' unless iiif_path_service.lookup_id
49+
uri = iiif_path_service.iiif_image_url(size: render_dimensions(image_width))
4850
URI.open(uri) do |file|
4951
page_size = [CoverPageGenerator::LETTER_WIDTH, CoverPageGenerator::LETTER_HEIGHT]
5052
file.binmode

app/services/iiif_collection_thumbnail_path_service.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class << self
33
# @return the network path to the thumbnail
44
# @param [FileSet] thumbnail the object that is the thumbnail
55
def thumbnail_path(thumbnail)
6-
Hyrax.config.iiif_image_url_builder.call(thumbnail.original_file.id, nil, '250,')
6+
IIIFFileSetPathService.new(thumbnail).iiif_image_url(size: '250,')
77
# Hyrax::Engine.routes.url_helpers.download_path(thumbnail.id,
88
# file: 'thumbnail')
99
end
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
class IIIFFileSetPathService
2+
attr_reader :file_set
3+
4+
# @param [ActiveFedora::SolrHit, FileSet, Hash, SolrDocument, Hyrax::FileSetPresenter] file_set
5+
def initialize(file_set)
6+
file_set = SolrDocument.new(file_set) if file_set.class.in? [ActiveFedora::SolrHit, Hash]
7+
if [:id, :content_location, :original_file_id].map { |m| file_set.respond_to?(m) }.all?
8+
@file_set = file_set
9+
else
10+
raise StandardError, 'Provided file_set does not meet interface requirements'
11+
end
12+
end
13+
14+
def lookup_id
15+
@lookup_id ||= versioned_lookup_id
16+
end
17+
18+
# @return [String] a URL that resolves to an image provided by a IIIF image server
19+
def iiif_image_url(base_url: nil, size: nil)
20+
return unless lookup_id
21+
Hyrax.config.iiif_image_url_builder.call(lookup_id, base_url, size || Hyrax.config.iiif_image_size_default)
22+
end
23+
24+
# @return [String] a URL that resolves to an info.json file provided by a IIIF image server
25+
def iiif_info_url(base_url)
26+
return unless lookup_id
27+
Hyrax.config.iiif_info_url_builder.call(lookup_id, base_url)
28+
end
29+
30+
private
31+
def versioned_lookup_id
32+
result = file_set.content_location || file_set.original_file_id
33+
if result.blank?
34+
Rails.logger.warn "original_file_id for #{file_set.id} not found, falling back to Fedora."
35+
# result = Hyrax::VersioningService.versioned_file_id(original_file)
36+
result = versioned_file_id(original_file) if original_file
37+
end
38+
if result.blank?
39+
Rails.logger.warn "original_file for #{file_set.id} not found, versioned_lookup_id failed."
40+
nil
41+
else
42+
result
43+
end
44+
end
45+
46+
# @return [Hydra::PCDM::File, nil]
47+
def original_file
48+
@original_file ||=
49+
case file_set
50+
when FileSet
51+
file_set.original_file
52+
else
53+
begin
54+
FileSet.find(file_set.id).original_file
55+
rescue => error
56+
Rails.logger.error "original_file lookup for #{file_set.id} raised error: #{error.inspect}"
57+
nil
58+
end
59+
end
60+
end
61+
62+
# @todo remove after upgrade to Hyrax 3.x
63+
# cherry-picked from Hyrax 3.x VersioningService
64+
# @param [ActiveFedora::File | Hyrax::FileMetadata] content
65+
def versioned_file_id(file)
66+
@versioned_file_id ||= begin
67+
raise StandardError, 'No original_file available for versioning' if file.nil?
68+
versions = file.versions.all
69+
if versions.present?
70+
ActiveFedora::File.uri_to_id versions.last.uri
71+
else
72+
file.id
73+
end
74+
end
75+
end
76+
end

app/services/iiif_thumbnail_path_service.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ class << self
33
# @return the network path to the thumbnail
44
# @param [FileSet] thumbnail the object that is the thumbnail
55
def thumbnail_path(thumbnail)
6-
return unless thumbnail.original_file
7-
id = thumbnail.content_location || thumbnail.original_file.id
8-
Hyrax.config.iiif_image_url_builder.call(id, nil, '250,')
6+
IIIFFileSetPathService.new(thumbnail).iiif_image_url(size: '250,')
97
# Hyrax::Engine.routes.url_helpers.download_path(thumbnail.id,
108
# file: 'thumbnail')
119
end

config/essi_config.example.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ test:
263263
rails:
264264
secret_key_base: c9dd75fe2cce941807d14e04c09aa1f9ae41b6e1f7ba9d2f33142659acf9491f4a7835aad0c4110bf2fa40f2a1e6f7a62048b5a1e1a32c361c8c16d772e40bf0
265265
cantaloupe:
266-
iiif_server_url: /iiif/2/
266+
iiif_server_url: https://localhost:3000/iiif/2/
267267
browse_everything:
268268
file_system:
269269
:home: <%= Rails.root.join("spec/fixtures") %>

lib/extensions/extensions.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,6 @@ def attribute_will_change!(attr)
188188

189189
# support for rendering an orphan FileSet
190190
Hyrax::FileSetsController.prepend Extensions::Hyrax::FileSetsController::RenderOrphanFileSet
191+
192+
# support for FileSetPresenter#content_location
193+
Hyrax::FileSetPresenter.include Extensions::Hyrax::FileSetPresenter::ContentLocation
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Extensions
2+
module Hyrax
3+
module FileSetPresenter
4+
module ContentLocation
5+
delegate :content_location, to: :solr_document
6+
end
7+
end
8+
end
9+
end

spec/models/collection_branding_info_spec.rb

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
RSpec.describe CollectionBrandingInfo, type: :model do
44
let(:banner) { FactoryBot.build(:collection_branding_banner) }
55
let(:file_set) { FactoryBot.create(:file_set, id: 'file_set_id', uri: 'file_set_uri') }
6-
let(:version) { double(uri: 'version_uri') }
7-
let(:versions) { double(any?: true, all: self, last: version) }
8-
6+
let(:local_file) { File.open(RSpec.configuration.fixture_path + '/world.png') }
7+
let(:local_file_set) { FactoryBot.create(:file_set, content: local_file) }
98

109
describe '#initialize' do
1110
context 'with local_path value provided' do
@@ -101,24 +100,18 @@
101100
banner.send(:image_path=, nil)
102101
end
103102
context 'and unable to generate one' do
104-
before do
105-
allow(banner).to receive(:file_set_versions).and_return([])
106-
end
107103
it 'returns nil' do
108104
expect(banner.file_set_image_path).to be_nil
109105
end
110106
end
111107
context 'but able to generate one' do
112-
before do
113-
allow(banner).to receive(:file_set_versions).and_return(versions)
114-
allow(versions).to receive(:all).and_return(versions)
115-
end
108+
let(:banner) { FactoryBot.build(:collection_branding_banner, file_set_id: local_file_set.id) }
116109
it 'sets the image_path value' do
117110
expect(banner).to receive(:image_path=)
118111
banner.file_set_image_path
119112
end
120113
it 'returns the image_path value' do
121-
expect(banner.file_set_image_path).to match version.uri
114+
expect(banner.file_set_image_path).to match /^http/
122115
end
123116
end
124117
end

0 commit comments

Comments
 (0)