Spaces:
Sleeping
Sleeping
| #!/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") |