From 205dc4a29c73497d53f101fad4ef3f3dc4478b9c Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Mon, 5 Apr 2021 11:28:23 +0200
Subject: [PATCH] Use a headless Chromium instead of electron-pdf

---
 Dockerfile                    | 25 +------------------------
 aleksis/core/static/print.css |  1 +
 aleksis/core/util/pdf.py      | 31 +++++++++++++++++++++++++++----
 docs/dev/01_setup.rst         |  6 +-----
 4 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 275f97ec5..40381ccac 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -33,30 +33,7 @@ RUN apt-get -y update && \
 	libssl-dev \
 	postgresql-client \
 	yarnpkg \
-	xvfb \
-    x11-xkb-utils \
-    xfonts-100dpi \
-    xfonts-75dpi \
-    xfonts-scalable \
-    xfonts-cyrillic \
-    x11-apps \
-    clang \
-    libdbus-1-dev \
-    libgtk2.0-dev \
-    libnotify-dev \
-    gnome-keyring \
-    libgconf2-dev \
-    libasound2-dev \
-    libcap-dev \
-    libcups2-dev \
-    libxtst-dev \
-    libxss1 \
-    libnss3-dev \
-    gcc-multilib \
-    libgbm-dev \
-    xauth \
-    g++-multilib && \
-	eatmydata yarnpkg global add electron-pdf && \
+	chromium && \
     eatmydata pip install uwsgi
 
 # Install extra dependencies
diff --git a/aleksis/core/static/print.css b/aleksis/core/static/print.css
index cd3eeeea0..cda82eaca 100644
--- a/aleksis/core/static/print.css
+++ b/aleksis/core/static/print.css
@@ -5,6 +5,7 @@
 @page {
     size: A4;
     padding: 30mm;
+    margin: 0;
 }
 
 header {
diff --git a/aleksis/core/util/pdf.py b/aleksis/core/util/pdf.py
index d8d3eb4a2..97b5edee7 100644
--- a/aleksis/core/util/pdf.py
+++ b/aleksis/core/util/pdf.py
@@ -2,11 +2,13 @@ import glob
 import os
 import subprocess  # noqa
 from tempfile import TemporaryDirectory
+from typing import Optional
 
 from django.http.request import HttpRequest
 from django.http.response import HttpResponse
 from django.shortcuts import render
 from django.template.loader import render_to_string
+from django.utils.translation import get_language
 from django.utils.translation import gettext as _
 
 from celery_progress.backend import ProgressRecorder
@@ -18,7 +20,9 @@ from aleksis.core.util.core_helpers import path_and_rename
 
 
 @recorded_task
-def generate_pdf(html_code: str, pdf_path: str, recorder: ProgressRecorder):
+def generate_pdf(
+    html_code: str, pdf_path: str, recorder: ProgressRecorder, lang: Optional[str] = None
+):
     """Generate a PDF file by rendering the HTML code using electron-pdf."""
     recorder.set_progress(0, 1)
 
@@ -29,8 +33,25 @@ def generate_pdf(html_code: str, pdf_path: str, recorder: ProgressRecorder):
         with open(path, "w") as f:
             f.write(html_code)
 
-        # Start a X framebuffer and run electron-pdf
-        subprocess.run(["xvfb-run", "-a", "electron-pdf", path, pdf_path])  # noqa
+        lang = lang or get_language()
+
+        # Run PDF generation using a headless Chromium
+        cmd = [
+            "chromium",
+            "--headless",
+            "--no-sandbox",
+            "--run-all-compositor-stages-before-draw",
+            "--temp-profile",
+            "--disable-dev-shm-usage",
+            "--disable-gpu",
+            "--disable-setuid-sandbox",
+            "--dbus-stub",
+            f"--home-dir={temp_dir}",
+            f"--lang={lang}",
+            f"--print-to-pdf={pdf_path}",
+            f"file://{path}",
+        ]
+        subprocess.run(cmd)  # noqa
 
     recorder.set_progress(1, 1)
 
@@ -52,7 +73,9 @@ def render_pdf(request: HttpRequest, template_name: str, context: dict = None) -
 
     html_template = render_to_string(template_name, context)
 
-    result = generate_pdf.delay(html_template, os.path.join(MEDIA_ROOT, pdf_path))
+    result = generate_pdf.delay(
+        html_template, os.path.join(MEDIA_ROOT, pdf_path), lang=get_language()
+    )
 
     context = {
         "title": _("Progress: Generate PDF file"),
diff --git a/docs/dev/01_setup.rst b/docs/dev/01_setup.rst
index 30e8acc90..122a9baa1 100644
--- a/docs/dev/01_setup.rst
+++ b/docs/dev/01_setup.rst
@@ -28,11 +28,7 @@ Install native dependencies
 
 Some system libraries are required to install AlekSIS::
 
-  sudo apt install build-essential libpq-dev libpq5 libssl-dev python3-dev python3-pip python3-venv yarnpkg gettext xvfb
-
-Additionally, you have to install ``electron-pdf`` for the PDF rendering feature using ``npm``::
-
-  sudo yarn global add electron-pdf
+  sudo apt install build-essential libpq-dev libpq5 libssl-dev python3-dev python3-pip python3-venv yarnpkg gettext chromium
 
 Get Poetry
 ----------
-- 
GitLab