From 0c95a098a5e668d6e110df0e82b298db7203025b Mon Sep 17 00:00:00 2001 From: Eric Leroy-Terquem Date: Tue, 11 Jun 2024 16:17:09 +0200 Subject: [PATCH 1/3] feat(gallery): do not create representations in web machines --- app/helpers/gallery_helper.rb | 9 ++++++--- spec/helpers/gallery_helper_spec.rb | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/app/helpers/gallery_helper.rb b/app/helpers/gallery_helper.rb index 1f9ddeeab..89e27842e 100644 --- a/app/helpers/gallery_helper.rb +++ b/app/helpers/gallery_helper.rb @@ -8,19 +8,22 @@ module GalleryHelper end def preview_url_for(attachment) - attachment.preview(resize_to_limit: [400, 400]).processed.url + preview = attachment.preview(resize_to_limit: [400, 400]) + preview.image.attached? ? preview.processed.url : 'pdf-placeholder.png' rescue StandardError 'pdf-placeholder.png' end def variant_url_for(attachment) - attachment.variant(resize_to_limit: [400, 400]).processed.url + variant = attachment.variant(resize_to_limit: [400, 400]) + variant.key.present? ? variant.processed.url : 'apercu-indisponible.png' rescue StandardError 'apercu-indisponible.png' end def blob_url(attachment) - attachment.blob.content_type.in?(RARE_IMAGE_TYPES) ? attachment.variant(resize_to_limit: [2000, 2000]).processed.url : attachment.blob.url + variant = attachment.variant(resize_to_limit: [2000, 2000]) + attachment.blob.content_type.in?(RARE_IMAGE_TYPES) && variant.key.present? ? variant.processed.url : attachment.blob.url rescue StandardError attachment.blob.url end diff --git a/spec/helpers/gallery_helper_spec.rb b/spec/helpers/gallery_helper_spec.rb index 41469798c..22ddabd32 100644 --- a/spec/helpers/gallery_helper_spec.rb +++ b/spec/helpers/gallery_helper_spec.rb @@ -22,13 +22,21 @@ RSpec.describe GalleryHelper, type: :helper do describe ".variant_url_for" do subject { variant_url_for(attachment) } - context "when attachment can be represented with a variant" do + context "when image attachment has a variant" do let(:file) { fixture_file_upload('spec/fixtures/files/logo_test_procedure.png', 'image/png') } - it { expect { subject }.to change { ActiveStorage::VariantRecord.count }.by(1) } + before { attachment.variant(resize_to_limit: [400, 400]).processed } + it { is_expected.not_to eq("apercu-indisponible.png") } end + context "when image attachment has no variant" do + let(:file) { fixture_file_upload('spec/fixtures/files/logo_test_procedure.png', 'image/png') } + + it { expect { subject }.not_to change { ActiveStorage::VariantRecord.count } } + it { is_expected.to eq("apercu-indisponible.png") } + end + context "when attachment cannot be represented with a variant" do let(:file) { fixture_file_upload('spec/fixtures/files/instructeurs-file.csv', 'text/csv') } @@ -40,13 +48,21 @@ RSpec.describe GalleryHelper, type: :helper do describe ".preview_url_for" do subject { preview_url_for(attachment) } - context "when attachment can be represented with a preview" do + context "when pdf attachment has a preview" do let(:file) { fixture_file_upload('spec/fixtures/files/RIB.pdf', 'application/pdf') } - it { expect { subject }.to change { ActiveStorage::VariantRecord.count }.by(1) } + before { attachment.preview(resize_to_limit: [400, 400]).processed } + it { is_expected.not_to eq("pdf-placeholder.png") } end + context "when pdf attachment has no preview" do + let(:file) { fixture_file_upload('spec/fixtures/files/RIB.pdf', 'application/pdf') } + + it { expect { subject }.not_to change { ActiveStorage::VariantRecord.count } } + it { is_expected.to eq("pdf-placeholder.png") } + end + context "when attachment cannot be represented with a preview" do let(:file) { fixture_file_upload('spec/fixtures/files/instructeurs-file.csv', 'text/csv') } From b638b2e45ae88716822fbcb06765aba54b6d3e75 Mon Sep 17 00:00:00 2001 From: Eric Leroy-Terquem Date: Tue, 11 Jun 2024 16:52:14 +0200 Subject: [PATCH 2/3] feat(gallery): gallery in demande page only for instructeurs --- .../shared/champs/piece_justificative/_show.html.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/shared/champs/piece_justificative/_show.html.haml b/app/views/shared/champs/piece_justificative/_show.html.haml index abb301872..12d1bca87 100644 --- a/app/views/shared/champs/piece_justificative/_show.html.haml +++ b/app/views/shared/champs/piece_justificative/_show.html.haml @@ -1,9 +1,5 @@ .fr-downloads-group - - if !feature_enabled?(:gallery_demande) - %ul - - champ.piece_justificative_file.attachments.each do |attachment| - %li= render Attachment::ShowComponent.new(attachment:, new_tab: true) - - else + - if instructeur_signed_in? && feature_enabled?(:gallery_demande) .gallery-items-list - champ.piece_justificative_file.attachments.with_all_variant_records.each do |attachment| .gallery-item @@ -25,3 +21,7 @@ .thumbnail = image_tag('apercu-indisponible.png') = render Attachment::ShowComponent.new(attachment:, new_tab: true, truncate: true) + - else + %ul + - champ.piece_justificative_file.attachments.each do |attachment| + %li= render Attachment::ShowComponent.new(attachment:, new_tab: true) From c94c2f55c8a117d8881b5a980c3dc478522b610a Mon Sep 17 00:00:00 2001 From: Eric Leroy-Terquem Date: Tue, 11 Jun 2024 17:30:09 +0200 Subject: [PATCH 3/3] task(pj): create representations for latest pieces jointes --- ...previews_for_pj_of_latest_dossiers_task.rb | 26 +++++++++ ...variants_for_pj_of_latest_dossiers_task.rb | 29 ++++++++++ ...ews_for_pj_of_latest_dossiers_task_spec.rb | 41 ++++++++++++++ ...nts_for_pj_of_latest_dossiers_task_spec.rb | 53 +++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb create mode 100644 app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb create mode 100644 spec/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task_spec.rb create mode 100644 spec/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task_spec.rb diff --git a/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb b/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb new file mode 100644 index 000000000..09b0c9e29 --- /dev/null +++ b/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Maintenance + class CreatePreviewsForPjOfLatestDossiersTask < MaintenanceTasks::Task + def collection + dossier_ids = Dossier + .state_en_construction_ou_instruction + .where(depose_at: 3.months.ago..) + .pluck(:id) + + champ_ids = Champ + .where(dossier_id: dossier_ids) + .where(type: ["Champs::PieceJustificativeChamp", 'Champs::TitreIdentiteChamp']) + .pluck(:id) + + ActiveStorage::Attachment + .where(record_id: champ_ids) + end + + def process(attachment) + return unless attachment.previewable? + attachment.preview(resize_to_limit: [400, 400]).processed unless attachment.preview(resize_to_limit: [400, 400]).image.attached? + rescue MiniMagick::Error + end + end +end diff --git a/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb b/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb new file mode 100644 index 000000000..22fe5db51 --- /dev/null +++ b/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Maintenance + class CreateVariantsForPjOfLatestDossiersTask < MaintenanceTasks::Task + def collection + dossier_ids = Dossier + .state_en_construction_ou_instruction + .where(depose_at: 3.months.ago..) + .pluck(:id) + + champ_ids = Champ + .where(dossier_id: dossier_ids) + .where(type: ["Champs::PieceJustificativeChamp", 'Champs::TitreIdentiteChamp']) + .pluck(:id) + + ActiveStorage::Attachment + .where(record_id: champ_ids) + end + + def process(attachment) + return unless attachment.variable? + attachment.variant(resize_to_limit: [400, 400]).processed if attachment.variant(resize_to_limit: [400, 400]).key.nil? + if attachment.blob.content_type.in?(RARE_IMAGE_TYPES) && attachment.variant(resize_to_limit: [2000, 2000]).key.nil? + attachment.variant(resize_to_limit: [2000, 2000]).processed + end + rescue MiniMagick::Error + end + end +end diff --git a/spec/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task_spec.rb b/spec/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task_spec.rb new file mode 100644 index 000000000..4dc92d795 --- /dev/null +++ b/spec/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "rails_helper" + +module Maintenance + RSpec.describe CreatePreviewsForPjOfLatestDossiersTask do + describe "#process" do + let(:procedure) { create(:procedure_with_dossiers) } + let(:type_de_champ_pj) { create(:type_de_champ_piece_justificative, stable_id: 3, libelle: 'Justificatif de domicile', procedure:) } + let(:champ_pj) { create(:champ_piece_justificative, type_de_champ: type_de_champ_pj) } + let(:blob_info) do + { + filename: file.original_filename, + byte_size: file.size, + checksum: Digest::SHA256.file(file.path), + content_type: file.content_type, + # we don't want to run virus scanner on this file + metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE } + } + end + let(:blob) do + blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_info) + blob.upload(file) + blob + end + + let(:attachment) { ActiveStorage::Attachment.create(name: "test", blob: blob, record: champ_pj) } + subject(:process) { described_class.process(attachment) } + + context "when pj is a pdf" do + let(:file) { fixture_file_upload('spec/fixtures/files/RIB.pdf', 'application/pdf') } + + it "creates a preview" do + expect(attachment.preview(resize_to_limit: [400, 400]).image.attached?).to be false + subject + expect(attachment.preview(resize_to_limit: [400, 400]).image.attached?).to be true + end + end + end + end +end diff --git a/spec/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task_spec.rb b/spec/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task_spec.rb new file mode 100644 index 000000000..b41b816a8 --- /dev/null +++ b/spec/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "rails_helper" + +module Maintenance + RSpec.describe CreateVariantsForPjOfLatestDossiersTask do + describe "#process" do + let(:procedure) { create(:procedure_with_dossiers) } + let(:type_de_champ_pj) { create(:type_de_champ_piece_justificative, stable_id: 3, libelle: 'Justificatif de domicile', procedure:) } + let(:champ_pj) { create(:champ_piece_justificative, type_de_champ: type_de_champ_pj) } + let(:blob_info) do + { + filename: file.original_filename, + byte_size: file.size, + checksum: Digest::SHA256.file(file.path), + content_type: file.content_type, + # we don't want to run virus scanner on this file + metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE } + } + end + let(:blob) do + blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_info) + blob.upload(file) + blob + end + + let(:attachment) { ActiveStorage::Attachment.create(name: "test", blob: blob, record: champ_pj) } + subject(:process) { described_class.process(attachment) } + + context "when pj is a classical format image" do + let(:file) { fixture_file_upload('spec/fixtures/files/logo_test_procedure.png', 'image/png') } + + it "creates a variant" do + expect(attachment.variant(resize_to_limit: [400, 400]).key).to be_nil + expect { subject }.to change { ActiveStorage::VariantRecord.count }.by(1) + expect(attachment.variant(resize_to_limit: [400, 400]).key).not_to be_nil + expect(attachment.variant(resize_to_limit: [2000, 2000]).key).to be_nil + end + end + + context "when pj is a rare format image" do + let(:file) { fixture_file_upload('spec/fixtures/files/pencil.tiff', 'image/tiff') } + + it "creates a variant" do + expect(attachment.variant(resize_to_limit: [400, 400]).key).to be_nil + expect { subject }.to change { ActiveStorage::VariantRecord.count }.by(2) + expect(attachment.variant(resize_to_limit: [400, 400]).key).not_to be_nil + expect(attachment.variant(resize_to_limit: [2000, 2000]).key).not_to be_nil + end + end + end + end +end