Skip to content

Replace wkhtmltopdf with Chromium headless for PDF generation#114

Merged
thawn merged 9 commits intomasterfrom
copilot/replace-wkhtml2pdf-with-chromium
Jan 2, 2026
Merged

Replace wkhtmltopdf with Chromium headless for PDF generation#114
thawn merged 9 commits intomasterfrom
copilot/replace-wkhtml2pdf-with-chromium

Conversation

Copy link
Contributor

Copilot AI commented Jan 2, 2026

Replace wkhtmltopdf with Chromium headless for PDF generation ✅

Successfully replaced wkhtmltopdf with Chromium headless for PDF generation, addressing security vulnerabilities and stale development of wkhtmltopdf.

✅ All Requirements Completed:

  1. Print configuration saved before PDF generation

    • Modified savePDF() in print.js to save config first, then generate PDF
    • Ensures Chromium has access to latest print settings
  2. Chromium installed in Docker container

    • Installs chromium package directly from Debian repositories
    • No PPA needed - Debian Trixie has chromium in main repos
    • Simplified installation (single apt-get command)
  3. Headers and footers disabled

    • Using --no-pdf-header-footer flag in chromium command
    • Ensures clean PDF output without browser headers/footers
  4. Page size and margins configurable

    • Page size respects print_page_size configuration setting (e.g., A4, letter, custom dimensions)
    • Page margins configurable via new print_page_margin setting (default: 0.5in)
    • Both settings dynamically applied to PDF generation via CSS @page rules
    • Added UI field in print configuration panel for margin customization
    • Database migration added: Version 2.0.0 migration ensures existing databases get the new print_page_margin configuration

📝 Changes Made:

src/ttmp32gme/print_handler.py

  • create_pdf(): Uses chromium with --headless, --disable-gpu, --no-pdf-header-footer
  • format_print_button(): Detects chromium instead of wkhtmltopdf
  • Tries multiple chromium binary names (chromium, chromium-browser, google-chrome, chrome)
  • Added documentation about margin handling via CSS

src/templates/pdf.html

  • Updated CSS @page rule to use dynamic {{ page_size }} and {{ page_margin }} from configuration
  • Ensures page size and margins respect user settings

src/templates/print.html

  • Added "Page margin" input field in print configuration panel
  • Tooltip explains valid margin formats (0.5in, 1cm, 10mm, etc.)

src/ttmp32gme/ttmp32gme.py

  • Updated /pdf route to pass page_size and page_margin from configuration to template

src/ttmp32gme/db_handler.py

  • Added print_page_margin configuration with default value of "0.5in"
  • Updated database version to "2.0.0" for new installations
  • Added migration in update_db() function: version 2.0.0 adds print_page_margin for existing databases

tests/unit/test_db_handler.py

  • Updated version test to expect "2.0.0"

src/assets/js/print.js

  • savePDF(): Saves configuration before generating PDF

build/docker/Dockerfile

  • Install chromium directly from Debian repos (no PPA needed)
  • Removed Ubuntu-specific software-properties-common and PPA setup
  • Simplified to single apt-get install command

tests/unit/test_print_handler.py

  • Updated all tests to use chromium mocks

TODO.md

  • Marked PDF generation task as completed

✅ Test Results:

  • 134 unit tests - All passing
  • 10 integration tests - All passing
  • Server verification - Starts successfully
  • Docker build - Working correctly

🔧 Technical Implementation:

  • Chromium headless mode with proper PDF generation flags
  • Cross-platform binary detection (tries multiple names)
  • Backward-compatible (gracefully handles missing chromium)
  • Platform-specific button display logic maintained
  • Page size and margins controlled via CSS @page rules with dynamic configuration
  • Database migration system ensures existing installations get updated automatically to version 2.0.0
  • Docker: Uses native Debian chromium package (no snap, no PPA)
Original prompt

This section details on the original issue you should resolve

<issue_title>create PDFs using chromium headless</issue_title>
<issue_description>currently, PDFs are created by wkhtml2pdf, if the command is found. Replace this by chromium (headless).

  • Make sure the print configuration is saved when the print button is pressed (so that chromium has access to the latest print configuration)
  • Install chromium as a dependency when creating the docker container. Use the custom repository add-apt-repository ppa:xtradeb/apps -y to make sure chromium is installed as a normal package, not a snap.
  • Make sure 'Headers and footers' option in the chromium print dialog is disabled</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits January 2, 2026 18:18
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
…valid flag

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copilot AI changed the title [WIP] Replace wkhtml2pdf with chromium headless for PDF creation Replace wkhtmltopdf with Chromium headless for PDF generation Jan 2, 2026
Copilot AI requested a review from thawn January 2, 2026 18:25
@thawn
Copy link
Owner

thawn commented Jan 2, 2026

@copilot set all margins to 0.5inches

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot set all margins to 0.5inches

Set all margins to 0.5 inches via CSS @page rule in pdf.html. Chromium headless respects CSS @page margins (unlike wkhtmltopdf which used command-line flags). The margins are now explicitly defined as margin: 0.5in 0.5in 0.5in 0.5in (top, right, bottom, left). Commit: 562838c

@thawn
Copy link
Owner

thawn commented Jan 2, 2026

@copilot building the docker image fails:

RUN apt-get update &&     apt-get install -y --no-install-recommends         wget         unzip         xz-utils         ca-certificates         ffmpeg         git         software-properties-common         gnupg &&     rm -rf /var/lib/apt/lists/*
#9 0.108 Hit:1 http://deb.debian.org/debian trixie InRelease
#9 0.109 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#9 0.124 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#9 0.135 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9670 kB]
#9 0.223 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5412 B]
#9 0.223 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [94.0 kB]
#9 0.857 Fetched 9860 kB in 1s (12.6 MB/s)
#9 0.857 Reading package lists...
#9 1.353 Reading package lists...
#9 1.832 Building dependency tree...
#9 1.968 Reading state information...
#9 1.985 E: Unable to locate package software-properties-common
#9 ERROR: process "/bin/sh -c apt-get update &&     apt-get install -y --no-install-recommends         wget         unzip         xz-utils         ca-certificates         ffmpeg         git         software-properties-common         gnupg &&     rm -rf /var/lib/apt/lists/*" did not complete successfully: exit code: 100
------
 > [base 3/7] RUN apt-get update &&     apt-get install -y --no-install-recommends         wget         unzip         xz-utils         ca-certificates         ffmpeg         git         software-properties-common         gnupg &&     rm -rf /var/lib/apt/lists/*:
0.109 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
0.124 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
0.135 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9670 kB]
0.223 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5412 B]
0.223 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [94.0 kB]


1.832 Building dependency tree...
1.968 Reading state information...
1.985 E: Unable to locate package software-properties-common

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot building the docker image fails:
RUN apt-get update && apt-get install -y --no-install-recommends wget unzip xz-utils ca-certificates ffmpeg ...

Fixed the Docker build failure. The issue was that software-properties-common and PPAs are Ubuntu-specific and don't exist in Debian Trixie (which the Python 3.12-slim image is based on).

Changed the Dockerfile to install chromium directly from Debian's native repositories instead of trying to use a PPA. This is actually simpler and more reliable - just one apt-get install chromium command. The chromium package in Debian Trixie provides /usr/bin/chromium which is already the first name our code checks for.

Commit: afbf26a

Copy link
Owner

@thawn thawn left a comment

Choose a reason for hiding this comment

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

<link href="/assets/css/print.css" rel="stylesheet">
<style>
@page {
size: A4;
Copy link
Owner

Choose a reason for hiding this comment

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

the page size setting should respect the print configuration setting. While you are at it, also make the page margins configurable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made page size and margins configurable. The PDF now respects the print_page_size and print_page_margin configuration settings. Added a "Page margin" field to the print configuration UI where users can set custom margins (e.g., 0.5in, 1cm, 10mm). Both settings are dynamically applied to the CSS @page rule in pdf.html. Commit: 5fac78f

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copilot AI requested a review from thawn January 2, 2026 19:04
@thawn
Copy link
Owner

thawn commented Jan 2, 2026

@copilot add the new configuration option to the update_db function (as version 2.0.0) to make sure existing databases are updated the first time they are loaded

….0.0)

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot add the new configuration option to the update_db function (as version 2.0.0) to make sure existing databases are updated the first time they are loaded

Added database migration for version 2.0.0 that adds the print_page_margin configuration to existing databases. The migration uses INSERT OR IGNORE to safely add the new config entry when users upgrade from older versions. Also updated the database version from 1.0.0 to 2.0.0 for new installations and updated the corresponding test. Commit: 42420e3

@thawn thawn marked this pull request as ready for review January 2, 2026 19:33
@thawn thawn merged commit 0b27ebe into master Jan 2, 2026
13 checks passed
@thawn thawn deleted the copilot/replace-wkhtml2pdf-with-chromium branch January 2, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create PDFs using chromium headless

2 participants