543 lines
20 KiB
Python
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 |