Add pdf preview for docx reports [SCI-5601]

This commit is contained in:
aignatov-bio 2021-05-25 15:14:50 +02:00
parent e675e4004e
commit 2be59bf8b2
7 changed files with 86 additions and 5 deletions

View file

@ -206,7 +206,7 @@ class ReportsController < ApplicationController
format.json do
@report.docx_processing!
log_activity(:generate_docx_report)
Reports::DocxJob.perform_later(@report, current_user, root_url)
Reports::DocxJob.perform_later(@report.id, current_user, root_url)
render json: {
message: I18n.t('projects.reports.index.generation.accepted_message')
}

View file

@ -51,6 +51,8 @@ module Reports
report_link: "<a href='#{report_path}'>#{sanitize_input(report.name)}</a>",
team_name: sanitize_input(report.team.name))
)
Reports::DocxPreviewJob.perform_later(report.id)
notification.create_user_notification(user)
ensure
file.close

View file

@ -0,0 +1,56 @@
# frozen_string_literal: true
# Provides asynchronous generation of image previews for ActiveStorage::Blob records.
module Reports
class DocxPreviewJob < ApplicationJob
queue_as :reports
discard_on StandardError do |job, error|
report = Report.find_by(id: job.arguments.first)
ActiveRecord::Base.no_touching do
report&.update(docx_preview_processing: false)
end
Rails.logger.error("Couldn't generate PDF preview for DOCX Report with id: #{job.arguments.first}. Error:\n #{error}")
end
discard_on ActiveRecord::RecordNotFound
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")
report.update(docx_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'
end
end
end

View file

@ -11,6 +11,7 @@ class Report < ApplicationRecord
# ActiveStorage configuration
has_one_attached :pdf_file
has_one_attached :docx_file
has_one_attached :docx_preview_file
auto_strip_attributes :name, :description, nullify: false
validates :name,
@ -96,6 +97,16 @@ class Report < ApplicationRecord
report_elements.order(:position).select { |el| el.parent.blank? }
end
def docx_preview_ready?
return false if docx_preview_processing
return true if docx_preview_file.attached?
Reports::DocxPreviewJob.perform_later(id)
ActiveRecord::Base.no_touching { update(docx_preview_processing: true) }
false
end
# Clean report elements from report
# the function runs before the report is edit
def cleanup_report

View file

@ -11,6 +11,8 @@
<div class="file-preview-container">
<% if report_type == 'pdf' %>
<%= render partial: 'shared/pdf_viewer.html.erb', locals: { asset: report.pdf_file, report_document: true } %>
<% elsif report_type == 'docx' && report.docx_preview_ready? %>
<%= render partial: 'shared/pdf_viewer.html.erb', locals: { asset: report.docx_preview_file, report_document: true } %>
<% else %>
<div>
<i class="fas fa-10x fa-file-word"></i>

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddDocxPreviewProcessingToReports < ActiveRecord::Migration[6.1]
def change
add_column :reports, :docx_preview_processing, :boolean, default: false, null: false
end
end

View file

@ -1307,9 +1307,10 @@ CREATE TABLE public.reports (
updated_at timestamp without time zone NOT NULL,
last_modified_by_id bigint,
team_id bigint,
pdf_file_status integer DEFAULT 0,
docx_file_status integer DEFAULT 0,
settings jsonb DEFAULT '{}'::jsonb NOT NULL
pdf_file_status integer,
docx_file_status integer,
settings jsonb DEFAULT '{}'::jsonb NOT NULL,
docx_preview_processing boolean DEFAULT false NOT NULL
);
@ -7234,6 +7235,8 @@ INSERT INTO "schema_migrations" (version) VALUES
('20210312185911'),
('20210325152257'),
('20210407143303'),
('20210506125657');
('20210410100006'),
('20210506125657'),
('20210525143303');