import logging import os import re import base64 import subprocess import tempfile from pathlib import Path from jinja2 import Environment, FileSystemLoader logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s" ) logger = logging.getLogger(__name__.split(".")[-1]) class BadgeGeneratorService: def __init__(self, svg_template: Path, html_template: Path, chrome_path: Path): self.svg_template = svg_template self.html_template = html_template self.chrome_path = chrome_path def generate_badge(self, name, seat_id, picture) -> None: svg = self._get_svg(name, seat_id, picture) html = self._svg_to_html(svg) self._html_to_pdf(html, f"output_badges/{name}.pdf") logger.info(f"Created: {name}, {seat_id}, {str(picture)[:10]}") def _get_svg(self, username: str, seat: str, image_base64: bytes) -> str: env = Environment(loader=FileSystemLoader("template")) template = env.get_template(self.svg_template.name) if image_base64: image_base64 = base64.b64encode(image_base64).decode("utf-8") else: image_base64 = "Standard picture" svg = template.render( picture=image_base64, username=username, seat_id=seat ) return svg def _svg_to_html(self, svg: str) -> str: width = re.search(r'width="([^"]+)"', svg).group(1) height = re.search(r'height="([^"]+)"', svg).group(1) env = Environment(loader=FileSystemLoader("template")) template = env.get_template(self.html_template.name) html = template.render( width=width, height=height, svg=svg ) return html def _html_to_pdf(self, html: str, pdf: str): with tempfile.NamedTemporaryFile(delete=False, suffix=".html", mode="w", encoding="utf-8") as file: file.write(html) html_path = file.name try: subprocess.run([ self.chrome_path, "--headless", "--disable-gpu", f"--print-to-pdf={os.path.abspath(pdf)}", html_path ], check=True) finally: os.remove(html_path)