Paperless-ngx mail parser that swaps the upstream Gotenberg/Chromium dependency for WeasyPrint. Pure Python, no browser, smaller attack surface for HTML email body rendering.
Built it because Gotenberg's bundled Chromium structurally lags Debian's security pocket by 1-2 weeks, producing a recurring ~90 CRITICAL CVE window. The Gotenberg maintainer formally treats it as "trusted content only" -- which doesn't fit an inbox receiving email from the open internet.
Subclasses upstream's MailDocumentParser (in paperless.parsers.mail) and
overrides the four methods that called Gotenberg/Tika:
generate_pdf_from_mail-- WeasyPrint instead ofchromium.html_to_pdfgenerate_pdf_from_html-- WeasyPrint with cid: attachment rewritinggenerate_pdf(the merge step) -- pypdf instead of Gotenberg's merge routetika_parse-- stdlib HTML->text instead of a Tika network call
Registers via the paperless_ngx.parsers entrypoint with score=100,
beating upstream's MailDocumentParser (score=10) at parser dispatch.
Optional. After the body renders, walks mail.attachments, appends
embeddable ones to the merged PDF (PDF + JPEG + PNG inline; everything
else gets a "skipped" appendix listing).
Combined with consumption_scope=EMAIL_ONLY and pdf_layout=HTML_ONLY
on the Paperless mail rule, you get one document per email containing
body and attachments together. (Note: that means EMAIL_ONLY no longer
strictly means "only the email body" once this plugin is active --
documented trade-off, not a bug.)
Build the included Dockerfile, layer onto whatever Paperless image you run. The plugin auto-registers on container start; no env vars to set.
FROM ghcr.io/<your-username>/paperless-weasyprint:<tag>- Some HTML email shapes don't render cleanly under WeasyPrint -- Outlook MSO conditionals, VML namespaces, position:absolute marketing layouts. Receipt and transactional emails are usually fine.
- No PDF/A output. If you set
PAPERLESS_OCR_OUTPUT_TYPE=pdfa, the generated PDFs aren't PDF/A compliant. Post-process withocrmypdf --output-type pdfa --skip-textif you need it. - Subclass risk: if upstream changes the signature of
generate_pdf_from_mailorgenerate_pdf_from_html, this plugin breaks until updated. Pin paperless-ngx by digest, watch for upstream changes. - Embed-attachments scope is PDF + JPEG + PNG only. Other types (.docx, .xlsx, .heic, .svg, .zip, etc.) skip with an appendix note.
I built this quickly as a stopgap for the notable WTF with the Gotenberg project state and don't plan to actively maintain it -- though I'll do occasional updates. Happy to support anyone who wants to take it forward.
AGPL-3.0-or-later. Matches Paperless-ngx upstream.