diff --git a/gnommo/cli.py b/gnommo/cli.py index c1bfb0e..b68caa2 100644 --- a/gnommo/cli.py +++ b/gnommo/cli.py @@ -1,6 +1,8 @@ """CLI entry point for GnommoEditor.""" import argparse +import json +import re import sys from pathlib import Path @@ -69,6 +71,22 @@ def main() -> int: help="Print FFmpeg command without executing", ) + # generate-slides command + gen_slides_parser = subparsers.add_parser( + "generate-slides", + help="Generate slides.json from Keynote export folder", + ) + gen_slides_parser.add_argument( + "directory", + type=Path, + help="Path to slides directory (e.g., media/slides/Video1)", + ) + gen_slides_parser.add_argument( + "--type", + default="square", + help="Slide type for all slides (default: square)", + ) + args = parser.parse_args() try: @@ -77,6 +95,8 @@ def main() -> int: elif args.command == "render": output = args.output or (args.project / "out" / "final.mp4") return cmd_render(args.project, output, args.verbose, args.dry_run) + elif args.command == "generate-slides": + return cmd_generate_slides(args.directory, args.type) except GnommoError as e: print(f"Error: {e}", file=sys.stderr) return 1 @@ -154,5 +174,62 @@ def cmd_render(project_path: Path, output_path: Path, verbose: bool, dry_run: bo return 0 +def cmd_generate_slides(directory: Path, slide_type: str) -> int: + """Generate slides.json from Keynote export folder.""" + directory = directory.resolve() + + if not directory.exists(): + print(f"Error: Directory not found: {directory}", file=sys.stderr) + return 1 + + if not directory.is_dir(): + print(f"Error: Not a directory: {directory}", file=sys.stderr) + return 1 + + # Find all image files (png, gif, pdf) + extensions = {".png", ".gif", ".pdf", ".jpg", ".jpeg"} + files = [f for f in directory.iterdir() if f.suffix.lower() in extensions] + + if not files: + print(f"Error: No image files found in {directory}", file=sys.stderr) + return 1 + + # Extract numeric suffix from filenames like "Video1.001.png" + # Pattern: anything followed by .NNN. followed by extension + pattern = re.compile(r"\.(\d+)\.[^.]+$") + + slides = {} + for file in files: + match = pattern.search(file.name) + if match: + num = int(match.group(1)) # "001" -> 1 + slide_id = f"S{num}" + slides[slide_id] = { + "image": file.name, + "type": slide_type, + } + else: + print(f" Warning: Could not parse slide number from: {file.name}") + + if not slides: + print("Error: No valid slide files found", file=sys.stderr) + return 1 + + # Sort by slide number + sorted_slides = dict(sorted(slides.items(), key=lambda x: int(x[0][1:]))) + + # Write slides.json in the same directory + output_path = directory / "slides.json" + with open(output_path, "w", encoding="utf-8") as f: + json.dump(sorted_slides, f, indent=2) + + print(f"Generated {output_path}") + print(f" - Found {len(sorted_slides)} slides") + for slide_id, slide_def in sorted_slides.items(): + print(f" [{slide_id}] {slide_def['image']}") + + return 0 + + if __name__ == "__main__": sys.exit(main())