aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage/lib/active_storage/previewer
diff options
context:
space:
mode:
authorTerence Lee <hone02@gmail.com>2018-02-05 19:33:35 -0600
committerGeorge Claghorn <george@basecamp.com>2018-03-06 13:33:33 -0500
commit0b717c20458d12191f479fc693dd1ca1eb11c050 (patch)
tree6bcd9dd08f792a35235a96f392a79fd2ac0cdbc2 /activestorage/lib/active_storage/previewer
parent060ed201e444785135ce9a4baea069079257295e (diff)
downloadrails-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/active_storage/previewer')
-rw-r--r--activestorage/lib/active_storage/previewer/mupdf_previewer.rb36
-rw-r--r--activestorage/lib/active_storage/previewer/pdf_previewer.rb26
-rw-r--r--activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb35
3 files changed, 71 insertions, 26 deletions
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