You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.3 KiB
134 lines
3.3 KiB
#!/usr/bin/env python
|
|
"""
|
|
Progress GUI for Reddit Video Maker Bot.
|
|
Real-time progress tracking with steps and previews.
|
|
"""
|
|
import os
|
|
import json
|
|
import threading
|
|
import webbrowser
|
|
from pathlib import Path
|
|
|
|
from flask import Flask, render_template, send_from_directory, jsonify, request
|
|
from flask_socketio import SocketIO, emit
|
|
|
|
from utils.progress import progress_tracker
|
|
|
|
# Configuration
|
|
HOST = "0.0.0.0"
|
|
PORT = 5000
|
|
|
|
# Configure Flask app
|
|
app = Flask(__name__, template_folder="GUI", static_folder="GUI/static")
|
|
app.secret_key = os.urandom(24)
|
|
|
|
# Configure SocketIO for real-time updates
|
|
socketio = SocketIO(app, cors_allowed_origins="*", async_mode="gevent")
|
|
|
|
|
|
# Progress update callback
|
|
def broadcast_progress(data):
|
|
"""Broadcast progress updates to all connected clients."""
|
|
socketio.emit("progress_update", data, namespace="/progress")
|
|
|
|
|
|
# Register the callback
|
|
progress_tracker.add_update_callback(broadcast_progress)
|
|
|
|
|
|
@app.after_request
|
|
def after_request(response):
|
|
"""Ensure responses aren't cached."""
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
|
response.headers["Expires"] = 0
|
|
response.headers["Pragma"] = "no-cache"
|
|
return response
|
|
|
|
|
|
@app.route("/")
|
|
def index():
|
|
"""Main progress dashboard."""
|
|
return render_template("progress.html")
|
|
|
|
|
|
@app.route("/api/status")
|
|
def get_status():
|
|
"""Get current progress status."""
|
|
return jsonify(progress_tracker.get_status())
|
|
|
|
|
|
@app.route("/api/history")
|
|
def get_history():
|
|
"""Get job history."""
|
|
return jsonify({
|
|
"jobs": [job.to_dict() for job in progress_tracker.job_history]
|
|
})
|
|
|
|
|
|
# Serve static files
|
|
@app.route("/static/<path:filename>")
|
|
def static_files(filename):
|
|
"""Serve static files."""
|
|
return send_from_directory("GUI/static", filename)
|
|
|
|
|
|
# Serve result videos
|
|
@app.route("/results/<path:name>")
|
|
def results(name):
|
|
"""Serve result videos."""
|
|
return send_from_directory("results", name)
|
|
|
|
|
|
# Serve preview images
|
|
@app.route("/preview/<path:name>")
|
|
def previews(name):
|
|
"""Serve preview images."""
|
|
return send_from_directory("assets/temp", name)
|
|
|
|
|
|
# Serve temp assets (screenshots, audio visualizations)
|
|
@app.route("/assets/<path:name>")
|
|
def assets(name):
|
|
"""Serve asset files."""
|
|
return send_from_directory("assets", name)
|
|
|
|
|
|
# SocketIO Events
|
|
@socketio.on("connect", namespace="/progress")
|
|
def handle_connect():
|
|
"""Handle client connection."""
|
|
emit("progress_update", progress_tracker.get_status())
|
|
|
|
|
|
@socketio.on("disconnect", namespace="/progress")
|
|
def handle_disconnect():
|
|
"""Handle client disconnection."""
|
|
pass
|
|
|
|
|
|
@socketio.on("request_status", namespace="/progress")
|
|
def handle_request_status():
|
|
"""Handle status request from client."""
|
|
emit("progress_update", progress_tracker.get_status())
|
|
|
|
|
|
def run_gui(open_browser=True):
|
|
"""Run the progress GUI server."""
|
|
if open_browser:
|
|
webbrowser.open(f"http://localhost:{PORT}", new=2)
|
|
|
|
print(f"Progress GUI running at http://localhost:{PORT}")
|
|
socketio.run(app, host=HOST, port=PORT, debug=False)
|
|
|
|
|
|
def run_gui_background():
|
|
"""Run the GUI server in a background thread."""
|
|
thread = threading.Thread(target=lambda: socketio.run(app, host=HOST, port=PORT, debug=False, use_reloader=False))
|
|
thread.daemon = True
|
|
thread.start()
|
|
return thread
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_gui()
|