mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-27 01:05:21 +08:00
Add pdf preview for docx reports [SCI-5601]
This commit is contained in:
parent
e675e4004e
commit
2be59bf8b2
7 changed files with 86 additions and 5 deletions
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
56
app/jobs/reports/docx_preview_job.rb
Normal file
56
app/jobs/reports/docx_preview_job.rb
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
|
@ -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');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue