Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎁 Adding naive configurability for thumbnail dimensions #41

Merged
merged 1 commit into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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