Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tech(pdf): replace wkhtmltopdf (no longer maintained) with grover #2619

Open
wants to merge 65 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
3bea6fe
tech(pdf): replace wkhtmltopdf (no longer maintained) with grover
Holist Feb 4, 2025
38e763b
fix eslint angry
Holist Feb 4, 2025
b425d5b
fix ci
Holist Feb 4, 2025
9d155e1
fixing and finalize
Holist Feb 4, 2025
dccb2b6
adapt test helper for Grover
Holist Feb 4, 2025
8722729
rollback on ci changes
Holist Feb 4, 2025
6843947
fixing CI
Holist Feb 4, 2025
d6a4c5e
fixing CI
Holist Feb 4, 2025
222ca7e
fixing direction names
Holist Feb 4, 2025
d5a4f15
merging staging
Holist Feb 4, 2025
1747ca8
installing Chrome in CI
Holist Feb 4, 2025
8bcaedf
Merge branch 'staging' into replace_wkhtmltopdf
Holist Feb 4, 2025
43dca32
fix css mistake
Holist Feb 6, 2025
3f56738
update pupeteer
Holist Feb 6, 2025
dac889f
fix new rules
Holist Feb 6, 2025
aeae175
apply review suggestions
Holist Feb 14, 2025
66db684
merging staging
Holist Feb 14, 2025
b6c0b8a
fixing fragment
Holist Feb 14, 2025
3e6c90c
testing without chrome install
Holist Feb 14, 2025
3700532
fix linter
Holist Feb 14, 2025
cc13fe7
adapt css alignment
Holist Feb 14, 2025
ea32b0f
qrcode a lil bigger
Holist Feb 14, 2025
af56f9d
comment
Holist Feb 18, 2025
472e804
Merge branch 'staging' into replace_wkhtmltopdf
Holist Feb 18, 2025
ab1150c
fix ci tests
Holist Feb 18, 2025
9262090
Merge branch 'replace_wkhtmltopdf' of github.com:betagouv/rdv-inserti…
Holist Feb 18, 2025
73095a1
fix ci tests
Holist Feb 18, 2025
959374b
fix ci tests
Holist Feb 18, 2025
79acd11
fix ci tests
Holist Feb 18, 2025
5bac0a2
fix ci tests
Holist Feb 18, 2025
f49aed9
fix ci tests
Holist Feb 18, 2025
4029760
fix ci tests
Holist Feb 18, 2025
1516d34
rollback on ci changes
Holist Feb 18, 2025
f05ed88
test CI
Holist Feb 19, 2025
5c0aa4c
test CI again
Holist Feb 19, 2025
41bd459
scalingo config for puppeter
Holist Feb 19, 2025
1bba223
install Chrome in package.json script
Holist Feb 19, 2025
3b3e324
Merge branch 'staging' into replace_wkhtmltopdf
Holist Feb 19, 2025
fa1534e
trying with specified path
Holist Feb 19, 2025
3bd03f6
remove node_modules from slugignore
Holist Feb 20, 2025
326a046
config file for puppeteer
Holist Feb 20, 2025
ba00e9c
trying to make this work
Holist Feb 20, 2025
1fda48a
install chrome in aptfile
Holist Feb 20, 2025
7ac8110
test ignoring node_modules/puppeteer
Holist Feb 20, 2025
a2371db
test exception in slugignore2
Holist Feb 20, 2025
623325a
test exception in slugignore again
Holist Feb 20, 2025
745479f
update puppeteer and rollback on slugignore file
Holist Feb 20, 2025
1ba124b
remove husky
Holist Feb 20, 2025
e8711e8
rollback on changes and remove slugignore
Holist Feb 21, 2025
ab303b4
fix buildpack
Holist Feb 21, 2025
c854c97
fix buildpack
Holist Feb 21, 2025
c07d8fb
fix buildpack
Holist Feb 21, 2025
26c2c5a
Updated Yarn lockfile
Holist Feb 21, 2025
6a9bf06
fix buildpack
Holist Feb 21, 2025
ab2e1ca
fix buildpack
Holist Feb 21, 2025
96a69ef
rollback on slugignore
Holist Feb 21, 2025
5dbd724
rollback on slugignore
Holist Feb 21, 2025
b7edd44
slugignore
Holist Feb 21, 2025
f698755
specific folder for puppeteer module
Holist Feb 21, 2025
4ffdee9
remove node_modules from slugignore
Holist Feb 21, 2025
efb4fcf
try again
Holist Feb 21, 2025
38f4d88
without apt
Holist Feb 21, 2025
fc245cd
working config on scalingo
Holist Feb 21, 2025
aa552eb
remove useless folder in gitignore
Holist Feb 21, 2025
04293b6
use external puppeteer service, remove grover
Holist Mar 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"no-nested-ternary": "off",
"no-use-before-define": "off",
"react/jsx-props-no-spreading": "off",
"jsx-a11y/no-autofocus": "off"
"jsx-a11y/no-autofocus": "off",
"react/jsx-no-useless-fragment": "off",
"react/function-component-definition": "off"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

il s'agit de nouvelles règles introduites par la mise à jour de "eslint-config-airbnb" qui était nécessaire pour l'installation de "puppeteer". Plutôt que de fix les erreurs sur du code react qui va bientôt disparaitre j'ai ajouté ces règles en exception.

}
}
11 changes: 8 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on: push
jobs:
linters:
name: Linters
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
Expand All @@ -24,7 +24,7 @@ jobs:
run: yarn lint
test_unit:
name: Unit Tests
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13.2
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:

test_features:
name: Feature Tests
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
Expand All @@ -114,11 +114,16 @@ jobs:
- 6379:6379
options: --entrypoint redis-server
steps:
- name: Disable AppArmor
# https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
- name: Installing Chrome for Puppeteer test
run: npx puppeteer browsers install chrome
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

est-ce que du coup la CI fail si on enlève cette instruction ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tout à fait (uniquement les features tests de Grover), avec cette erreur :

      Grover::JavaScript::Error:
        Could not find Chrome (ver. 133.0.6943.53). This can occur if either
         1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome`) or
         2. your cache path is incorrectly configured (which is: /home/runner/.cache/puppeteer).
        For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ça vaut peut-être le coup dans ce cas de rajouter un commentaire pour dire qu'on rajouter pupeteer pour les pdf (via grover)

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
Expand Down
5 changes: 2 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ gem "addressable"

gem "agent_connect", github: "gip-inclusion/agent_connect_engine"

# Easily generate PDF from HTML
gem "wicked_pdf"
gem "wkhtmltopdf-binary"
# Easily generate PDF from HTML with puppeteer and headless chrome
gem "grover"

# CORS support
gem "rack-cors"
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ GEM
rake (>= 13)
groupdate (6.5.1)
activesupport (>= 7)
grover (1.2.3)
nokogiri (~> 1)
hashdiff (1.1.2)
hashery (2.1.2)
htmlentities (4.3.4)
Expand Down Expand Up @@ -633,7 +635,6 @@ GEM
with_advisory_lock (5.1.0)
activerecord (>= 6.1)
zeitwerk (>= 2.6)
wkhtmltopdf-binary (0.12.6.8)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.7.1)
Expand Down Expand Up @@ -669,6 +670,7 @@ DEPENDENCIES
factory_bot_rails
faraday
groupdate
grover
image_processing
jbuilder (~> 2.7)
jsbundling-rails
Expand Down Expand Up @@ -717,9 +719,7 @@ DEPENDENCIES
tzinfo-data
web-console (>= 3.3.0)
webmock
wicked_pdf
with_advisory_lock
wkhtmltopdf-binary

RUBY VERSION
ruby 3.4.1p0
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/invitations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def invite_user
end

def pdf
WickedPdf.new.pdf_from_string(invitation.content, encoding: "utf-8")
Grover.new(invitation.content, format: "A4", print_background: true).to_pdf
end

def pdf_filename
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/notifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def notify_participation
end

def pdf
WickedPdf.new.pdf_from_string(notify_participation.notification.content, encoding: "utf-8")
Grover.new(notify_participation.notification.content, format: "A4", print_background: true).to_pdf
end

def pdf_filename
Expand Down
10 changes: 0 additions & 10 deletions app/helpers/pdf_helper.rb

This file was deleted.

135 changes: 79 additions & 56 deletions app/javascript/stylesheets/pdf.scss

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions app/views/layouts/pdf.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>PDF</title>
<%= pdf_stylesheet_link_tag("pdf") %>
<meta charset="utf-8">
<title>PDF</title>
<%= stylesheet_link_tag 'pdf' %>
</head>
<body>
<%= yield %>
Expand Down
32 changes: 17 additions & 15 deletions app/views/letters/_header.html.erb
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
<div>
<div class="header-left-col">
<div>
<div class="header-logo">
<%= image_tag(organisation.logo.attached? ? organisation.logo.url : department.logo.url) %>
</div>
<div class="header">
<div>
<div class="header-logo">
<%= image_tag(organisation.logo.attached? ? organisation.logo.url : department.logo.url) %>
</div>
<% if direction_names.blank? %>
<p><%= organisation.name.upcase %></p>
<% else %>
<% direction_names.each do |direction_name| %>
<p><%= direction_name.upcase %></p>
<% end %>
<% end %>
</div>
<div class="header-right-col">
<div>
<p><%= sender_city || department.capital %>, le <%= Date.today.strftime('%d/%m/%Y') %></p>
<br/>
<p>À l'attention de</p>
<br/><br/><br/>
<br/><br/>
</div>
<div class="user-address">
<p><%= user.title.upcase %> <%= user.first_name.upcase %> <%= user.last_name.upcase %><br/>
<%= simple_format(user.parsed_street_address.upcase, {}, wrapper_tag: "span") %><br/>
<%= user.parsed_post_code_and_city.upcase %></p>
</div>
</div>
<div class="direction-names">
<% if direction_names.blank? %>
<p><%= organisation.name.upcase %></p>
<% else %>
<% direction_names.each do |direction_name| %>
<p><%= direction_name.upcase %></p>
<% end %>
<% end %>
</div>
7 changes: 3 additions & 4 deletions app/views/letters/invitations/atelier.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
<p>Vous êtes <%= user_designation %> et bénéficiez d'un accompagnement. Pour en profiter au mieux, nous vous invitons à vous inscrire directement et librement aux ateliers et formations de votre choix.</p>
<p>Pour faciliter votre inscription, <%= sender_name %> a mis en place <span class="bold-blue">une plateforme vous permettant de vous inscrire vous-même.</span></p>
<p>Choisissez un créneau à votre convenance&nbsp;:</p>
<div>
<div class="invitation-left-col pdf-align-center">
<div class="invitation-choices">
<div class="pdf-align-center">
<div>soit en scannant ce QR code</div>
<div class="qr-code"><%= image_tag(qr_code.to_data_url) %></div>
</div>
<div class="invitation-right-col pdf-align-center">
<div class="pdf-align-center">
<div>soit en vous rendant à l'adresse</div>
<div class="invitation-token"><%= invitation_url %> </div>
</div>
</div>
<br style="clear:both"/>
<%= tag.p tag.span(mandatory_warning, class: "bold-blue") if mandatory_warning %>
<%= tag.p tag.span("En l'absence d'action de votre part, #{punishable_warning}.", class: "bold-blue") if punishable_warning.present? %>
<%= render "letters/invitations/help_message", invitation: invitation, help_address: help_address %>
Expand Down
7 changes: 3 additions & 4 deletions app/views/letters/invitations/atelier_enfants_ados.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@
<p>Nous te proposons de découvrir le programme.</p>
<p><%= sender_name.capitalize %> a mis en place <span class="bold-blue">une plateforme te permettant de t'inscrire.</span></p>
<p>Choisis ton créneau&nbsp;:</p>
<div>
<div class="invitation-left-col pdf-align-center">
<div class="invitation-choices">
<div class="pdf-align-center">
<div>soit en scannant ce QR code</div>
<div class="qr-code"><%= image_tag(qr_code.to_data_url) %></div>
</div>
<div class="invitation-right-col pdf-align-center">
<div class="pdf-align-center">
<div>soit en vous rendant à l'adresse</div>
<div class="invitation-token"><%= invitation_url %> </div>
</div>
</div>
<br style="clear:both"/>

<div class="letter-signature">
<%= render "common/organisation_signature", signature_lines: signature_lines, department: department %>
Expand Down
7 changes: 3 additions & 4 deletions app/views/letters/invitations/short.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
<p>Vous êtes <%= user.conjugate('invité') %> pour un <%= rdv_title %>.</p>
<p>Pour faciliter votre prise de rendez-vous, <%= sender_name %> a mis en place <span class="bold-blue">une plateforme vous permettant de prendre rendez-vous vous-même.</span></p>
<p>Choisissez un créneau à votre convenance&nbsp;:</p>
<div>
<div class="invitation-left-col pdf-align-center">
<div class="invitation-choices">
<div class="pdf-align-center">
<div>soit en scannant ce QR code</div>
<div class="qr-code"><%= image_tag(qr_code.to_data_url) %></div>
</div>
<div class="invitation-right-col pdf-align-center">
<div class="pdf-align-center">
<div>soit en vous rendant à l'adresse</div>
<div class="invitation-token"><%= invitation_url %> </div>
</div>
</div>
<br style="clear:both"/>
<%= tag.p tag.span(mandatory_warning, class: "bold-blue") if mandatory_warning %>
<%= tag.p tag.span("En l'absence d'action de votre part, #{punishable_warning}.", class: "bold-blue") if punishable_warning.present? %>
<%= render "letters/invitations/help_message", invitation: invitation, help_address: help_address %>
Expand Down
7 changes: 3 additions & 4 deletions app/views/letters/invitations/standard.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
<%= tag.p(custom_sentence) if custom_sentence %>
<p>Pour faciliter votre prise de rendez-vous, <%= sender_name %> a mis en place <span class="bold-blue">une plateforme vous permettant de prendre rendez-vous vous-même.</span></p>
<p>Choisissez un créneau à votre convenance<%= " dans un délai de #{Invitation::NUMBER_OF_DAYS_BEFORE_REMINDER} jours à réception de ce courrier" if invitation.expireable? %>&nbsp;:</p>
<div>
<div class="invitation-left-col pdf-align-center">
<div class="invitation-choices">
<div class="pdf-align-center">
<div>soit en scannant ce QR code</div>
<div class="qr-code"><%= image_tag(qr_code.to_data_url) %></div>
</div>
<div class="invitation-right-col pdf-align-center">
<div class="pdf-align-center">
<div>soit en vous rendant à l'adresse</div>
<div class="invitation-token"><%= invitation_url %> </div>
</div>
</div>
<br style="clear:both"/>
<%= tag.p tag.span(mandatory_warning, class: "bold-blue") if mandatory_warning %>
<%= tag.p tag.span("En l'absence d'action de votre part, #{punishable_warning}.", class: "bold-blue") if punishable_warning.present? %>
<%= render "letters/invitations/help_message", invitation: invitation, help_address: help_address %>
Expand Down
3 changes: 0 additions & 3 deletions config/initializers/wicked_pdf.rb

This file was deleted.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
"mobx": "^6.10.0",
"mobx-react-lite": "^4.0.3",
"prop-types": "^15.7.2",
"puppeteer": "^24.1.1",
"qr-scanner": "^1.4.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react_ujs": "^2.6.1",
"react-dom": "^17.0.2",
"remixicon": "^4.5.0",
"sass": "^1.70.0",
"sass-loader": "^14.0.0",
Expand All @@ -46,7 +47,7 @@
"version": "1.22.5",
"devDependencies": {
"eslint": "^8.49.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
Expand Down
2 changes: 1 addition & 1 deletion spec/controllers/invitations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
end

before do
allow(WickedPdf).to receive_message_chain(:new, :pdf_from_string)
allow(Grover).to receive_message_chain(:new, :to_pdf)
allow(invitation).to receive(:content).and_return("some content")
end

Expand Down
14 changes: 8 additions & 6 deletions spec/support/download_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ def download
end

def download_content(format: nil)
format == "pdf" ? PDF::Reader.new(download) : File.read(download)
wait_for_download
case format
when "pdf"
content = File.read(download, mode: "rb")
PDF::Reader.new(StringIO.new(content))
else
File.read(download)
end
end

def wait_for_download
Expand All @@ -21,11 +28,6 @@ def wait_for_download
end
end

def downloaded_content(format: nil)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cette méthode n'était pas utilisée

wait_for_download
download_content(format:)
end

def downloaded?
!downloading? && downloads.any?
end
Expand Down
Loading
Loading