|
|
|
""" |
|
Generates slide markdown plus TTS audio and images using Gemini models. |
|
|
|
Functions exposed: |
|
generate_slideshow_with_audio(topic) -> (list_of_slide_markdown, list_of_audio_paths, list_of_image_paths) |
|
""" |
|
|
|
import asyncio |
|
import atexit |
|
import datetime |
|
import os |
|
import re |
|
import shutil |
|
import struct |
|
import tempfile |
|
from pathlib import Path |
|
from io import BytesIO |
|
from typing import Dict, List, Optional |
|
|
|
from dotenv import load_dotenv |
|
from google import genai |
|
from google.genai import types |
|
from PIL import Image |
|
|
|
load_dotenv() |
|
GEMINI_API_KEY = os.environ.get("GEMINI_KEY") |
|
|
|
|
|
_temp_dirs: Dict[str, str] = {} |
|
|
|
def get_temp_dir(session_id: str) -> str: |
|
"""Get or create a temporary directory for a user session""" |
|
if session_id not in _temp_dirs: |
|
temp_dir = tempfile.mkdtemp(prefix=f"slideshow_{session_id}_") |
|
_temp_dirs[session_id] = temp_dir |
|
return _temp_dirs[session_id] |
|
|
|
|
|
def generate_slideshow_with_audio(topic: str, session_id: str = None) -> tuple: |
|
"""Generate slides, audio, and images for a presentation on a topic |
|
|
|
Args: |
|
topic: The presentation topic |
|
session_id: Optional session identifier for temp file management |
|
|
|
Returns: |
|
tuple: (list_of_slide_markdown, list_of_audio_paths, list_of_image_paths) |
|
""" |
|
|
|
return asyncio.run(generate_slideshow_with_audio_async(topic, session_id)) |
|
|
|
async def generate_slideshow_with_audio_async(topic: str, session_id: str = None) -> tuple: |
|
"""Async version of generate_slideshow_with_audio |
|
|
|
Args: |
|
topic: The presentation topic |
|
session_id: Optional session identifier for temp file management |
|
|
|
Returns: |
|
tuple: (list_of_slide_markdown, list_of_audio_paths, list_of_image_paths) |
|
""" |
|
|
|
|
|
|
|
|
|
|
|
slides = ["# Example Slide\n\n- This is a placeholder"] |
|
audio_files = [] |
|
image_files = [] |
|
|
|
return slides, audio_files, image_files |
|
|
|
def validate_topic(topic: str) -> bool: |
|
"""Validate if the topic is appropriate for generating a slideshow |
|
|
|
Args: |
|
topic: The topic to validate |
|
|
|
Returns: |
|
bool: True if the topic is valid, False otherwise |
|
""" |
|
|
|
topic = (topic or "").strip() |
|
return len(topic) > 0 |
|
|
|
|
|
@atexit.register |
|
def cleanup_temp_dirs(): |
|
"""Clean up all temporary directories on application exit""" |
|
for session_id, temp_dir in _temp_dirs.items(): |
|
if os.path.exists(temp_dir): |
|
shutil.rmtree(temp_dir, ignore_errors=True) |
|
|