Projektarbeit-MYP/backend/app_timer_routes.py

543 lines
20 KiB
Python

"""
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/<timer_name>', 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/<timer_name>/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/<timer_name>/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/<timer_name>/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/<timer_name>/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/<timer_name>/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