diff options
author | Terence Lee <hone02@gmail.com> | 2018-02-05 19:33:35 -0600 |
---|---|---|
committer | George Claghorn <george@basecamp.com> | 2018-03-06 13:33:33 -0500 |
commit | 0b717c20458d12191f479fc693dd1ca1eb11c050 (patch) | |
tree | 6bcd9dd08f792a35235a96f392a79fd2ac0cdbc2 /activestorage/lib | |
parent | 060ed201e444785135ce9a4baea069079257295e (diff) | |
download | rails-0b717c20458d12191f479fc693dd1ca1eb11c050.tar.gz rails-0b717c20458d12191f479fc693dd1ca1eb11c050.tar.bz2 rails-0b717c20458d12191f479fc693dd1ca1eb11c050.zip |
Provide an alternative PDF previewer based on Poppler
mutool is licensed under the Affero GPL, which has strict distribution requirements.
Poppler is licensed under the more liberal GPL, making it a good alternative for those who can't use mutool.
Diffstat (limited to 'activestorage/lib')
4 files changed, 74 insertions, 28 deletions
diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb index 1e223f9f17..1385e2aa84 100644 --- a/activestorage/lib/active_storage/engine.rb +++ b/activestorage/lib/active_storage/engine.rb @@ -3,7 +3,8 @@ require "rails" require "active_storage" -require "active_storage/previewer/pdf_previewer" +require "active_storage/previewer/poppler_pdf_previewer" +require "active_storage/previewer/mupdf_previewer" require "active_storage/previewer/video_previewer" require "active_storage/analyzer/image_analyzer" @@ -14,7 +15,7 @@ module ActiveStorage isolate_namespace ActiveStorage config.active_storage = ActiveSupport::OrderedOptions.new - config.active_storage.previewers = [ ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ] + config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ] config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer ] config.active_storage.paths = ActiveSupport::OrderedOptions.new diff --git a/activestorage/lib/active_storage/previewer/mupdf_previewer.rb b/activestorage/lib/active_storage/previewer/mupdf_previewer.rb new file mode 100644 index 0000000000..ae02a4889d --- /dev/null +++ b/activestorage/lib/active_storage/previewer/mupdf_previewer.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module ActiveStorage + class Previewer::MuPDFPreviewer < Previewer + class << self + def accept?(blob) + blob.content_type == "application/pdf" && mutool_exists? + end + + def mutool_path + ActiveStorage.paths[:mutool] || "mutool" + end + + def mutool_exists? + return @mutool_exists unless @mutool_exists.nil? + + system mutool_path, out: File::NULL, err: File::NULL + + @mutool_exists = $?.exitstatus == 1 + end + end + + def preview + download_blob_to_tempfile do |input| + draw_first_page_from input do |output| + yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png" + end + end + end + + private + def draw_first_page_from(file, &block) + draw self.class.mutool_path, "draw", "-F", "png", "-o", "-", file.path, "1", &block + end + end +end diff --git a/activestorage/lib/active_storage/previewer/pdf_previewer.rb b/activestorage/lib/active_storage/previewer/pdf_previewer.rb deleted file mode 100644 index 426ff51eb1..0000000000 --- a/activestorage/lib/active_storage/previewer/pdf_previewer.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module ActiveStorage - class Previewer::PDFPreviewer < Previewer - def self.accept?(blob) - blob.content_type == "application/pdf" - end - - def preview - download_blob_to_tempfile do |input| - draw_first_page_from input do |output| - yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png" - end - end - end - - private - def draw_first_page_from(file, &block) - draw mutool_path, "draw", "-F", "png", "-o", "-", file.path, "1", &block - end - - def mutool_path - ActiveStorage.paths[:mutool] || "mutool" - end - end -end diff --git a/activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb b/activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb new file mode 100644 index 0000000000..2a787362cf --- /dev/null +++ b/activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module ActiveStorage + class Previewer::PopplerPDFPreviewer < Previewer + class << self + def accept?(blob) + blob.content_type == "application/pdf" && pdftoppm_exists? + end + + def pdftoppm_path + ActiveStorage.paths[:pdftoppm] || "pdftoppm" + end + + def pdftoppm_exists? + return @pdftoppm_exists unless @pdftoppm_exists.nil? + + @pdftoppm_exists = system(pdftoppm_path, "-v", out: File::NULL, err: File::NULL) + end + end + + def preview + download_blob_to_tempfile do |input| + draw_first_page_from input do |output| + yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png" + end + end + end + + private + def draw_first_page_from(file, &block) + # use 72 dpi to match thumbnail dimesions of the PDF + draw self.class.pdftoppm_path, "-singlefile", "-r", "72", "-png", file.path, &block + end + end +end |