import logging import os import uuid from flask import Flask, render_template, Response, request, session from main import yoink, process, user_streams, stream_lock app = Flask(__name__, static_folder="website/static", template_folder="website") app.secret_key = os.urandom(24) # Necessary for using sessions # Configure logging logging.basicConfig( filename='./logs/app.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) def create_session(): """ Create a new session by generating a UUID and ensuring it does not collide with an existing session in the user_streams global dictionary. Returns: str: A unique session ID. """ session_id = str(uuid.uuid4()) # Even though collisions are unlikely, we check for safety. try: if user_streams[session_id]: session_id = create_session() except KeyError: pass return session_id @app.route('/') def home(): """ Render the home page and initialize a session. Returns: Response: The rendered home page with a unique session id. """ session_id = create_session() session['id'] = session_id logging.info(f"Home page accessed. Assigned initial session ID: {session_id}") return render_template('index.html', session_id=session_id) @app.route('/process_url', methods=['POST']) def process_url(): """ Accept a YouTube URL (from a form submission), initialize the session if necessary, and trigger the transcript retrieval and AI processing. Returns: Response: Text response indicating start or error message. """ session_id = session.get('id') if not session_id: session_id = create_session() session['id'] = session_id logging.info(f"No existing session. Created new session ID: {session_id}") url = request.form['url'] logging.info(f"Received URL for processing from session {session_id}: {url}") success, msg, status_code = process(url, session_id) if success: logging.info(f"Processing started successfully for session {session_id}.") return Response("Processing started. Check /stream_output for updates.", content_type='text/plain', status=200) else: logging.error(f"Processing failed for session {session_id}: {msg}") return Response(msg, content_type='text/plain', status=status_code) @app.route('/stream_output') def stream_output(): """ Stream the AI processing output for the current session. Returns: Response: A streaming response with text/plain content. """ session_id = session.get('id') if not session_id or session_id not in user_streams: logging.warning(f"Stream requested without a valid session ID: {session_id}") return Response("No active stream for this session.", content_type='text/plain', status=400) logging.info(f"Streaming output requested for session {session_id}.") return Response(yoink(session_id), content_type='text/plain', status=200) if __name__ == '__main__': logging.info("Starting Flask application.") # Running with threaded=True to handle multiple requests concurrently. app.run(debug=True, threaded=True)