""" Admin Routes - Erweiterte Admin-Funktionen für das Reservierungssystem """ import os import json from datetime import datetime, timedelta from functools import wraps from flask import Blueprint, request, jsonify, session from database import get_db from auth import require_auth admin_bp = Blueprint('admin_extended', __name__, url_prefix='/api/admin') def get_config_safe(db, key, default=''): """Config-Wert sicher abrufen""" try: result = db.execute('SELECT value FROM config WHERE key = ?', (key,)).fetchone() return result['value'] if result else default except: return default def set_config_safe(db, key, value): """Config-Wert sicher speichern""" try: db.execute(''' INSERT INTO config (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at ''', (key, value, datetime.now().isoformat())) return True except: return False # ============================================================================= # SMTP KONFIGURATION # ============================================================================= @admin_bp.route('/smtp', methods=['GET', 'POST']) def smtp_config(): """SMTP-Konfiguration lesen oder speichern""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 if request.method == 'GET': try: with get_db() as db: return jsonify({ 'host': get_config_safe(db, 'smtp_host', ''), 'port': int(get_config_safe(db, 'smtp_port', '587') or 587), 'user': get_config_safe(db, 'smtp_user', ''), 'password': '', # Nie zurückgeben 'from_email': get_config_safe(db, 'smtp_from', ''), 'from_name': get_config_safe(db, 'smtp_from_name', 'Reservierungssystem'), 'security': get_config_safe(db, 'smtp_security', 'tls'), 'enabled': get_config_safe(db, 'smtp_enabled', 'false') == 'true' }) except Exception as e: return jsonify({ 'host': '', 'port': 587, 'user': '', 'password': '', 'from_email': '', 'from_name': 'Reservierungssystem', 'security': 'tls', 'enabled': False }) # POST data = request.get_json() try: with get_db() as db: set_config_safe(db, 'smtp_host', data.get('host', '')) set_config_safe(db, 'smtp_port', str(data.get('port', 587))) set_config_safe(db, 'smtp_user', data.get('user', '')) set_config_safe(db, 'smtp_from', data.get('from_email', '')) set_config_safe(db, 'smtp_from_name', data.get('from_name', 'Reservierungssystem')) set_config_safe(db, 'smtp_security', data.get('security', 'tls')) set_config_safe(db, 'smtp_enabled', 'true' if data.get('enabled') else 'false') if data.get('password'): set_config_safe(db, 'smtp_password', data.get('password')) db.commit() return jsonify({"message": "SMTP-Konfiguration gespeichert"}) except Exception as e: return jsonify({"error": f"Fehler: {str(e)}"}), 500 @admin_bp.route('/smtp/test', methods=['POST']) def test_smtp_endpoint(): """SMTP-Verbindung testen""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 try: import smtplib with get_db() as db: host = get_config_safe(db, 'smtp_host', '') port = int(get_config_safe(db, 'smtp_port', '587') or 587) user = get_config_safe(db, 'smtp_user', '') password = get_config_safe(db, 'smtp_password', '') security = get_config_safe(db, 'smtp_security', 'tls') if not all([host, user, password]): return jsonify({"error": "SMTP-Konfiguration unvollständig"}), 400 if security == 'ssl': server = smtplib.SMTP_SSL(host, port) else: server = smtplib.SMTP(host, port) if security == 'tls': server.starttls() server.login(user, password) server.quit() return jsonify({"message": "SMTP-Verbindung erfolgreich"}) except Exception as e: return jsonify({"error": f"SMTP-Fehler: {str(e)}"}), 500 # ============================================================================= # LLM KONFIGURATION (Ollama) # ============================================================================= @admin_bp.route('/llm-config', methods=['GET', 'POST']) def llm_config_endpoint(): """LLM-Konfiguration lesen oder speichern""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 if request.method == 'GET': try: with get_db() as db: return jsonify({ 'enabled': get_config_safe(db, 'llm_enabled', 'false') == 'true', 'url': get_config_safe(db, 'ollama_url', 'http://localhost:11434'), 'model': get_config_safe(db, 'llm_model', 'llama2'), 'temperature': float(get_config_safe(db, 'llm_temperature', '0.7') or 0.7), 'max_tokens': int(get_config_safe(db, 'llm_max_tokens', '500') or 500), 'auto_reply': get_config_safe(db, 'llm_auto_reply', 'false') == 'true' }) except: return jsonify({ 'enabled': False, 'url': 'http://localhost:11434', 'model': 'llama2', 'temperature': 0.7, 'max_tokens': 500, 'auto_reply': False }) data = request.get_json() try: with get_db() as db: set_config_safe(db, 'ollama_url', data.get('url', 'http://localhost:11434')) set_config_safe(db, 'llm_model', data.get('model', 'llama2')) set_config_safe(db, 'llm_temperature', str(data.get('temperature', 0.7))) set_config_safe(db, 'llm_max_tokens', str(data.get('max_tokens', 500))) set_config_safe(db, 'llm_enabled', 'true' if data.get('enabled') else 'false') set_config_safe(db, 'llm_auto_reply', 'true' if data.get('auto_reply') else 'false') db.commit() return jsonify({"message": "LLM-Konfiguration gespeichert"}) except Exception as e: return jsonify({"error": f"Fehler: {str(e)}"}), 500 @admin_bp.route('/llm-config/test', methods=['POST']) def test_llm_endpoint(): """Ollama-Verbindung testen""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 try: import requests with get_db() as db: url = get_config_safe(db, 'ollama_url', 'http://localhost:11434') response = requests.get(f"{url}/api/tags", timeout=5) if response.status_code == 200: models = response.json().get('models', []) return jsonify({ "message": "Ollama-Verbindung erfolgreich", "available_models": [m.get('name') for m in models[:5]] }) else: return jsonify({"error": f"Ollama Fehler: {response.status_code}"}), 500 except Exception as e: return jsonify({"error": f"Verbindungsfehler: {str(e)}"}), 500 # ============================================================================= # RÄUME UND BEREICHE # ============================================================================= @admin_bp.route('/rooms', methods=['GET', 'POST']) def manage_rooms(): """Räume verwalten""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 if request.method == 'GET': try: with get_db() as db: rooms = db.execute('SELECT * FROM rooms').fetchall() result = [] for room in rooms: room_dict = dict(room) areas = db.execute('SELECT * FROM areas WHERE room_id = ?', (room['id'],)).fetchall() room_dict['areas'] = [dict(a) for a in areas] result.append(room_dict) return jsonify(result) except Exception as e: return jsonify([]) # POST data = request.get_json() try: with get_db() as db: cursor = db.execute( 'INSERT INTO rooms (name, capacity, color) VALUES (?, ?, ?)', (data.get('name'), data.get('capacity', 50), data.get('color', '#3498db')) ) db.commit() return jsonify({"id": cursor.lastrowid, "message": "Raum erstellt"}) except Exception as e: return jsonify({"error": str(e)}), 500 @admin_bp.route('/areas', methods=['POST']) def create_area(): """Bereich erstellen""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 data = request.get_json() try: with get_db() as db: cursor = db.execute( 'INSERT INTO areas (room_id, name) VALUES (?, ?)', (data.get('room_id'), data.get('name')) ) db.commit() return jsonify({"id": cursor.lastrowid, "message": "Bereich erstellt"}) except Exception as e: return jsonify({"error": str(e)}), 500 # ============================================================================= # BLOCKIERTE ZEITEN # ============================================================================= @admin_bp.route('/blocked-times', methods=['GET', 'POST']) def manage_blocked_times(): """Blockierte Zeiten verwalten""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 if request.method == 'GET': try: with get_db() as db: rows = db.execute(''' SELECT b.*, r.name as room_name FROM blocked_times b JOIN rooms r ON b.room_id = r.id WHERE b.date >= ? ORDER BY b.date, b.time_from ''', (datetime.now().date().isoformat(),)).fetchall() return jsonify([dict(r) for r in rows]) except: return jsonify([]) # POST data = request.get_json() try: with get_db() as db: cursor = db.execute(''' INSERT INTO blocked_times (room_id, date, time_from, time_to, reason, created_by) VALUES (?, ?, ?, ?, ?, ?) ''', ( data.get('room_id'), data.get('date'), data.get('time_from'), data.get('time_to'), data.get('reason', ''), 'admin' )) db.commit() return jsonify({"id": cursor.lastrowid, "message": "Zeit blockiert"}) except Exception as e: return jsonify({"error": str(e)}), 500 # ============================================================================= # ÖFFNUNGSZEITEN # ============================================================================= @admin_bp.route('/hours', methods=['GET', 'POST']) def opening_hours(): """Öffnungszeiten verwalten""" if not session.get('user_role') == 'admin': return jsonify({"error": "Unauthorized"}), 401 if request.method == 'GET': try: with get_db() as db: return jsonify({ 'open_hour': int(get_config_safe(db, 'open_hour', '10') or 10), 'close_hour': int(get_config_safe(db, 'close_hour', '23') or 23) }) except: return jsonify({'open_hour': 10, 'close_hour': 23}) # POST data = request.get_json() try: with get_db() as db: set_config_safe(db, 'open_hour', str(data.get('open_hour', 10))) set_config_safe(db, 'close_hour', str(data.get('close_hour', 23))) db.commit() return jsonify({"message": "Öffnungszeiten gespeichert"}) except Exception as e: return jsonify({"error": str(e)}), 500