#!/usr/bin/env python3 import gradio as gr import os import threading import sys import uuid import time from main import generate_multiple_mazes, merge_pdfs # Session management user_sessions = {} def create_session(): """Create a new session for the user""" session_id = str(uuid.uuid4())[:8] # Short session ID user_sessions[session_id] = { 'created_at': time.time(), 'files_generated': 0 } return session_id def get_session_files(session_id): """Get list of PDF files for a specific session""" try: if os.path.exists('pdfs'): pdf_files = [f for f in os.listdir('pdfs') if f.endswith('.pdf') and f.startswith(f"{session_id}_")] pdf_files.sort() return pdf_files if pdf_files else ["No PDF files found for this session"] else: return ["pdfs/ directory does not exist"] except Exception as e: return [f"Error: {str(e)}"] def cleanup_merged_pdf(session_id): """Remove the merged PDF for a session after download""" merged_pdf_path = os.path.join('pdfs', f"{session_id}_merged_mazes.pdf") if os.path.exists(merged_pdf_path): try: os.remove(merged_pdf_path) print(f"Cleaned up merged PDF: {merged_pdf_path}") except Exception as e: print(f"Error cleaning up merged PDF: {e}") def generate_mazes_interface(num_files, width, height, session_id, progress=gr.Progress()): """Interface function for generating mazes with progress tracking""" try: progress(0.1, desc="Starting maze generation...") # Validate parameters if num_files < 1: return "Error: Number of files must be at least 1", None if not (2 <= width <= 200): return "Error: Width must be between 2 and 200", None if not (2 <= height <= 200): return "Error: Height must be between 2 and 200", None progress(0.2, desc="Generating mazes...") # Generate the mazes with session ID success_count = generate_multiple_mazes(num_files, width, height, session_id) progress(1.0, desc="Generation complete!") # Update session info if session_id in user_sessions: user_sessions[session_id]['files_generated'] += success_count if success_count == num_files: return f"Successfully generated {success_count} maze PDFs for session {session_id}", get_session_files(session_id) else: return f"Warning: Only {success_count} out of {num_files} mazes were generated successfully for session {session_id}", get_session_files(session_id) except Exception as e: return f"Error: {str(e)}", None def merge_pdfs_interface(session_id, progress=gr.Progress()): """Interface function for merging PDFs with progress tracking""" try: progress(0.1, desc="Starting PDF merge...") if not os.path.exists('pdfs'): return "Error: pdfs/ directory does not exist", None, None progress(0.5, desc="Merging PDFs...") # Merge only session-specific PDFs success = merge_pdfs('pdfs', session_id) progress(1.0, desc="Merge complete!") if success: merged_pdf_path = os.path.join('pdfs', f"{session_id}_merged_mazes.pdf") if os.path.exists(merged_pdf_path): return f"Successfully merged session {session_id} PDFs into {session_id}_merged_mazes.pdf", get_session_files(session_id), merged_pdf_path else: return "Merge completed but merged file not found", get_session_files(session_id), None else: return "Failed to merge PDFs", get_session_files(session_id), None except Exception as e: return f"Error: {str(e)}", None, None def get_pdf_list(): """Get list of PDF files in pdfs directory""" try: if os.path.exists('pdfs'): pdf_files = [f for f in os.listdir('pdfs') if f.endswith('.pdf')] pdf_files.sort() return pdf_files if pdf_files else ["No PDF files found"] else: return ["pdfs/ directory does not exist"] except Exception as e: return [f"Error: {str(e)}"] def refresh_file_list(): """Refresh the file list""" return get_pdf_list() def create_interface(): """Create the Gradio interface""" # Create pdfs directory if it doesn't exist os.makedirs('pdfs', exist_ok=True) with gr.Blocks(title="Maze Generator", theme=gr.themes.Soft()) as interface: # Session state session_id = gr.State(create_session()) gr.Markdown("# 🎯 Maze Generator") gr.Markdown("Generate custom maze PDFs or merge existing ones using this web interface.") gr.Markdown(f"**Session ID:** {session_id.value} - Your files are isolated from other users") with gr.Tabs(): with gr.TabItem("Generate Mazes"): with gr.Row(): with gr.Column(): gr.Markdown("### Generate New Mazes") num_files = gr.Number( label="Number of Mazes", value=1, minimum=1, maximum=50, step=1 ) width = gr.Number( label="Width (cells)", value=25, minimum=2, maximum=200, step=1 ) height = gr.Number( label="Height (cells)", value=35, minimum=2, maximum=200, step=1 ) generate_btn = gr.Button("🚀 Generate Mazes", variant="primary", size="lg") with gr.Column(): gr.Markdown("### Your Generated Files") file_list = gr.List( label="PDF Files for Your Session", value=get_session_files(session_id.value) ) refresh_btn = gr.Button("🔄 Refresh List", size="sm") generate_output = gr.Textbox( label="Status", lines=3, max_lines=5, show_label=False, container=True ) # Event handlers generate_btn.click( fn=generate_mazes_interface, inputs=[num_files, width, height, session_id], outputs=[generate_output, file_list], show_progress=True ) refresh_btn.click( fn=lambda sid: get_session_files(sid), inputs=[session_id], outputs=[file_list] ) with gr.TabItem("Merge PDFs"): with gr.Row(): with gr.Column(): gr.Markdown("### Merge Your PDFs") gr.Markdown("Merge all your PDF files in this session into a single file. Individual files will be deleted after merging.") merge_btn = gr.Button("🔗 Merge Your PDFs", variant="primary", size="lg") merge_output = gr.Textbox( label="Merge Status", lines=3, max_lines=5, show_label=False, container=True ) merge_file_list = gr.List( label="Your PDF Files After Merge", value=get_session_files(session_id.value) ) download_merged_btn = gr.DownloadButton( label="📥 Download Merged PDF", variant="secondary", size="lg" ) # Event handlers merge_btn.click( fn=merge_pdfs_interface, inputs=[session_id], outputs=[merge_output, merge_file_list, download_merged_btn], show_progress=True ) # Clean up merged PDF after download download_merged_btn.click( fn=lambda sid: cleanup_merged_pdf(sid), inputs=[session_id] ) # Auto-refresh file list every few seconds interface.load( fn=lambda sid: (get_session_files(sid), get_session_files(sid)), inputs=[session_id], outputs=[file_list, merge_file_list] ) return interface if __name__ == "__main__": print("🚀 Starting Maze Generator Application...") print("📁 Creating pdfs directory if it doesn't exist...") # Create and launch the interface interface = create_interface() print("🌐 Launching Gradio interface...") print("📍 Server will be available at: http://0.0.0.0:7861") print("📍 Local access: http://localhost:7861") print("⏳ Waiting for server to start...") interface.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True ) print("✅ Maze Generator is ready and running!") print("🎯 Open your browser and navigate to http://localhost:7860")