Files
Catalogue-Generator/generate_catalog.py
2026-05-13 22:41:42 +02:00

185 lines
4.4 KiB
Python

from pathlib import Path
import argparse
import csv
from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
def load_csv(csv_path):
categories = {}
with open(csv_path, newline="", encoding="utf-8-sig") as f:
sample = f.read(4096)
f.seek(0)
dialect = csv.Sniffer().sniff(sample, delimiters=",;")
reader = csv.DictReader(f, dialect=dialect)
for row in reader:
normalized = {
(key or "").strip().lower().replace(" ", "_"): (value or "").strip()
for key, value in row.items()
}
category = (
normalized.get("category")
or normalized.get("catagory")
or normalized.get("kategorie")
or "Ostatní"
)
name = (
normalized.get("name")
or normalized.get("nazev")
or normalized.get("název")
or ""
)
price = (
normalized.get("price")
or normalized.get("cena")
or ""
)
image = (
normalized.get("image")
or normalized.get("foto")
or normalized.get("fotka")
or normalized.get("obrazek")
or normalized.get("obrázek")
or ""
)
show_allergen_icon = (
normalized.get("show_alergen_icon")
or normalized.get("show_allergen_icon")
or normalized.get("alergen_icon")
or normalized.get("allergen_icon")
or ""
).lower() in ("1", "true", "yes", "ano", "y")
note = (
normalized.get("note")
or normalized.get("description")
or normalized.get("poznamka")
or normalized.get("poznámka")
or ""
)
if category not in categories:
categories[category] = []
categories[category].append({
"name": name,
"price": price,
"image": image,
"show_allergen_icon": show_allergen_icon,
"description": note,
})
return categories
def build_catalog_data(title, subtitle, categories):
return {
"title": title,
"subtitle": subtitle,
"categories": [
{
"name": name,
"products": products,
}
for name, products in categories.items()
],
}
def render_html(data, template_dir, images_dir):
env = Environment(
loader=FileSystemLoader(template_dir)
)
template = env.get_template("catalog.html.j2")
return template.render(
catalog=data,
brand=data,
settings={
"columns": 4,
"page_size": "1024px 768px",
"margin": "0",
},
images_dir=images_dir.as_posix(),
assets_dir=(Path(__file__).resolve().parent / "assets").as_posix(),
logo_exists=(Path(__file__).resolve().parent / "assets" / "logo.png").exists(),
)
def generate_pdf(html_content, output_path):
HTML(string=html_content).write_pdf(output_path)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"-i",
"--input",
required=True,
help="CSV input file"
)
parser.add_argument(
"--output",
default="output/catalog.pdf",
help="Output PDF path"
)
parser.add_argument(
"--images-dir",
default="images",
help="Directory with product images"
)
parser.add_argument(
"--title",
default="Bistro Ušky",
)
parser.add_argument(
"--subtitle",
default="Cake & Patisserie",
)
args = parser.parse_args()
base_dir = Path(__file__).resolve().parent
csv_path = Path(args.input)
output_path = Path(args.output)
images_dir = Path(args.images_dir)
output_path.parent.mkdir(parents=True, exist_ok=True)
categories = load_csv(csv_path)
catalog_data = build_catalog_data(
args.title,
args.subtitle,
categories,
)
html = render_html(
catalog_data,
base_dir / "templates",
images_dir,
)
generate_pdf(html, output_path)
print(f"PDF generated: {output_path}")
if __name__ == "__main__":
main()