ezgg-badge-generator/services/BadgeGeneratorService.py

69 lines
2.3 KiB
Python

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, chrome_path: Path):
self.svg_template = svg_template
self.chrome_path = chrome_path
def generate_badge(self, name, seat_id, picture) -> None:
svg = self.generate_svg(name, seat_id, picture)
self.svg_to_pdf(svg, f"files/{name}.pdf")
def generate_svg(self, username: str, seat: str, image_base64: bytes) -> str:
with open(self.svg_template, "r", encoding="utf-8") as f:
svg = f.read()
# ToDo: Select font size for long names
svg = svg.replace(">test_username</tspan>", f">{username}</tspan>")
svg = svg.replace(">Platz: XYZ</tspan><", f">Platz: {seat}</tspan><")
if image_base64:
encoded = base64.b64encode(image_base64).decode("utf-8")
svg = svg.replace('xlink:href="data:image/jpeg;base64,"', f'xlink:href="data:image/jpeg;base64,{encoded}"')
logger.info(f"Generate svg string: Username: {username}, Seat: {seat}, Picture: {str(image_base64)[:15]}")
return svg
def svg_to_pdf(self, svg_string: str, pdf_path: str):
width = re.search(r'width="([^"]+)"', svg_string).group(1)
height = re.search(r'height="([^"]+)"', svg_string).group(1)
env = Environment(loader=FileSystemLoader("template"))
template = env.get_template("badge_pdf.html")
html = template.render(
width=width,
height=height,
svg_string=svg_string
)
with tempfile.NamedTemporaryFile(delete=False, suffix=".html", mode="w", encoding="utf-8") as f:
f.write(html)
html_path = f.name
try:
subprocess.run([
self.chrome_path,
"--headless",
"--disable-gpu",
f"--print-to-pdf={os.path.abspath(pdf_path)}",
html_path
], check=True)
finally:
os.remove(html_path)
logger.info(f"Created: {pdf_path}")