diff --git a/app/controllers/preview_document_page_controller.rb b/app/controllers/preview_document_page_controller.rb deleted file mode 100644 index 5e59e74a2..000000000 --- a/app/controllers/preview_document_page_controller.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -class PreviewDocumentPageController < ActionController::API - include ActiveStorage::SetCurrent - - FORMAT = Templates::ProcessDocument::FORMAT - - def show - attachment_uuid = ApplicationRecord.signed_id_verifier.verified(params[:signed_uuid], purpose: :attachment) - - attachment = ActiveStorage::Attachment.find_by(uuid: attachment_uuid) if attachment_uuid - - return head :not_found unless attachment - - @template = attachment.record - - preview_image = attachment.preview_images.joins(:blob) - .find_by(blob: { filename: ["#{params[:id]}.png", "#{params[:id]}.jpg"] }) - - return redirect_to preview_image.url, allow_other_host: true if preview_image - - file_path = - if attachment.service.name == :disk - ActiveStorage::Blob.service.path_for(attachment.key) - else - find_or_create_document_tempfile_path(attachment) - end - - preview_image = - Templates::ProcessDocument.generate_pdf_preview_from_file(attachment, file_path, params[:id].to_i) - - redirect_to preview_image.url, allow_other_host: true - end - - def find_or_create_document_tempfile_path(attachment) - file_path = "#{Dir.tmpdir}/#{attachment.uuid}" - - File.open(file_path, File::RDWR | File::CREAT, 0o644) do |f| - f.flock(File::LOCK_EX) - - # rubocop:disable Style/ZeroLengthPredicate - if f.size.zero? - f.binmode - - f.write(attachment.download) - end - # rubocop:enable Style/ZeroLengthPredicate - end - - file_path - end -end diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index f576ffc84..17e6a248b 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -203,7 +203,6 @@ :draw-field="drawField" :draw-field-type="drawFieldType" :editable="editable" - :base-url="baseUrl" @draw="[onDraw($event), withSelectedFieldType ? '' : drawFieldType = '', showDrawField = false]" @drop-field="onDropfield" @remove-area="removeArea" diff --git a/app/javascript/template_builder/document.vue b/app/javascript/template_builder/document.vue index 2c7592c75..099c95122 100644 --- a/app/javascript/template_builder/document.vue +++ b/app/javascript/template_builder/document.vue @@ -95,11 +95,6 @@ export default { required: false, default: null }, - baseUrl: { - type: String, - required: false, - default: '' - }, isDrag: { type: Boolean, required: false, @@ -113,26 +108,13 @@ export default { } }, computed: { - basePreviewUrl () { - if (this.baseUrl) { - return new URL(this.baseUrl).origin - } else { - return '' - } - }, numberOfPages () { return this.document.metadata?.pdf?.number_of_pages || this.document.preview_images.length }, sortedPreviewImages () { - const lazyloadMetadata = this.document.preview_images[this.document.preview_images.length - 1].metadata - - return [...Array(this.numberOfPages).keys()].map((i) => { - return this.previewImagesIndex[i] || { - metadata: lazyloadMetadata, - id: Math.random().toString(), - url: this.basePreviewUrl + `/preview/${this.document.signed_uuid || this.document.uuid}/${i}.jpg` - } - }) + return [...Array(this.numberOfPages).keys()] + .map((i) => this.previewImagesIndex[i] ? { ...this.previewImagesIndex[i], _pageIndex: i } : null) + .filter(Boolean) }, previewImagesIndex () { return this.document.preview_images.reduce((acc, e) => { diff --git a/app/javascript/template_builder/dropzone.vue b/app/javascript/template_builder/dropzone.vue index 2485bd23a..453491fb8 100644 --- a/app/javascript/template_builder/dropzone.vue +++ b/app/javascript/template_builder/dropzone.vue @@ -35,11 +35,17 @@ {{ message }}
{{ t('click_to_upload') }} {{ t('or_drag_and_drop_files') }}
+
+ {{ t('larger_pdfs_may_take_a_while_to_process') }} +
<% submitters_index = @submission.submitters.index_by(&:uuid) %> <% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %> - <% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %> <% schema.each do |item| %> <% document = @submission.schema_documents.find { |e| e.uuid == item['attachment_uuid'] } %> <% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %> <% preview_images_index = document.preview_images.loaded? ? document.preview_images.index_by { |e| e.filename.base.to_i } : {} %> - <% lazyload_metadata = document.preview_images.first.metadata %> <% (document.metadata.dig('pdf', 'number_of_pages') || (document.preview_images.loaded? ? preview_images_index.size : document.preview_images.size)).times do |index| %> - <% page = preview_images_index[index] || page_blob_struct.new(metadata: lazyload_metadata, url: preview_document_page_path(document.signed_uuid, "#{index}.jpg")) %> + <% page = preview_images_index[index] %> + <% next unless page %>
" class="relative"> - +
<% document_annots_index[index]&.each do |annot| %> <%= render 'submissions/annotation', annot: %> diff --git a/app/views/submit_form/show.html.erb b/app/views/submit_form/show.html.erb index 22cc19f18..f577b55e9 100644 --- a/app/views/submit_form/show.html.erb +++ b/app/views/submit_form/show.html.erb @@ -6,7 +6,6 @@ <% values = merge_prefill_values(submitter_values, @prefill_values || {}, template_fields) %> <% submitters_index = @submitter.submission.submitters.index_by(&:uuid) %> -<% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %> <% schema = Submissions.filtered_conditions_schema(@submitter.submission, values:, include_submitter_uuid: @submitter.uuid) %>
@@ -20,11 +19,11 @@
<% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %> <% preview_images_index = document.preview_images.loaded? ? document.preview_images.index_by { |e| e.filename.base.to_i } : {} %> - <% lazyload_metadata = document.preview_images.last&.metadata || {} %> <% (document.metadata.dig('pdf', 'number_of_pages') || (document.preview_images.loaded? ? preview_images_index.size : document.preview_images.size)).times do |index| %> - <% page = preview_images_index[index] || page_blob_struct.new(metadata: lazyload_metadata, url: preview_document_page_path(document.signed_uuid, "#{index}.jpg")) %> + <% page = preview_images_index[index] %> + <% next unless page %>
- +
<% if annots = document_annots_index[index] %> <%= render 'submit_form/annotations', annots: %> diff --git a/config/routes.rb b/config/routes.rb index 2ad783d7c..8f8099acf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -140,7 +140,6 @@ resources :recipients, only: %i[create], controller: 'templates_recipients' resources :submissions_export, only: %i[index new] end - resources :preview_document_page, only: %i[show], path: '/preview/:signed_uuid' resource :blobs_proxy, only: %i[show], path: '/file/:signed_uuid/*filename', controller: 'api/active_storage_blobs_proxy' resource :blobs_proxy, only: %i[show], path: '/blobs_proxy/:signed_uuid/*filename', diff --git a/lib/submissions.rb b/lib/submissions.rb index 1ffba7956..c94aa280e 100644 --- a/lib/submissions.rb +++ b/lib/submissions.rb @@ -3,8 +3,6 @@ module Submissions DEFAULT_SUBMITTERS_ORDER = 'single_sided' - PRELOAD_ALL_PAGES_AMOUNT = 200 - module_function def search(current_user, submissions, keyword, search_values: false, search_template: false) @@ -79,19 +77,14 @@ def preload_with_pages(submission) ActiveRecord::Associations::Preloader.new( records: [submission], associations: [ - submission.template_id? ? { template_schema_documents: :blob } : { documents_attachments: :blob } + submission.template_id? ? :template_schema_documents : :documents_attachments ] ).call - total_pages = - submission.schema_documents.sum { |e| e.metadata.dig('pdf', 'number_of_pages').to_i } - - if total_pages < PRELOAD_ALL_PAGES_AMOUNT - ActiveRecord::Associations::Preloader.new( - records: submission.schema_documents, - associations: [:blob, { preview_images_attachments: :blob }] - ).call - end + ActiveRecord::Associations::Preloader.new( + records: submission.schema_documents, + associations: [{ preview_images_attachments: :blob }] + ).call submission end diff --git a/lib/submitters.rb b/lib/submitters.rb index d31386a78..9c4dafc88 100644 --- a/lib/submitters.rb +++ b/lib/submitters.rb @@ -2,7 +2,6 @@ module Submitters TRUE_VALUES = ['1', 'true', true].freeze - PRELOAD_ALL_PAGES_AMOUNT = 200 FIELD_NAME_WEIGHTS = { 'email' => 'A', diff --git a/lib/templates/process_document.rb b/lib/templates/process_document.rb index 26ccd9a9d..92988e991 100644 --- a/lib/templates/process_document.rb +++ b/lib/templates/process_document.rb @@ -12,13 +12,11 @@ module ProcessDocument Q = 95 JPEG_Q = ENV.fetch('PAGE_QUALITY', '35').to_i MAX_WIDTH = 1400 - MAX_NUMBER_OF_PAGES_PROCESSED = 15 MAX_FLATTEN_FILE_SIZE = 20.megabytes - GENERATE_PREVIEW_SIZE_LIMIT = 50.megabytes module_function - def call(attachment, data, extract_fields: false, max_pages: MAX_NUMBER_OF_PAGES_PROCESSED) + def call(attachment, data, extract_fields: false) if attachment.content_type == PDF_CONTENT_TYPE if extract_fields && data.size < MAX_FLATTEN_FILE_SIZE pdf = HexaPDF::Document.new(io: StringIO.new(data)) @@ -26,7 +24,7 @@ def call(attachment, data, extract_fields: false, max_pages: MAX_NUMBER_OF_PAGES fields = Templates::FindAcroFields.call(pdf, attachment, data) end - generate_pdf_preview_images(attachment, data, pdf, max_pages:) + generate_pdf_preview_images(attachment, data, pdf) attachment.metadata['pdf']['fields'] = fields if fields elsif attachment.image? @@ -81,7 +79,7 @@ def generate_preview_image(attachment, data) ) end - def generate_pdf_preview_images(attachment, data, pdf = nil, max_pages: MAX_NUMBER_OF_PAGES_PROCESSED) + def generate_pdf_preview_images(attachment, data, pdf = nil) ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all pdf ||= HexaPDF::Document.new(io: StringIO.new(data)) @@ -96,9 +94,7 @@ def generate_pdf_preview_images(attachment, data, pdf = nil, max_pages: MAX_NUMB attachment.save! end - max_pages_to_process = data.size < GENERATE_PREVIEW_SIZE_LIMIT ? max_pages : 1 - - generate_document_preview_images(attachment, data, (0..[number_of_pages - 1, max_pages_to_process].min)) + generate_document_preview_images(attachment, data, (0..number_of_pages - 1)) end def generate_document_preview_images(attachment, data, range, concurrency: CONCURRENCY) @@ -201,20 +197,5 @@ def normalize_attachment_fields(template, attachments = template.documents) end end - def generate_pdf_preview_from_file(attachment, file_path, page_number) - doc = Pdfium::Document.open_file(file_path) - - blob = build_and_upload_blob(doc, page_number, '.jpg') - - ApplicationRecord.no_touching do - ActiveStorage::Attachment.create!( - blob: blob, - name: ATTACHMENT_NAME, - record: attachment - ) - end - ensure - doc&.close - end end end diff --git a/spec/lib/templates/process_document_spec.rb b/spec/lib/templates/process_document_spec.rb deleted file mode 100644 index cd7bb4996..000000000 --- a/spec/lib/templates/process_document_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -describe Templates::ProcessDocument do - describe '.generate_pdf_preview_from_file' do - let(:account) { create(:account) } - let(:user) { create(:user, account:) } - let(:template) { create(:template, account:, author: user, attachment_count: 0) } - let(:attachment) do - blob = ActiveStorage::Blob.create_and_upload!( - io: Rails.root.join('spec/fixtures/sample-document.pdf').open, - filename: 'sample-document.pdf', - content_type: 'application/pdf' - ) - ActiveStorage::Attachment.create!(blob: blob, name: :documents, record: template) - end - let(:file_path) { ActiveStorage::Blob.service.path_for(attachment.key) } - - it 'saves the preview blob under a filename the PreviewDocumentPageController cache lookup matches' do - described_class.generate_pdf_preview_from_file(attachment, file_path, 0) - - cached = attachment.preview_images.joins(:blob) - .find_by(blob: { filename: ['0.png', '0.jpg'] }) - - expect(cached).not_to be_nil - end - end -end