from __future__ import annotations from pathlib import Path from typing import Iterable ALLOWED_LAYOUT_TYPES = {"title_slide", "content_slide", "split_slide"} def validate_file_extension(filename: str, allowed_extensions: Iterable[str]) -> None: if not any(filename.lower().endswith(ext.lower()) for ext in allowed_extensions): raise ValueError( f"Invalid file extension: {filename}. Allowed extensions are: {list(allowed_extensions)}" ) def validate_template(template_path: str | Path) -> Path: if not template_path: raise ValueError("Template path cannot be empty.") path = Path(template_path) if not path.exists() or not path.is_file(): raise ValueError(f"Template file does not exist: {path}") validate_file_extension(path.name, [".pptx"]) return path def validate_slide_content(slide_content: dict) -> None: if not isinstance(slide_content, dict): raise ValueError("Invalid slide content: Expected a dictionary.") title = slide_content.get("title", "") bullets = slide_content.get("bullets", []) layout_type = slide_content.get("layout_type", "content_slide") if not isinstance(title, str) or not title.strip(): raise ValueError("Each slide must include a non-empty 'title' string.") if not isinstance(bullets, list) or not all(isinstance(item, str) for item in bullets): raise ValueError("Each slide must include 'bullets' as a list of strings.") if layout_type not in ALLOWED_LAYOUT_TYPES: raise ValueError( f"Invalid layout_type '{layout_type}'. Expected one of {sorted(ALLOWED_LAYOUT_TYPES)}." ) def validate_slides(slides: list[dict]) -> bool: if not isinstance(slides, list): raise ValueError("Generated slide data must be a list.") for slide in slides: validate_slide_content(slide) return True