from flask import Blueprint, request, jsonify, Response from datetime import datetime, timezone from typing import Dict, Any, Tuple from models.state import video_state watchparty_bp = Blueprint("watchparty", __name__) @watchparty_bp.route("/watchparty//video", methods=["GET", "POST"]) def watchparty_video_control(room: str) -> Tuple[Response, int] | Response: room = room.strip() video_state.setdefault(room, {}) if request.method == "POST": data: Dict[str, Any] = request.get_json() or {} url: str = data.get("url", "").strip() if not url: return jsonify({"error": "No video URL"}), 400 video_state[room] = { "url": url, "started_at": datetime.now(timezone.utc).isoformat(), "is_paused": False, "is_active": True, } return jsonify({"status": "started", "url": url}) # GET: return URL, elapsed time, is_paused, is_active video_data = video_state.get(room, {}) if not video_data or "url" not in video_data: return jsonify({"is_active": False, "url": None, "elapsed": 0, "is_paused": False}) try: is_paused = video_data.get("is_paused", False) if is_paused: elapsed = video_data.get("elapsed_at_pause", 0) else: start_time = datetime.fromisoformat(video_data["started_at"]) elapsed = (datetime.now(timezone.utc) - start_time).total_seconds() return jsonify( { "url": video_data["url"], "elapsed": max(0, int(elapsed)), "is_paused": is_paused, "is_active": video_data.get("is_active", True), } ) except Exception: return jsonify({"is_active": False, "url": None, "elapsed": 0, "is_paused": False}) @watchparty_bp.route("/watchparty//video/clear", methods=["POST"]) def clear_watchparty_video(room: str) -> Response: room = room.strip() video_state.pop(room, None) return jsonify({"status": "cleared"}) @watchparty_bp.route("/watchparty//video/pause", methods=["POST"]) def watchparty_pause_video(room: str) -> Response: room = room.strip() state = video_state.get(room) if not state or state.get("is_paused"): return jsonify({"status": "ignored"}) start_time = datetime.fromisoformat(state["started_at"]) elapsed = (datetime.now(timezone.utc) - start_time).total_seconds() state["is_paused"] = True state["elapsed_at_pause"] = max(0, int(elapsed)) return jsonify({"status": "paused"}) @watchparty_bp.route("/watchparty//video/resume", methods=["POST"]) def watchparty_resume_video(room: str) -> Response: room = room.strip() state = video_state.get(room) if not state or not state.get("is_paused"): return jsonify({"status": "ignored"}) elapsed = state.get("elapsed_at_pause", 0) new_start_timestamp = datetime.now(timezone.utc).timestamp() - elapsed state["started_at"] = datetime.fromtimestamp(new_start_timestamp, timezone.utc).isoformat() state["is_paused"] = False state.pop("elapsed_at_pause", None) return jsonify({"status": "resumed"}) @watchparty_bp.route("/watchparty//video/toggle", methods=["POST"]) def watchparty_toggle_video(room: str) -> Response: room = room.strip() data: Dict[str, Any] = request.get_json() or {} state = video_state.setdefault(room, {}) if "is_active" in data: state["is_active"] = bool(data["is_active"]) else: state["is_active"] = not state.get("is_active", False) return jsonify({"status": "toggled", "is_active": state["is_active"]})