diff --git a/app/jobs/pdf_preview_job.rb b/app/jobs/pdf_preview_job.rb index 8f161d226..1a9a22cb8 100644 --- a/app/jobs/pdf_preview_job.rb +++ b/app/jobs/pdf_preview_job.rb @@ -16,39 +16,9 @@ class PdfPreviewJob < ApplicationJob def perform(asset_id) asset = Asset.find(asset_id) - blob = asset.file.blob - blob.open(tmpdir: tempdir) do |input| - work_dir = File.dirname(input.path) - preview_filename = "#{File.basename(input.path, '.*')}.pdf" - preview_file = File.join(work_dir, preview_filename) - Rails.logger.info "Starting preparing document preview for file #{blob.filename.sanitized}..." - ActiveRecord::Base.transaction do - success = system( - libreoffice_path, '--headless', '--invisible', '--convert-to', 'pdf', '--outdir', work_dir, input.path - ) - unless success && File.file?(preview_file) - raise StandardError, "There was an error generating PDF preview, blob id: #{blob.id}" - end - - ActiveRecord::Base.no_touching do - asset.file_pdf_preview.attach(io: File.open(preview_file), filename: "#{blob.filename.base}.pdf") - asset.update(pdf_preview_processing: false) - end - Rails.logger.info("Finished preparing PDF preview for file #{blob.filename.sanitized}.") - end - ensure - File.delete(preview_file) if File.file?(preview_file) - end - end - - private - - def tempdir - Rails.root.join('tmp') - end - - def libreoffice_path - ENV['LIBREOFFICE_PATH'] || 'soffice' + PdfPreviewService.new(asset.file.blob, asset.file_pdf_preview).generate! + ensure + asset.update(pdf_preview_processing: false) end end diff --git a/app/jobs/reports/docx_preview_job.rb b/app/jobs/reports/docx_preview_job.rb index 5134bc529..9c35c6160 100644 --- a/app/jobs/reports/docx_preview_job.rb +++ b/app/jobs/reports/docx_preview_job.rb @@ -15,39 +15,7 @@ module Reports def perform(report_id) report = Report.find(report_id) - blob = report.docx_file.blob - blob.open(tmpdir: tempdir) do |input| - work_dir = File.dirname(input.path) - preview_filename = "#{File.basename(input.path, '.*')}.pdf" - preview_file = File.join(work_dir, preview_filename) - Rails.logger.info "Starting preparing document preview for file #{blob.filename.sanitized}..." - - ActiveRecord::Base.transaction do - success = system( - libreoffice_path, '--headless', '--invisible', '--convert-to', 'pdf', '--outdir', work_dir, input.path - ) - unless success && File.file?(preview_file) - raise StandardError, "There was an error generating PDF preview, blob id: #{blob.id}" - end - - ActiveRecord::Base.no_touching do - report.docx_preview_file.attach(io: File.open(preview_file), filename: "#{blob.filename.base}.pdf") - end - Rails.logger.info("Finished preparing PDF preview for file #{blob.filename.sanitized}.") - end - ensure - File.delete(preview_file) if File.file?(preview_file) - end - end - - private - - def tempdir - Rails.root.join('tmp') - end - - def libreoffice_path - ENV['LIBREOFFICE_PATH'] || 'soffice' + PdfPreviewService.new(report.docx_file.blob, report.docx_preview_file).generate! end end end diff --git a/app/services/pdf_preview_service.rb b/app/services/pdf_preview_service.rb new file mode 100644 index 000000000..dce368ea2 --- /dev/null +++ b/app/services/pdf_preview_service.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class PdfPreviewService + def initialize(blob, attached) + @blob = blob + @attached = attached + end + + def generate! + preview_file = nil + + @blob.open(tmpdir: tempdir) do |input| + work_dir = File.dirname(input.path) + preview_filename = "#{File.basename(input.path, '.*')}.pdf" + preview_file = File.join(work_dir, preview_filename) + Rails.logger.info "Starting preparing document preview for file #{@blob.filename.sanitized}..." + + ActiveRecord::Base.transaction do + success = system( + 'timeout', + Constants::PREVIEW_TIMEOUT_SECONDS.to_s, + libreoffice_path, + '--headless', + '--invisible', + '--convert-to', + 'pdf', '--outdir', + work_dir, input.path + ) + unless success && File.file?(preview_file) + raise StandardError, "There was an error generating PDF preview, blob id: #{@blob.id}" + end + + ActiveRecord::Base.no_touching do + attached.attach(io: File.open(preview_file), filename: "#{@blob.filename.base}.pdf") + end + Rails.logger.info("Finished preparing PDF preview for file #{@blob.filename.sanitized}.") + end + end + ensure + File.delete(preview_file) if File.file?(preview_file) + end + + private + + def tempdir + Rails.root.join('tmp') + end + + def libreoffice_path + ENV['LIBREOFFICE_PATH'] || 'soffice' + end +end diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb index bceb558de..4ebb75ae5 100644 --- a/config/initializers/constants.rb +++ b/config/initializers/constants.rb @@ -328,6 +328,9 @@ class Constants PREVIEWABLE_FILE_TYPES = TEXT_EXTRACT_FILE_TYPES + # default preview timeout to 15 minutes + PREVIEW_TIMEOUT_SECONDS = ENV['PREVIEW_TIMEOUT_SECONDS'] ? ENV['PREVIEW_TIMEOUT_SECONDS'].to_i : 900 + WHITELISTED_IMAGE_TYPES = [ 'gif', 'jpeg', 'pjpeg', 'png', 'x-png', 'svg+xml', 'bmp', 'tiff', 'jpg' ].freeze diff --git a/lib/active_storage/previewer/libreoffice_previewer.rb b/lib/active_storage/previewer/libreoffice_previewer.rb index 31752df28..334e7a765 100644 --- a/lib/active_storage/previewer/libreoffice_previewer.rb +++ b/lib/active_storage/previewer/libreoffice_previewer.rb @@ -22,7 +22,12 @@ module ActiveStorage begin success = system( - libreoffice_path, '--headless', '--invisible', '--convert-to', 'png', '--outdir', work_dir, input.path + 'timeout', + Constants::PREVIEW_TIMEOUT_SECONDS.to_s, + libreoffice_path, + '--headless', '--invisible', '--convert-to', 'png', '--outdir', + work_dir, + input.path ) unless success && File.file?(preview_file)