diff --git a/app/routes/admin.py b/app/routes/admin.py index 827bbbc..1324ec6 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -6,7 +6,7 @@ from datetime import datetime from flask import Blueprint, render_template, request, jsonify, redirect, url_for, current_app from app.state import current_config -from app.utils.helpers import load_configs, load_default_sounds, load_soundboard_configs +from app.utils.helpers import load_configs, load_default_sounds, load_soundboard_configs, write_default_theme admin_bp = Blueprint('admin', __name__) logger = logging.getLogger(__name__) @@ -210,8 +210,23 @@ def admin_create_theme(): } with open(path, 'w', encoding='utf-8') as f: json.dump(template, f, ensure_ascii=False, indent=2) - logger.info(f"Neues Theme angelegt: {os.path.relpath(path, base_dir)}") - return jsonify({"success": True, "path": os.path.relpath(path, base_dir)}) + logger.info(f"Neues Theme angelegt: {os.path.relpath(path, base_dir)}") + return jsonify({"success": True, "path": os.path.relpath(path, base_dir)}) + + +@admin_bp.route('/set_default_theme', methods=['POST']) +def admin_set_default_theme(): + data = request.get_json(force=True, silent=True) or {} + filename = data.get('filename') + if not filename: + return jsonify({"success": False, "message": "filename fehlt"}), 400 + try: + write_default_theme(current_app.config['DEFAULT_THEME_FILE'], filename) + logger.info(f"Default-Theme gesetzt: {filename}") + return jsonify({"success": True, "filename": filename}) + except Exception as e: + logger.exception("Default-Theme setzen fehlgeschlagen") + return jsonify({"success": False, "message": str(e)}), 500 except Exception as e: logger.exception("create_theme fehlgeschlagen") return jsonify({"success": False, "message": str(e)}), 500 diff --git a/app/routes/api.py b/app/routes/api.py index 8327d1f..0e1835e 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -11,7 +11,7 @@ from flask import Blueprint, jsonify, request, current_app import app.state as state from app.bluetooth.manager import MouldKing, advertiser, tracer -from app.utils.helpers import load_default_sounds, load_soundboard_configs, load_soundboard_config +from app.utils.helpers import load_default_sounds, load_soundboard_configs, load_soundboard_config, read_default_theme from config import Config logger = logging.getLogger(__name__) @@ -451,6 +451,26 @@ def api_soundboard_load(): return jsonify({"success": False, "message": str(e)}), 500 +@api_bp.route('/soundboard/load_default', methods=['POST']) +def api_soundboard_load_default(): + # Lädt das Standard-Theme, falls gesetzt und noch kein Soundboard aktiv ist + try: + if state.current_soundboard: + return jsonify({"success": True, "soundboard": state.current_soundboard, "already_loaded": True}) + default_file = read_default_theme(Config.DEFAULT_THEME_FILE) + if not default_file: + return jsonify({"success": False, "message": "Kein Standard-Theme gesetzt"}), 404 + sb = load_soundboard_config(default_file, + current_app.config['SOUNDBOARD_CONFIG_DIR'], + current_app.config['SOUNDS_DIR']) + state.current_soundboard = sb + logger.info(f"Standard-Soundboard geladen: {default_file}") + return jsonify({"success": True, "soundboard": sb, "default_loaded": True}) + except Exception as e: + logger.exception("Standard-Soundboard laden fehlgeschlagen") + return jsonify({"success": False, "message": str(e)}), 500 + + @api_bp.route('/soundboard/play_random', methods=['POST']) def api_soundboard_play_random(): if state.current_soundboard is None: diff --git a/app/utils/helpers.py b/app/utils/helpers.py index 22262d2..62c0743 100644 --- a/app/utils/helpers.py +++ b/app/utils/helpers.py @@ -144,3 +144,20 @@ def load_soundboard_config(filename, config_dir, sounds_dir=None): for item in data[key]: item.setdefault('base_path', base_sound_dir) return data + + +def read_default_theme(path): + try: + if not os.path.exists(path): + return None + with open(path, 'r', encoding='utf-8') as f: + val = f.read().strip() + return val or None + except Exception: + return None + + +def write_default_theme(path, filename): + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, 'w', encoding='utf-8') as f: + f.write(filename) diff --git a/config.py b/config.py index 731bdb0..b5a89cc 100644 --- a/config.py +++ b/config.py @@ -13,6 +13,7 @@ class Config: LOG_DIR = os.path.join(BASE_DIR, 'logs') SOUNDS_DIR = os.path.join(BASE_DIR, 'sounds') SOUNDBOARD_CONFIG_DIR = os.path.join(BASE_DIR, 'soundboards') + DEFAULT_THEME_FILE = os.path.join(SOUNDBOARD_CONFIG_DIR, 'default_theme.txt') # Audio-Parameter (für pygame.mixer) AUDIO_FREQ = 44100 diff --git a/templates/admin.html b/templates/admin.html index e3ba454..852b618 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -84,6 +84,10 @@ class="btn btn-sm btn-primary"> Bearbeiten + {% endfor %} @@ -252,5 +256,26 @@ alert('Fehler: ' + e.message); } }); + + // Standard-Theme setzen + document.querySelectorAll('.set-default-theme-btn').forEach(btn => { + btn.addEventListener('click', async () => { + const filename = btn.dataset.filename; + try { + const res = await fetch('/admin/set_default_theme', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ filename }) + }); + const text = await res.text(); + let json; + try { json = JSON.parse(text); } catch (_) { throw new Error('Serverantwort ist kein JSON:\n'+text); } + if (!json.success) throw new Error(json.message || 'Fehler'); + alert('Standard-Theme gesetzt: ' + filename); + } catch (e) { + alert('Fehler: ' + e.message); + } + }); + }); {% endblock %} diff --git a/templates/soundboard.html b/templates/soundboard.html index 237efb1..219e8a7 100644 --- a/templates/soundboard.html +++ b/templates/soundboard.html @@ -288,14 +288,18 @@ // Reihenfolge: Status prüfen, dann ggf. Theme laden (async () => { await updateAutoStatus(); + // Wenn noch kein Theme aktiv ist, versuche Standard-Theme zu laden + const statusRes = await fetch('/api/soundboard/status'); + const statusData = await statusRes.json(); + if (!statusData.active && !statusData.current_theme) { + await fetch('/api/soundboard/load_default', { method: 'POST' }); + } if (selectEl && selectEl.value) { - // Wenn bereits ein Theme aktiv ist, nicht erneut laden (würde Auto stoppen) - const statusRes = await fetch('/api/soundboard/status'); - const statusData = await statusRes.json(); - if (!statusData.active || statusData.current_theme !== selectEl.value) { + const statusRes2 = await fetch('/api/soundboard/status'); + const statusData2 = await statusRes2.json(); + if (!statusData2.active || statusData2.current_theme !== selectEl.value) { loadSoundboard(selectEl.value); } else { - // Theme-Daten nachladen ohne Auto zu stoppen const cur = await fetch('/api/soundboard/current'); const curData = await cur.json(); if (curData.soundboard) {