82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
import base64
|
|
import logging
|
|
import re
|
|
import subprocess
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
logger = logging.getLogger(__name__.split(".")[-1])
|
|
|
|
|
|
def get_default_user_image(image_path: Path) -> str:
|
|
with open(image_path, "rb") as file:
|
|
encoded_bytes = base64.b64encode(file.read())
|
|
return encoded_bytes.decode("utf-8")
|
|
|
|
|
|
class BadgeGeneratorService:
|
|
def __init__(self, config: str):
|
|
with open(config, "rb") as file:
|
|
config = tomllib.load(file)
|
|
|
|
self.bg_config = config["badge_generator"]
|
|
self.env = Environment(loader=FileSystemLoader("template"))
|
|
self.output_path = Path("output_badges")
|
|
self.output_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
self.svg_template = self.env.get_template(Path(self.bg_config["svg_template"]).name)
|
|
self.html_template = self.env.get_template(Path(self.bg_config["html_template"]).name)
|
|
self.browser_path = Path(self.bg_config["browser_path"])
|
|
self.default_image = get_default_user_image(Path(self.bg_config["default_user_image"]))
|
|
self._badge_count = 0
|
|
|
|
def _get_user_svg(self, user_name: str, seat_id: str, user_image: bytes) -> str:
|
|
if user_image:
|
|
user_image = base64.b64encode(user_image).decode("utf-8")
|
|
else:
|
|
user_image = self.default_image
|
|
|
|
svg = self.svg_template.render(
|
|
picture=user_image,
|
|
username=user_name,
|
|
seat_id=seat_id
|
|
)
|
|
return svg
|
|
|
|
def _get_html_from_svg(self, user_svg: str) -> str:
|
|
width = re.search(r'width="([^"]+)"', user_svg).group(1)
|
|
height = re.search(r'height="([^"]+)"', user_svg).group(1)
|
|
|
|
html = self.html_template.render(
|
|
width=width,
|
|
height=height,
|
|
svg=user_svg
|
|
)
|
|
return html
|
|
|
|
def _html_to_pdf(self, user_html: str, output_path: Path) -> None:
|
|
html_path = output_path.with_suffix(".html")
|
|
|
|
html_path.write_text(user_html, encoding="utf-8")
|
|
|
|
try:
|
|
subprocess.run([
|
|
self.browser_path,
|
|
"--headless",
|
|
"--disable-gpu",
|
|
f"--print-to-pdf={output_path.resolve()}",
|
|
html_path.resolve()
|
|
], check=True)
|
|
finally:
|
|
html_path.unlink(missing_ok=True)
|
|
|
|
def generate_badge(self, user_name, seat_id, picture) -> None:
|
|
svg = self._get_user_svg(user_name, seat_id, picture)
|
|
html = self._get_html_from_svg(svg)
|
|
output_path = self.output_path / f"{user_name}.pdf"
|
|
self._html_to_pdf(html, output_path)
|
|
self._badge_count += 1
|
|
logger.info(f"({self._badge_count}) Created: {output_path}, {user_name}, {seat_id}, {str(picture)[:10]}")
|