make pdf links clickable
This commit is contained in:
@@ -20,6 +20,7 @@ gem 'oj'
|
|||||||
gem 'omniauth-google-oauth2'
|
gem 'omniauth-google-oauth2'
|
||||||
gem 'omniauth-rails_csrf_protection'
|
gem 'omniauth-rails_csrf_protection'
|
||||||
gem 'pagy'
|
gem 'pagy'
|
||||||
|
gem 'pdf-reader'
|
||||||
gem 'pg', require: false
|
gem 'pg', require: false
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'puma'
|
gem 'puma'
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
Ascii85 (1.1.0)
|
||||||
actioncable (7.0.7)
|
actioncable (7.0.7)
|
||||||
actionpack (= 7.0.7)
|
actionpack (= 7.0.7)
|
||||||
activesupport (= 7.0.7)
|
activesupport (= 7.0.7)
|
||||||
@@ -68,6 +69,7 @@ GEM
|
|||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
addressable (2.8.5)
|
addressable (2.8.5)
|
||||||
public_suffix (>= 2.0.2, < 6.0)
|
public_suffix (>= 2.0.2, < 6.0)
|
||||||
|
afm (0.2.2)
|
||||||
annotate (3.2.0)
|
annotate (3.2.0)
|
||||||
activerecord (>= 3.2, < 8.0)
|
activerecord (>= 3.2, < 8.0)
|
||||||
rake (>= 10.4, < 14.0)
|
rake (>= 10.4, < 14.0)
|
||||||
@@ -233,6 +235,7 @@ GEM
|
|||||||
os (>= 0.9, < 2.0)
|
os (>= 0.9, < 2.0)
|
||||||
signet (>= 0.16, < 2.a)
|
signet (>= 0.16, < 2.a)
|
||||||
hashdiff (1.0.1)
|
hashdiff (1.0.1)
|
||||||
|
hashery (2.1.2)
|
||||||
hashie (5.0.0)
|
hashie (5.0.0)
|
||||||
hexapdf (0.33.0)
|
hexapdf (0.33.0)
|
||||||
cmdparse (~> 3.0, >= 3.0.3)
|
cmdparse (~> 3.0, >= 3.0.3)
|
||||||
@@ -335,6 +338,12 @@ GEM
|
|||||||
parser (3.2.2.3)
|
parser (3.2.2.3)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
racc
|
racc
|
||||||
|
pdf-reader (2.11.0)
|
||||||
|
Ascii85 (~> 1.0)
|
||||||
|
afm (~> 0.2.1)
|
||||||
|
hashery (~> 2.0)
|
||||||
|
ruby-rc4
|
||||||
|
ttfunk
|
||||||
pg (1.5.3)
|
pg (1.5.3)
|
||||||
premailer (1.21.0)
|
premailer (1.21.0)
|
||||||
addressable
|
addressable
|
||||||
@@ -461,6 +470,7 @@ GEM
|
|||||||
rubocop-capybara (~> 2.17)
|
rubocop-capybara (~> 2.17)
|
||||||
rubocop-factory_bot (~> 2.22)
|
rubocop-factory_bot (~> 2.22)
|
||||||
ruby-progressbar (1.13.0)
|
ruby-progressbar (1.13.0)
|
||||||
|
ruby-rc4 (0.1.5)
|
||||||
ruby-vips (2.1.4)
|
ruby-vips (2.1.4)
|
||||||
ffi (~> 1.12)
|
ffi (~> 1.12)
|
||||||
ruby2_keywords (0.0.5)
|
ruby2_keywords (0.0.5)
|
||||||
@@ -502,6 +512,7 @@ GEM
|
|||||||
thor (1.2.2)
|
thor (1.2.2)
|
||||||
timeout (0.4.0)
|
timeout (0.4.0)
|
||||||
trailblazer-option (0.1.2)
|
trailblazer-option (0.1.2)
|
||||||
|
ttfunk (1.7.0)
|
||||||
turbo-rails (1.4.0)
|
turbo-rails (1.4.0)
|
||||||
actionpack (>= 6.0.0)
|
actionpack (>= 6.0.0)
|
||||||
activejob (>= 6.0.0)
|
activejob (>= 6.0.0)
|
||||||
@@ -564,6 +575,7 @@ DEPENDENCIES
|
|||||||
omniauth-google-oauth2
|
omniauth-google-oauth2
|
||||||
omniauth-rails_csrf_protection
|
omniauth-rails_csrf_protection
|
||||||
pagy
|
pagy
|
||||||
|
pdf-reader
|
||||||
pg
|
pg
|
||||||
premailer-rails
|
premailer-rails
|
||||||
pry-rails
|
pry-rails
|
||||||
|
|||||||
@@ -7,12 +7,7 @@ module Api
|
|||||||
|
|
||||||
@template = current_account.templates.find(params[:template_id])
|
@template = current_account.templates.find(params[:template_id])
|
||||||
|
|
||||||
documents =
|
documents = Templates::CreateAttachments.call(@template, params)
|
||||||
find_or_create_blobs.map do |blob|
|
|
||||||
document = @template.documents.create!(blob:)
|
|
||||||
|
|
||||||
Templates::ProcessDocument.call(document)
|
|
||||||
end
|
|
||||||
|
|
||||||
schema = documents.map do |doc|
|
schema = documents.map do |doc|
|
||||||
{ attachment_uuid: doc.uuid, name: doc.filename.base }
|
{ attachment_uuid: doc.uuid, name: doc.filename.base }
|
||||||
@@ -27,19 +22,5 @@ module Api
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_or_create_blobs
|
|
||||||
blobs = params[:blobs]&.map do |attrs|
|
|
||||||
ActiveStorage::Blob.find_signed(attrs[:signed_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
blobs || params[:files].map do |file|
|
|
||||||
ActiveStorage::Blob.create_and_upload!(io: file.open,
|
|
||||||
filename: file.original_filename,
|
|
||||||
content_type: file.content_type)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class EsignSettingsController < ApplicationController
|
|||||||
default_pkcs = GenerateCertificate.load_pkcs(cert_data) if cert_data['cert'].present?
|
default_pkcs = GenerateCertificate.load_pkcs(cert_data) if cert_data['cert'].present?
|
||||||
|
|
||||||
custom_pkcs_list = (cert_data['custom'] || []).map do |e|
|
custom_pkcs_list = (cert_data['custom'] || []).map do |e|
|
||||||
{ 'pkcs' => OpenSSL::PKCS12.new(Base64.urlsafe_decode64(e['data']), e['password']),
|
{ 'pkcs' => OpenSSL::PKCS12.new(Base64.urlsafe_decode64(e['data']), e['password'].to_s),
|
||||||
'name' => e['name'],
|
'name' => e['name'],
|
||||||
'status' => e['status'] }
|
'status' => e['status'] }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class SubmissionsController < ApplicationController
|
|||||||
def show
|
def show
|
||||||
@submission =
|
@submission =
|
||||||
Submission.joins(:template).where(template: { account_id: current_account.id })
|
Submission.joins(:template).where(template: { account_id: current_account.id })
|
||||||
.preload(template: { documents_attachments: { preview_images_attachments: :blob } })
|
.preload(:template, template_schema_documents: [:blob, { preview_images_attachments: :blob }])
|
||||||
.find(params[:id])
|
.find(params[:id])
|
||||||
|
|
||||||
render :show, layout: 'plain'
|
render :show, layout: 'plain'
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ class SubmitFormController < ApplicationController
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
@submitter =
|
@submitter =
|
||||||
Submitter.preload(submission: { template: { documents_attachments: { preview_images_attachments: :blob } } })
|
Submitter.preload(submission: [
|
||||||
|
:template, { template_schema_documents: [:blob, { preview_images_attachments: :blob }] }
|
||||||
|
])
|
||||||
.find_by!(slug: params[:slug])
|
.find_by!(slug: params[:slug])
|
||||||
|
|
||||||
return redirect_to submit_form_completed_path(@submitter.slug) if @submitter.completed_at?
|
return redirect_to submit_form_completed_path(@submitter.slug) if @submitter.completed_at?
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ class VerifyPdfSignatureController < ApplicationController
|
|||||||
cert_data = if Docuseal.multitenant?
|
cert_data = if Docuseal.multitenant?
|
||||||
Docuseal::CERTS
|
Docuseal::CERTS
|
||||||
else
|
else
|
||||||
EncryptedConfig.find_by(account:, key: EncryptedConfig::ESIGN_CERTS_KEY)&.value || {}
|
EncryptedConfig.find_by(account: current_account, key: EncryptedConfig::ESIGN_CERTS_KEY)&.value || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
default_pkcs = GenerateCertificate.load_pkcs(cert_data)
|
default_pkcs = GenerateCertificate.load_pkcs(cert_data)
|
||||||
|
|
||||||
custom_certs = (cert_data['custom'] || []).map do |e|
|
custom_certs = cert_data.fetch('custom', []).map do |e|
|
||||||
OpenSSL::PKCS12.new(Base64.urlsafe_decode64(e['data']), e['password'])
|
OpenSSL::PKCS12.new(Base64.urlsafe_decode64(e['data']), e['password'].to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
trusted_certs = [default_pkcs.certificate,
|
trusted_certs = [default_pkcs.certificate,
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ class Submission < ApplicationRecord
|
|||||||
|
|
||||||
attribute :source, :string, default: 'link'
|
attribute :source, :string, default: 'link'
|
||||||
|
|
||||||
|
has_many :template_schema_documents,
|
||||||
|
->(e) { where(uuid: (e.template_schema.presence || e.template.schema).pluck('attachment_uuid')) },
|
||||||
|
through: :template, source: :documents_attachments
|
||||||
|
|
||||||
scope :active, -> { where(deleted_at: nil) }
|
scope :active, -> { where(deleted_at: nil) }
|
||||||
|
|
||||||
enum :source, {
|
enum :source, {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<a href="<%= annot['value'] %>" rel="noopener noreferrer nofollow" target="_blank" class="flex absolute" style="width: <%= annot['w'] * 100 %>%; height: <%= annot['h'] * 100 %>%; left: <%= annot['x'] * 100 %>%; top: <%= annot['y'] * 100 %>%"></a>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<div class="flex md:max-h-[calc(100vh-60px)]">
|
<div class="flex md:max-h-[calc(100vh-60px)]">
|
||||||
<div class="overflow-y-auto overflow-x-hidden hidden lg:block w-52 flex-none pr-3 mt-0.5 pt-0.5">
|
<div class="overflow-y-auto overflow-x-hidden hidden lg:block w-52 flex-none pr-3 mt-0.5 pt-0.5">
|
||||||
<% (@submission.template_schema || @submission.template.schema).each do |item| %>
|
<% (@submission.template_schema || @submission.template.schema).each do |item| %>
|
||||||
<% document = @submission.template.documents.find { |a| item['attachment_uuid'] == a.uuid } %>
|
<% document = @submission.template_schema_documents.find { |a| item['attachment_uuid'] == a.uuid } %>
|
||||||
<a href="#<%= "page-#{document.uuid}-0" %>" onclick="[event.preventDefault(), window[event.target.closest('a').href.split('#')[1]].scrollIntoView({ behavior: 'smooth', block: 'start' })]" class="block cursor-pointer">
|
<a href="#<%= "page-#{document.uuid}-0" %>" onclick="[event.preventDefault(), window[event.target.closest('a').href.split('#')[1]].scrollIntoView({ behavior: 'smooth', block: 'start' })]" class="block cursor-pointer">
|
||||||
<img src="<%= document.preview_images.first.url %>" width="<%= document.preview_images.first.metadata['width'] %>" height="<%= document.preview_images.first.metadata['height'] %>" class="rounded border" loading="lazy">
|
<img src="<%= document.preview_images.first.url %>" width="<%= document.preview_images.first.metadata['width'] %>" height="<%= document.preview_images.first.metadata['height'] %>" class="rounded border" loading="lazy">
|
||||||
<div class="pb-2 pt-1.5 text-center">
|
<div class="pb-2 pt-1.5 text-center">
|
||||||
@@ -39,11 +39,15 @@
|
|||||||
<% values = @submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %>
|
<% values = @submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %>
|
||||||
<% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %>
|
<% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %>
|
||||||
<% (@submission.template_schema || @submission.template.schema).each do |item| %>
|
<% (@submission.template_schema || @submission.template.schema).each do |item| %>
|
||||||
<% document = @submission.template.documents.find { |e| e.uuid == item['attachment_uuid'] } %>
|
<% document = @submission.template_schema_documents.find { |e| e.uuid == item['attachment_uuid'] } %>
|
||||||
|
<% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %>
|
||||||
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
||||||
<div id="<%= "page-#{document.uuid}-#{index}" %>" class="relative">
|
<div id="<%= "page-#{document.uuid}-#{index}" %>" class="relative">
|
||||||
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" class="shadow-md mb-4" height="<%= page.metadata['height'] %>" loading="lazy">
|
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" class="shadow-md mb-4" height="<%= page.metadata['height'] %>" loading="lazy">
|
||||||
<div class="top-0 bottom-0 left-0 right-0 absolute">
|
<div class="top-0 bottom-0 left-0 right-0 absolute">
|
||||||
|
<% document_annots_index[index]&.each do |annot| %>
|
||||||
|
<%= render 'submissions/annotation', annot: %>
|
||||||
|
<% end %>
|
||||||
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
||||||
<% value = values[field['uuid']] %>
|
<% value = values[field['uuid']] %>
|
||||||
<% next if value.blank? %>
|
<% next if value.blank? %>
|
||||||
|
|||||||
@@ -8,11 +8,15 @@
|
|||||||
<%= render 'banner' %>
|
<%= render 'banner' %>
|
||||||
</div>
|
</div>
|
||||||
<% (@submitter.submission.template_schema || @submitter.submission.template.schema).each do |item| %>
|
<% (@submitter.submission.template_schema || @submitter.submission.template.schema).each do |item| %>
|
||||||
<% document = @submitter.submission.template.documents.find { |a| a.uuid == item['attachment_uuid'] } %>
|
<% document = @submitter.submission.template_schema_documents.find { |a| a.uuid == item['attachment_uuid'] } %>
|
||||||
|
<% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %>
|
||||||
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
||||||
<div class="relative my-4 shadow-md">
|
<div class="relative my-4 shadow-md">
|
||||||
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" height="<%= page.metadata['height'] %>" loading="lazy">
|
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" height="<%= page.metadata['height'] %>" loading="lazy">
|
||||||
<div id="page-<%= [document.uuid, index].join('-') %>" class="top-0 bottom-0 left-0 right-0 absolute">
|
<div id="page-<%= [document.uuid, index].join('-') %>" class="top-0 bottom-0 left-0 right-0 absolute">
|
||||||
|
<% document_annots_index[index]&.each do |annot| %>
|
||||||
|
<%= render 'submissions/annotation', annot: %>
|
||||||
|
<% end %>
|
||||||
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
||||||
<% value = values[field['uuid']] %>
|
<% value = values[field['uuid']] %>
|
||||||
<% next if value.blank? %>
|
<% next if value.blank? %>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-1">
|
<div class="flex items-center space-x-1">
|
||||||
<%= svg_icon('certificate', class: 'w-5 h-5 inline') %>
|
<%= svg_icon('certificate', class: 'w-5 h-5 inline') %>
|
||||||
<span><%= signature.signer_name %></span>
|
<span><%= signature.signer_name.force_encoding('UTF-8') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-1">
|
<div class="flex items-center space-x-1">
|
||||||
<%= svg_icon('lock_access', class: 'w-5 h-5 inline') %>
|
<%= svg_icon('lock_access', class: 'w-5 h-5 inline') %>
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ module Accounts
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (default_cert = cert_data['custom']&.find { |e| e['status'] == 'default' })
|
if (default_cert = cert_data['custom']&.find { |e| e['status'] == 'default' })
|
||||||
OpenSSL::PKCS12.new(Base64.urlsafe_decode64(default_cert['data']), default_cert['password'])
|
OpenSSL::PKCS12.new(Base64.urlsafe_decode64(default_cert['data']), default_cert['password'].to_s)
|
||||||
else
|
else
|
||||||
GenerateCertificate.load_pkcs(cert_data)
|
GenerateCertificate.load_pkcs(cert_data)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Templates
|
||||||
|
module BuildAnnotations
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def call(data)
|
||||||
|
pdf = PDF::Reader.new(StringIO.new(data))
|
||||||
|
|
||||||
|
pdf.pages.flat_map.with_index do |page, index|
|
||||||
|
annotations = page.objects.deref!(page.attributes[:Annots]) || []
|
||||||
|
annotations.filter_map do |annot|
|
||||||
|
next if annot[:A].blank? || annot[:A][:URI].blank?
|
||||||
|
next unless annot[:Subtype] == :Link
|
||||||
|
next if !annot[:A][:URI].starts_with?('https://') && !annot[:A][:URI].starts_with?('http://')
|
||||||
|
|
||||||
|
build_external_link_hash(page, annot).merge('page' => index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_external_link_hash(page, annot)
|
||||||
|
left, bottom, right, top = annot[:Rect]
|
||||||
|
|
||||||
|
{
|
||||||
|
'type' => 'external_link',
|
||||||
|
'value' => annot[:A][:URI],
|
||||||
|
'x' => left / page.width,
|
||||||
|
'y' => (page.height - top) / page.height,
|
||||||
|
'w' => (right - left) / page.width,
|
||||||
|
'h' => (top - bottom) / page.height
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Templates
|
||||||
|
module CreateAttachments
|
||||||
|
PDF_CONTENT_TYPE = 'application/pdf'
|
||||||
|
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def call(template, params)
|
||||||
|
find_or_create_blobs(params).map do |blob|
|
||||||
|
document = template.documents.create!(blob:)
|
||||||
|
|
||||||
|
document_data = blob.download
|
||||||
|
|
||||||
|
if blob.content_type == PDF_CONTENT_TYPE && blob.metadata['pdf'].nil?
|
||||||
|
blob.metadata['pdf'] = { 'annotations' => Templates::BuildAnnotations.call(document_data) }
|
||||||
|
end
|
||||||
|
|
||||||
|
blob.save!
|
||||||
|
|
||||||
|
Templates::ProcessDocument.call(document, document_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create_blobs(params)
|
||||||
|
blobs = params[:blobs]&.map do |attrs|
|
||||||
|
ActiveStorage::Blob.find_signed(attrs[:signed_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
blobs || params[:files].map do |file|
|
||||||
|
data = file.read
|
||||||
|
|
||||||
|
if file.content_type == PDF_CONTENT_TYPE
|
||||||
|
metadata = { 'identified' => true, 'analyzed' => true,
|
||||||
|
'pdf' => { 'annotations' => Templates::BuildAnnotations.call(data) } }
|
||||||
|
end
|
||||||
|
|
||||||
|
ActiveStorage::Blob.create_and_upload!(
|
||||||
|
io: StringIO.new(data),
|
||||||
|
filename: file.original_filename,
|
||||||
|
metadata:,
|
||||||
|
content_type: file.content_type
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -12,22 +12,20 @@ module Templates
|
|||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def call(attachment)
|
def call(attachment, data)
|
||||||
if attachment.content_type == PDF_CONTENT_TYPE
|
if attachment.content_type == PDF_CONTENT_TYPE
|
||||||
generate_pdf_preview_images(attachment)
|
generate_pdf_preview_images(attachment, data)
|
||||||
elsif attachment.image?
|
elsif attachment.image?
|
||||||
generate_preview_image(attachment)
|
generate_preview_image(attachment, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
attachment
|
attachment
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_preview_image(attachment)
|
def generate_preview_image(attachment, data)
|
||||||
binary = attachment.download
|
|
||||||
|
|
||||||
ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all
|
ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all
|
||||||
|
|
||||||
image = Vips::Image.new_from_buffer(binary, '')
|
image = Vips::Image.new_from_buffer(data, '')
|
||||||
image = image.autorot.resize(MAX_WIDTH / image.width.to_f)
|
image = image.autorot.resize(MAX_WIDTH / image.width.to_f)
|
||||||
|
|
||||||
io = StringIO.new(image.write_to_buffer(FORMAT, Q: Q, interlace: true))
|
io = StringIO.new(image.write_to_buffer(FORMAT, Q: Q, interlace: true))
|
||||||
@@ -42,14 +40,12 @@ module Templates
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_pdf_preview_images(attachment)
|
def generate_pdf_preview_images(attachment, data)
|
||||||
binary = attachment.download
|
|
||||||
|
|
||||||
ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all
|
ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all
|
||||||
number_of_pages = HexaPDF::Document.new(io: StringIO.new(binary)).pages.size - 1
|
number_of_pages = PDF::Reader.new(StringIO.new(data)).pages.size - 1
|
||||||
|
|
||||||
(0..number_of_pages).each do |page_number|
|
(0..number_of_pages).each do |page_number|
|
||||||
page = Vips::Image.new_from_buffer(binary, '', dpi: DPI, page: page_number)
|
page = Vips::Image.new_from_buffer(data, '', dpi: DPI, page: page_number)
|
||||||
page = page.resize(MAX_WIDTH / page.width.to_f)
|
page = page.resize(MAX_WIDTH / page.width.to_f)
|
||||||
|
|
||||||
io = StringIO.new(page.write_to_buffer(FORMAT, Q: Q, interlace: true))
|
io = StringIO.new(page.write_to_buffer(FORMAT, Q: Q, interlace: true))
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ FactoryBot.define do
|
|||||||
record: template
|
record: template
|
||||||
)
|
)
|
||||||
|
|
||||||
Templates::ProcessDocument.call(attachment)
|
Templates::ProcessDocument.call(attachment, attachment.download)
|
||||||
|
|
||||||
template.schema = [{ attachment_uuid: attachment.uuid, name: 'sample-document' }]
|
template.schema = [{ attachment_uuid: attachment.uuid, name: 'sample-document' }]
|
||||||
template.submitters = [
|
template.submitters = [
|
||||||
|
|||||||
Reference in New Issue
Block a user