Files
sufw-anweisenheiten/generate.py
T
2026-03-27 13:19:24 +01:00

150 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CLI entry point for the Attendance PDF Generator.
Usage
-----
python generate.py generate --file Anwesenheit_2026.xlsx --sheet Feb
python generate.py validate --file Anwesenheit_2026.xlsx --sheet Feb
"""
import sys
from pathlib import Path
import click
# Add project root to sys.path so 'src' is importable
sys.path.insert(0, str(Path(__file__).parent))
from src.config_loader import load_config
from src.excel_reader import extract_attendance, extract_persons, extract_year_from_filename
from src.pdf_filler import fill_pdf
from src.validators import show_preview_and_confirm, validate
@click.group()
def cli() -> None:
"""Anwesenheit PDF Generator — Excel → PDF"""
@cli.command("validate")
@click.option(
"--file",
"excel_file",
required=True,
type=click.Path(exists=False, file_okay=True, dir_okay=False),
help="Pfad zur Excel-Datei (z. B. Anwesenheit_2026.xlsx)",
)
@click.option(
"--month",
required=True,
help="Name des Monats-Sheets (z. B. Feb, Mrz, Jan)",
)
def validate_cmd(excel_file: str, month: str) -> None:
"""Nur Validierung und Vorschau – keine PDFs werden erzeugt."""
config = load_config()
errors = validate(excel_file, month)
try:
year = extract_year_from_filename(excel_file, config)
except Exception:
year = 0
try:
persons = extract_persons(excel_file, month, config)
person_count = len(persons)
except Exception:
person_count = 0
show_preview_and_confirm(excel_file, month, year, person_count, config, errors)
if errors:
click.echo("\nValidierung fehlgeschlagen. Keine PDFs erzeugt.")
sys.exit(1)
else:
click.echo("\nValidierung erfolgreich.")
@cli.command("generate")
@click.option(
"--file",
"excel_file",
required=True,
type=click.Path(exists=False, file_okay=True, dir_okay=False),
help="Pfad zur Excel-Datei (z. B. Anwesenheit_2026.xlsx)",
)
@click.option(
"--month",
required=True,
help="Name des Monats-Sheets (z. B. Feb, Mrz, Jan)",
)
@click.option(
"--out",
"output_dir",
required=False,
default=None,
type=click.Path(file_okay=False, dir_okay=True),
help="Ausgabeverzeichnis (Standard: output/ aus config.json)",
)
def generate_cmd(excel_file: str, month: str, output_dir: str | None) -> None:
"""Liest Excel-Daten und erzeugt eine PDF-Datei pro Teilnehmer."""
config = load_config()
# --- Validation ----------------------------------------------------------
errors = validate(excel_file, month)
try:
year = extract_year_from_filename(excel_file, config)
except Exception as exc:
click.echo(f"Fehler bei Jahresextraktion: {exc}", err=True)
sys.exit(1)
try:
persons = extract_persons(excel_file, month, config)
except Exception as exc:
click.echo(f"Fehler beim Lesen der Teilnehmer: {exc}", err=True)
sys.exit(1)
# --- Preview + confirmation ----------------------------------------------
confirmed = show_preview_and_confirm(
excel_file, month, year, len(persons), config, errors
)
if not confirmed:
click.echo("Abgebrochen. Keine PDFs erzeugt.")
sys.exit(0)
if errors:
click.echo("Generierung abgebrochen – es gibt Validierungsfehler.")
sys.exit(1)
# --- Resolve paths -------------------------------------------------------
project_root = Path(__file__).parent
template_path = (project_root / config["template_pdf"]).resolve()
out_dir = Path(output_dir).resolve() if output_dir else (project_root / config["output_dir"]).resolve()
out_dir.mkdir(parents=True, exist_ok=True)
# --- Generate PDFs -------------------------------------------------------
success_count = 0
fail_count = 0
for person in persons:
try:
attendance = extract_attendance(excel_file, month, person, year, config)
output_filename = f"{person.filename_safe_name}.pdf"
output_path = out_dir / output_filename
fill_pdf(attendance, template_path, output_path, config)
click.echo(f" [OK] {output_filename}")
success_count += 1
except Exception as exc:
click.echo(f" [FEHLER] {person.filename_safe_name}: {exc}", err=True)
fail_count += 1
click.echo()
click.echo(f"Fertig: {success_count} PDF(s) erzeugt, {fail_count} Fehler.")
click.echo(f"Ausgabeverzeichnis: {out_dir}")
if fail_count > 0:
sys.exit(1)
if __name__ == "__main__":
cli()