""" Kiosk-Blueprint für das 3D-Druck-Management-System Dieses Modul enthält alle Routen und Funktionen für den Kiosk-Modus. """ from flask import Blueprint, jsonify, request, redirect, url_for from flask_login import login_required, current_user, logout_user from werkzeug.security import generate_password_hash from models import User, SystemLog, get_db_session from utils.logging_config import get_logger from datetime import datetime import os import subprocess import threading import time # Blueprint erstellen kiosk_blueprint = Blueprint('kiosk', __name__, url_prefix='/api/kiosk') # Logger initialisieren kiosk_logger = get_logger("kiosk") # Kiosk-Status kiosk_status = { "active": False, "user_id": None, "start_time": None, "countdown_active": False, "countdown_minutes": 0, "countdown_start": None } @kiosk_blueprint.route('/status', methods=['GET']) def get_status(): """Gibt den aktuellen Kiosk-Status zurück""" try: # Berechne verbleibende Zeit wenn Countdown aktiv remaining_time = 0 if kiosk_status["countdown_active"] and kiosk_status["countdown_start"]: elapsed = (datetime.now() - kiosk_status["countdown_start"]).total_seconds() total_seconds = kiosk_status["countdown_minutes"] * 60 remaining_time = max(0, total_seconds - elapsed) return jsonify({ "active": kiosk_status["active"], "user_id": kiosk_status["user_id"], "start_time": kiosk_status["start_time"].isoformat() if kiosk_status["start_time"] else None, "countdown_active": kiosk_status["countdown_active"], "countdown_minutes": kiosk_status["countdown_minutes"], "remaining_seconds": int(remaining_time) }) except Exception as e: kiosk_logger.error(f"Fehler beim Abrufen des Kiosk-Status: {str(e)}") return jsonify({"error": "Fehler beim Abrufen des Status"}), 500 @kiosk_blueprint.route('/deactivate', methods=['POST']) def deactivate(): """ Deaktiviert den Kiosk-Modus Diese Route kann sowohl von angemeldeten Benutzern als auch ohne Anmeldung aufgerufen werden (für den Force-Logout). """ try: kiosk_logger.info("Kiosk-Modus wird deaktiviert") # SystemLog erstellen with get_db_session() as db_session: user_id = current_user.id if current_user.is_authenticated else None SystemLog.log_system_event( level="INFO", message="Kiosk-Modus deaktiviert", module="kiosk", user_id=user_id ) db_session.commit() # Benutzer abmelden wenn angemeldet if current_user.is_authenticated: logout_user() # Kiosk-Status zurücksetzen kiosk_status.update({ "active": False, "user_id": None, "start_time": None, "countdown_active": False, "countdown_minutes": 0, "countdown_start": None }) return jsonify({ "success": True, "message": "Kiosk-Modus wurde deaktiviert" }) except Exception as e: kiosk_logger.error(f"Fehler beim Deaktivieren des Kiosk-Modus: {str(e)}") return jsonify({ "error": "Fehler beim Deaktivieren des Kiosk-Modus" }), 500 @kiosk_blueprint.route('/activate', methods=['POST']) @login_required def activate(): """Aktiviert den Kiosk-Modus für einen temporären Benutzer""" try: if not current_user.is_admin: return jsonify({"error": "Nur Administratoren können den Kiosk-Modus aktivieren"}), 403 data = request.get_json() or {} countdown_minutes = data.get('countdown_minutes', 30) # Kiosk-Benutzer erstellen oder aktualisieren with get_db_session() as db_session: kiosk_user = db_session.query(User).filter_by(username="kiosk").first() if not kiosk_user: # Neuen Kiosk-Benutzer erstellen kiosk_user = User( username="kiosk", email="kiosk@local", name="Kiosk-Benutzer", role="user" ) kiosk_user.set_password(generate_password_hash("kiosk_temp_password")) db_session.add(kiosk_user) db_session.commit() # Kiosk-Status aktivieren kiosk_status.update({ "active": True, "user_id": kiosk_user.id, "start_time": datetime.now(), "countdown_active": True, "countdown_minutes": countdown_minutes, "countdown_start": datetime.now() }) # SystemLog erstellen SystemLog.log_system_event( level="INFO", message=f"Kiosk-Modus aktiviert für {countdown_minutes} Minuten", module="kiosk", user_id=current_user.id ) db_session.commit() kiosk_logger.info(f"Kiosk-Modus aktiviert für {countdown_minutes} Minuten") return jsonify({ "success": True, "message": f"Kiosk-Modus wurde für {countdown_minutes} Minuten aktiviert", "kiosk_user_id": kiosk_user.id }) except Exception as e: kiosk_logger.error(f"Fehler beim Aktivieren des Kiosk-Modus: {str(e)}") return jsonify({"error": "Fehler beim Aktivieren des Kiosk-Modus"}), 500 @kiosk_blueprint.route('/restart', methods=['POST']) def restart_system(): """ Startet das System neu (nur für Kiosk-Modus). Diese Route ist öffentlich zugänglich für den Kiosk-Neustart. """ try: kiosk_logger.warning("System-Neustart wird vom Kiosk-Modus ausgelöst") # SystemLog erstellen with get_db_session() as db_session: SystemLog.log_system_event( level="WARNING", message="System-Neustart vom Kiosk-Modus ausgelöst", module="kiosk" ) db_session.commit() # Neustart in separatem Thread nach kurzer Verzögerung def delayed_restart(): time.sleep(2) try: if os.name == 'nt': # Windows subprocess.run(["shutdown", "/r", "/t", "0"], check=True) else: # Linux/Unix subprocess.run(["sudo", "reboot"], check=True) except Exception as e: kiosk_logger.error(f"Fehler beim System-Neustart: {str(e)}") restart_thread = threading.Thread(target=delayed_restart) restart_thread.daemon = True restart_thread.start() return jsonify({ "success": True, "message": "System wird in Kürze neu gestartet" }) except Exception as e: kiosk_logger.error(f"Fehler beim System-Neustart: {str(e)}") return jsonify({"error": "Fehler beim System-Neustart"}), 500