Skip to content

Commit

Permalink
🎁 Adding naive configurability for thumbnail dimensions
Browse files Browse the repository at this point in the history
With this commit, I'm introducing the most barebones and naive
functionality for allowing for configurability by type.  This gets us
unblocked for scientist-softserv/adventist-dl#330; there's certainly
improvements we can make.  But we won't know those until we work through
additional DerivativeRodeo client needs.

Closes: #30

Related to:

- #30
- https://github.com/scientist-softserv/adventist-dl/issues/330
  • Loading branch information
jeremyf committed May 31, 2023
1 parent e80e11e commit eacd442
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
44 changes: 42 additions & 2 deletions lib/derivative_rodeo/generators/thumbnail_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,33 @@ module Generators
# This generator is responsible for converting a given binary into a thumbnail. As of
# <2023-05-22 Mon>, we're needing to generate thumbnails for PDFs and images.
class ThumbnailGenerator < BaseGenerator
##
# @!group Class Attributes

##
# We want to mirror the same file "last" extension as described in Hyrax.
#
# @see https://github.com/samvera/hyrax/blob/426575a9065a5dd3b30f458f5589a0a705ad7be2/app/services/hyrax/file_set_derivatives_service.rb
self.output_extension = 'thumbnail.jpeg'

##
# @!attribute dimensions_by_type
#
# @return [Hash<Symbol,String>] the "types" (as categorized by
# Hyrax::FileSetDerivativeService). These aren't mime-types per se but a conceptual
# distillation of that.
#
# @see https://github.com/samvera/hyrax/blob/815e0abaacf9f331a5640c5d6129661d01eadf75/app/services/hyrax/file_set_derivatives_service.rb
class_attribute :dimensions_by_type, default: { pdf: "338x493" }

##
# @!attribute dimensions_fallback
#
# @return [String] when there's no match for {.dimensions_by_type} use this value.
class_attribute :dimensions_fallback, default: "200x150>"
# @!endgroup Class Attributes
##

##
# @param output_location [StorageLocations::BaseLocation]
# @param input_tmp_file_path [String] the location of the file that we can use for processing.
Expand All @@ -23,15 +44,34 @@ def build_step(output_location:, input_tmp_file_path:, **)
end
end

##
# @param filename [String]
# @return [String]
#
# @see .dimensions_by_type
# @see .dimensions_fallback
#
# @note TODO: This is a very quick and dirty and assumptive type detector. For the 2023-05-31
# use case it is likely adequate (e.g. if it ends in .pdf we'll have a configured
# match). In other words, we'd love someone else to be sniffing out mime-types rather
# than doing it here.
def self.dimensions_for(filename:)
type = filename.split(".")&.last&.to_sym
dimensions_by_type.fetch(type, dimensions_fallback)
end

# Want to expose the dimensions_for as an instance method
delegate :dimensions_for, to: :class

##
# Convert the file found at :path_to_input into a thumbnail, writing it to the
# :path_for_thumbnail_output
#
# @param path_of_file_to_create_thumbnail_from [String]
# @param path_for_thumbnail_output [String]
def thumbnify(path_of_file_to_create_thumbnail_from:, path_for_thumbnail_output:)
# @todo the dimensions might not be always 200x150, figure out a way to make it dynamic
`convert #{path_of_file_to_create_thumbnail_from} -thumbnail '200x150>' -flatten #{path_for_thumbnail_output}`
dimensions = dimensions_for(filename: path_of_file_to_create_thumbnail_from)
`convert #{path_of_file_to_create_thumbnail_from} -thumbnail '#{dimensions}' -flatten #{path_for_thumbnail_output}`
end
end
end
Expand Down
30 changes: 30 additions & 0 deletions spec/derivative_rodeo/generators/thumbnail_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,36 @@
it { is_expected.to eq("thumbnail.jpeg") }
end

context '.dimensions_by_type' do
subject { described_class.dimensions_by_type }
it { is_expected.to be_a(Hash) }
end

context '.dimensions_fallback' do
subject { described_class.dimensions_fallback }
it { is_expected.to eq("200x150>") }
it { is_expected.to be_a String }
end

describe '.dimensions_for' do
subject { described_class.dimensions_for(filename: filename) }

context "given a file ending in '.pdf'" do
let(:filename) { "really-cool.pdf" }
it { is_expected.to eq described_class.dimensions_by_type.fetch(:pdf) }
end

context "given a file without an extension" do
let(:filename) { "aint-no-extension-here" }
it { is_expected.to eq described_class.dimensions_fallback }
end

context "given a file ending in '.tiff'" do
let(:filename) { "muppet-man.tiff" }
it { is_expected.to eq described_class.dimensions_fallback }
end
end

describe "#generated_files" do
context 'for a PDF' do
it 'creates a thumbnail.jpeg file' do
Expand Down

0 comments on commit eacd442

Please sign in to comment.