""" Timer-API-Routen für Flask-App Diese Datei enthält alle API-Endpunkte für das Timer-System. Die Routen werden in die Haupt-app.py eingebunden. Autor: System Erstellt: 2025 """ # Timer-Manager importieren für API-Routen try: from utils.timer_manager import ( get_timer_manager, init_timer_manager, shutdown_timer_manager, TimerType, ForceQuitAction, TimerStatus, create_kiosk_timer, create_session_timer, start_timer, pause_timer, stop_timer, reset_timer, extend_timer, get_timer_status, update_session_activity ) TIMER_MANAGER_AVAILABLE = True except ImportError as e: print(f"❌ Timer-Manager konnte nicht geladen werden: {e}") TIMER_MANAGER_AVAILABLE = False def register_timer_routes(app, login_required, admin_required, current_user, jsonify, request, url_for, logout_user, app_logger): """ Registriert alle Timer-API-Routen bei der Flask-App. Args: app: Flask-App-Instanz login_required: Login-Required-Decorator admin_required: Admin-Required-Decorator current_user: Current-User-Objekt jsonify: Flask jsonify-Funktion request: Flask request-Objekt url_for: Flask url_for-Funktion logout_user: Flask-Login logout_user-Funktion app_logger: Logger-Instanz """ @app.route('/api/timers', methods=['GET']) @login_required def get_all_timers(): """ Holt alle Timer für den aktuellen Benutzer oder alle Timer (Admin). """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: timer_manager = get_timer_manager() if current_user.is_admin: # Admin kann alle Timer sehen timers = timer_manager.get_all_timers() else: # Normale Benutzer sehen nur ihre eigenen Timer user_timers = timer_manager.get_timers_by_type(TimerType.SESSION) kiosk_timers = timer_manager.get_timers_by_type(TimerType.KIOSK) # Filtere nur Timer die dem aktuellen Benutzer gehören timers = [] for timer in user_timers: if timer.context_id == current_user.id: timers.append(timer) # Kiosk-Timer sind für alle sichtbar timers.extend(kiosk_timers) timer_data = [timer.to_dict() for timer in timers] return jsonify({ "success": True, "data": timer_data, "count": len(timer_data) }) except Exception as e: app_logger.error(f"Fehler beim Laden der Timer: {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Laden der Timer" }), 500 @app.route('/api/timers/', methods=['GET']) @login_required def get_timer_status_api(timer_name): """ Holt den Status eines bestimmten Timers. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: timer_status = get_timer_status(timer_name) if not timer_status: return jsonify({ "success": False, "error": "Timer nicht gefunden" }), 404 # Berechtigung prüfen timer = get_timer_manager().get_timer(timer_name) if timer and not current_user.is_admin: # Session-Timer nur für Besitzer if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für diesen Timer" }), 403 return jsonify({ "success": True, "data": timer_status }) except Exception as e: app_logger.error(f"Fehler beim Laden des Timer-Status für '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Laden des Timer-Status" }), 500 @app.route('/api/timers//start', methods=['POST']) @login_required def start_timer_api(timer_name): """ Startet einen Timer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: # Berechtigung prüfen timer = get_timer_manager().get_timer(timer_name) if timer and not current_user.is_admin: # Session-Timer nur für Besitzer if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für diesen Timer" }), 403 success = start_timer(timer_name) if success: app_logger.info(f"Timer '{timer_name}' von Benutzer {current_user.id} gestartet") return jsonify({ "success": True, "message": f"Timer '{timer_name}' gestartet" }) else: return jsonify({ "success": False, "error": "Timer konnte nicht gestartet werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Starten des Timers '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Starten des Timers" }), 500 @app.route('/api/timers//pause', methods=['POST']) @login_required def pause_timer_api(timer_name): """ Pausiert einen Timer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: # Berechtigung prüfen timer = get_timer_manager().get_timer(timer_name) if timer and not current_user.is_admin: # Session-Timer nur für Besitzer if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für diesen Timer" }), 403 success = pause_timer(timer_name) if success: app_logger.info(f"Timer '{timer_name}' von Benutzer {current_user.id} pausiert") return jsonify({ "success": True, "message": f"Timer '{timer_name}' pausiert" }) else: return jsonify({ "success": False, "error": "Timer konnte nicht pausiert werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Pausieren des Timers '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Pausieren des Timers" }), 500 @app.route('/api/timers//stop', methods=['POST']) @login_required def stop_timer_api(timer_name): """ Stoppt einen Timer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: # Berechtigung prüfen timer = get_timer_manager().get_timer(timer_name) if timer and not current_user.is_admin: # Session-Timer nur für Besitzer if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für diesen Timer" }), 403 success = stop_timer(timer_name) if success: app_logger.info(f"Timer '{timer_name}' von Benutzer {current_user.id} gestoppt") return jsonify({ "success": True, "message": f"Timer '{timer_name}' gestoppt" }) else: return jsonify({ "success": False, "error": "Timer konnte nicht gestoppt werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Stoppen des Timers '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Stoppen des Timers" }), 500 @app.route('/api/timers//extend', methods=['POST']) @login_required def extend_timer_api(timer_name): """ Verlängert einen Timer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: data = request.get_json() or {} additional_seconds = data.get('seconds', 300) # Standard: 5 Minuten # Berechtigung prüfen timer = get_timer_manager().get_timer(timer_name) if timer and not current_user.is_admin: # Session-Timer nur für Besitzer if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für diesen Timer" }), 403 success = extend_timer(timer_name, additional_seconds) if success: app_logger.info(f"Timer '{timer_name}' von Benutzer {current_user.id} um {additional_seconds} Sekunden verlängert") return jsonify({ "success": True, "message": f"Timer '{timer_name}' um {additional_seconds // 60} Minuten verlängert" }) else: return jsonify({ "success": False, "error": "Timer konnte nicht verlängert werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Verlängern des Timers '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Verlängern des Timers" }), 500 @app.route('/api/timers//force-quit', methods=['POST']) @login_required def force_quit_timer_api(timer_name): """ Führt Force-Quit für einen Timer aus. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: timer = get_timer_manager().get_timer(timer_name) if not timer: return jsonify({ "success": False, "error": "Timer nicht gefunden" }), 404 # Berechtigung prüfen - Force-Quit nur für Admin oder Besitzer if not current_user.is_admin: if timer.timer_type == TimerType.SESSION.value and timer.context_id != current_user.id: return jsonify({ "success": False, "error": "Keine Berechtigung für Force-Quit" }), 403 success = timer.force_quit_execute() if success: app_logger.warning(f"Force-Quit für Timer '{timer_name}' von Benutzer {current_user.id} ausgeführt") # Führe entsprechende Aktion aus if timer.force_quit_action == ForceQuitAction.LOGOUT.value: # Session beenden logout_user() return jsonify({ "success": True, "message": "Force-Quit ausgeführt - Session beendet", "action": "logout", "redirect_url": url_for("login") }) else: return jsonify({ "success": True, "message": f"Force-Quit für Timer '{timer_name}' ausgeführt", "action": timer.force_quit_action }) else: return jsonify({ "success": False, "error": "Force-Quit konnte nicht ausgeführt werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Force-Quit des Timers '{timer_name}': {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Force-Quit" }), 500 @app.route('/api/timers/kiosk/create', methods=['POST']) @login_required @admin_required def create_kiosk_timer_api(): """ Erstellt einen Kiosk-Timer (nur Admin). """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: data = request.get_json() or {} duration_minutes = data.get('duration_minutes', 30) auto_start = data.get('auto_start', True) timer = create_kiosk_timer(duration_minutes, auto_start) if timer: app_logger.info(f"Kiosk-Timer ({duration_minutes} Min) von Admin {current_user.id} erstellt") return jsonify({ "success": True, "message": f"Kiosk-Timer für {duration_minutes} Minuten erstellt", "data": timer.to_dict() }) else: return jsonify({ "success": False, "error": "Kiosk-Timer konnte nicht erstellt werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Erstellen des Kiosk-Timers: {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Erstellen des Kiosk-Timers" }), 500 @app.route('/api/timers/session/create', methods=['POST']) @login_required def create_session_timer_api(): """ Erstellt einen Session-Timer für den aktuellen Benutzer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: data = request.get_json() or {} duration_minutes = data.get('duration_minutes', 120) timer = create_session_timer(current_user.id, duration_minutes) if timer: app_logger.info(f"Session-Timer ({duration_minutes} Min) für Benutzer {current_user.id} erstellt") return jsonify({ "success": True, "message": f"Session-Timer für {duration_minutes} Minuten erstellt", "data": timer.to_dict() }) else: return jsonify({ "success": False, "error": "Session-Timer konnte nicht erstellt werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Erstellen des Session-Timers: {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Erstellen des Session-Timers" }), 500 @app.route('/api/timers/session/activity', methods=['POST']) @login_required def update_session_activity_api(): """ Aktualisiert die Session-Aktivität für den aktuellen Benutzer. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: success = update_session_activity(current_user.id) if success: return jsonify({ "success": True, "message": "Session-Aktivität aktualisiert" }) else: return jsonify({ "success": False, "error": "Session-Aktivität konnte nicht aktualisiert werden" }), 500 except Exception as e: app_logger.error(f"Fehler beim Aktualisieren der Session-Aktivität: {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Aktualisieren der Session-Aktivität" }), 500 @app.route('/api/timers/status', methods=['GET']) @login_required def get_timer_status_overview(): """ Gibt eine Übersicht über alle Timer-Status zurück. """ if not TIMER_MANAGER_AVAILABLE: return jsonify({ "success": False, "error": "Timer-System nicht verfügbar" }), 503 try: timer_manager = get_timer_manager() # Verschiedene Timer-Kategorien holen all_timers = timer_manager.get_all_timers() running_timers = timer_manager.get_running_timers() # Statistiken berechnen stats = { "total_timers": len(all_timers), "running_timers": len(running_timers), "kiosk_timers": len([t for t in all_timers if t.timer_type == TimerType.KIOSK.value]), "session_timers": len([t for t in all_timers if t.timer_type == TimerType.SESSION.value]), "user_session_timer": None } # Aktueller Benutzer-Session-Timer user_timer_name = f"session_{current_user.id}" user_timer = timer_manager.get_timer(user_timer_name) if user_timer: stats["user_session_timer"] = user_timer.to_dict() # Laufende Timer-Details running_timer_details = [] for timer in running_timers: timer_dict = timer.to_dict() # Nur Timer anzeigen die der Benutzer sehen darf if current_user.is_admin or timer.timer_type == TimerType.KIOSK.value or timer.context_id == current_user.id: running_timer_details.append(timer_dict) return jsonify({ "success": True, "data": { "stats": stats, "running_timers": running_timer_details } }) except Exception as e: app_logger.error(f"Fehler beim Laden der Timer-Status-Übersicht: {str(e)}") return jsonify({ "success": False, "error": "Fehler beim Laden der Timer-Status-Übersicht" }), 500 # Rückgabe der verfügbaren Timer-Manager-Instanz für weitere Verwendung return get_timer_manager() if TIMER_MANAGER_AVAILABLE else None