# Keep all existing imports and add any new ones needed import gradio as gr import random from datetime import datetime import tempfile import os import edge_tts import asyncio import warnings import pytz import re import json import pandas as pd from pathlib import Path from gradio_client import Client warnings.filterwarnings('ignore') # Add constants for community generations PAGE_SIZE = 10 FILE_DIR_PATH = "gallery" # Using existing gallery directory # Keep existing STORY_STARTERS array # Keep all existing functions through play_gallery_audio() def list_all_outputs(generation_history): """Load all story generations for community view""" try: directory_path = FILE_DIR_PATH if not os.path.exists(directory_path): return "", gr.update(visible=True) # Get all matched pairs of story/audio files file_pairs = [] for story_file in Path(directory_path).glob("story_*.md"): timestamp = story_file.stem.split('_')[1] audio_pattern = f"audio_{timestamp}_*.mp3" audio_files = list(Path(directory_path).glob(audio_pattern)) if audio_files: # Only include if we have both story and audio file_pairs.append((story_file, audio_files[0])) # Sort by modification time, newest first file_pairs.sort(key=lambda x: os.path.getmtime(x[0]), reverse=True) history_list = generation_history.split(',') if generation_history else [] updated_files = [str(audio) for _, audio in file_pairs if str(audio) not in history_list] updated_history = updated_files + history_list return ','.join(updated_history), gr.update(visible=True) except Exception as e: print(f"Error loading community generations: {str(e)}") return "", gr.update(visible=True) def increase_list_size(list_size): """Increase the number of visible community generations""" return list_size + PAGE_SIZE # Add CSS for community generations css = ''' #live_gen:before { content: ''; animation: svelte-z7cif2-pulseStart 1s cubic-bezier(.4,0,.6,1), svelte-z7cif2-pulse 2s cubic-bezier(.4,0,.6,1) 1s infinite; border: 2px solid var(--color-accent); background: transparent; z-index: var(--layer-1); pointer-events: none; position: absolute; height: 100%; width: 100%; border-radius: 7px; } #live_gen_items{ max-height: 570px; overflow-y: scroll; } ''' # Modified Gradio interface with gr.Blocks(title="AI Story Generator", css=css) as demo: gr.Markdown(""" # 🎭 AI Story Generator & Narrator Generate creative stories, listen to them, and build your gallery! """) # Add hidden state for community generations generation_history = gr.Textbox(visible=False) list_size = gr.Number(value=PAGE_SIZE, visible=False) with gr.Row(): # Keep existing left column with gr.Column(scale=3): with gr.Row(): prompt_input = gr.Textbox( label="Story Concept", placeholder="Enter your story idea...", lines=3 ) with gr.Row(): model_choice = gr.Dropdown( label="Model", choices=[ "mistralai/Mixtral-8x7B-Instruct-v0.1", "mistralai/Mistral-7B-Instruct-v0.2" ], value="mistralai/Mixtral-8x7B-Instruct-v0.1" ) generate_btn = gr.Button("Generate Story") with gr.Row(): story_output = gr.Textbox( label="Generated Story", lines=10, interactive=False ) with gr.Row(): audio_output = gr.Audio( label="Story Narration", type="filepath" ) # Modify right column to include community generations with gr.Column(scale=1): gr.Markdown("### 📚 Story Starters") story_starters = gr.Dataframe( value=STORY_STARTERS, headers=["Category", "Starter"], interactive=False ) # Add Community Generations section with gr.Column(elem_id="live_gen") as community_list: gr.Markdown("### 🎬 Community Stories") with gr.Column(elem_id="live_gen_items"): @gr.render(inputs=[generation_history, list_size]) def show_output_list(generation_history, list_size): history_list = generation_history.split(',') if generation_history else [] history_list_latest = history_list[:list_size] for audio_path in history_list_latest: if not audio_path: continue try: # Get corresponding story file story_path = audio_path.replace('audio_', 'story_').replace('.mp3', '.md') if not os.path.exists(story_path): continue # Read story content with open(story_path, 'r') as file: story_content = file.read() # Extract title from markdown title = story_content.split('\n')[0].replace('# ', '') with gr.Group(): gr.Markdown(value=f"### {title}") gr.Audio(value=audio_path) except Exception as e: print(f"Error showing generation: {str(e)}") continue load_more = gr.Button("Load More Stories") load_more.click(fn=increase_list_size, inputs=list_size, outputs=list_size) # Keep existing event handlers def update_prompt(evt: gr.SelectData): return STORY_STARTERS[evt.index[0]][1] story_starters.select(update_prompt, None, prompt_input) generate_btn.click( fn=process_story_and_audio, inputs=[prompt_input, model_choice], outputs=[story_output, audio_output, gallery] ) # Add auto-refresh for community generations demo.load(fn=list_all_outputs, inputs=generation_history, outputs=[generation_history, community_list], every=2) if __name__ == "__main__": demo.launch()