fixxes over codex

This commit is contained in:
oberon 2026-02-16 20:38:51 +01:00
parent fee6d40b04
commit 37747d0614
5 changed files with 51 additions and 20 deletions

View File

@ -1,11 +1,15 @@
# app/routes/admin.py # app/routes/admin.py
import datetime import os
import json
import logging
from datetime import datetime
from flask import Blueprint, render_template, request, jsonify, redirect, url_for from flask import Blueprint, render_template, request, jsonify, redirect, url_for, current_app
from app.state import current_config from app.state import current_config
from app.utils.helpers import load_configs, load_default_sounds from app.utils.helpers import load_configs, load_default_sounds
admin_bp = Blueprint('admin', __name__) admin_bp = Blueprint('admin', __name__)
logger = logging.getLogger(__name__)
@admin_bp.route('/') @admin_bp.route('/')
def admin(): def admin():
@ -15,7 +19,7 @@ def admin():
@admin_bp.route('/edit/<filename>', methods=['GET', 'POST']) @admin_bp.route('/edit/<filename>', methods=['GET', 'POST'])
def admin_edit_config(filename): def admin_edit_config(filename):
path = os.path.join(app.config['CONFIG_DIR'], filename) path = os.path.join(current_app.config['CONFIG_DIR'], filename)
if request.method == 'POST': if request.method == 'POST':
try: try:
@ -56,7 +60,7 @@ def admin_edit_config(filename):
@admin_bp.route('/delete/<filename>', methods=['POST']) @admin_bp.route('/delete/<filename>', methods=['POST'])
def admin_delete_config(filename): def admin_delete_config(filename):
path = os.path.join(app.config['CONFIG_DIR'], filename) path = os.path.join(current_app.config['CONFIG_DIR'], filename)
if os.path.exists(path): if os.path.exists(path):
try: try:
os.remove(path) os.remove(path)
@ -77,7 +81,7 @@ def admin_logs(date=None):
today = datetime.now().strftime('%Y-%m') # ← Hier definieren! today = datetime.now().strftime('%Y-%m') # ← Hier definieren!
current_month = datetime.now().strftime('%Y-%m') current_month = datetime.now().strftime('%Y-%m')
log_dir = os.path.join(LOG_DIR, today) log_dir = os.path.join(current_app.config['LOG_DIR'], today)
if not os.path.exists(log_dir): if not os.path.exists(log_dir):
return render_template('admin_logs.html', logs="Keine Logs für diesen Tag.", date=date, dates=[], today=today) return render_template('admin_logs.html', logs="Keine Logs für diesen Tag.", date=date, dates=[], today=today)
@ -107,4 +111,4 @@ def admin_logs(date=None):
date=date, date=date,
dates=dates, dates=dates,
today=current_month) today=current_month)
pass pass

View File

@ -15,7 +15,7 @@ logger = logging.getLogger(__name__)
@main_bp.route('/') @main_bp.route('/')
def index(): def index():
configs = load_configs() configs = load_configs(current_app.config['CONFIG_DIR'])
return render_template('index.html', configs=configs) return render_template('index.html', configs=configs)
""" """
@ -67,7 +67,7 @@ def control_page():
return redirect(url_for('main.index')) return redirect(url_for('main.index'))
# Globale Sounds immer laden # Globale Sounds immer laden
global_sounds = load_default_sounds() global_sounds = load_default_sounds(current_app.config['CONFIG_DIR'])
logger.info(f"Steuerseite geladen für Config: {current_config.get('filename', 'unbekannt')} mit {len(current_config.get('channels', []))} Kanälen") logger.info(f"Steuerseite geladen für Config: {current_config.get('filename', 'unbekannt')} mit {len(current_config.get('channels', []))} Kanälen")

View File

@ -3,13 +3,37 @@ import os
import json import json
import logging import logging
try:
# Flask ist optional bei Aufruf außerhalb des App-Contexts fallbacken wir
from flask import current_app
except Exception: # pragma: no cover - nur wenn Flask nicht verfügbar ist
current_app = None
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def load_configs(config_dir='configs'): def _resolve_config_dir(config_dir=None):
"""
Ermittelt den zu nutzenden Config-Pfad:
1) Expliziter Parameter
2) Flask current_app.config['CONFIG_DIR']
3) Fallback: lokaler 'configs' Ordner
"""
if config_dir:
return config_dir
if current_app:
try:
return current_app.config.get('CONFIG_DIR', 'configs')
except Exception:
pass
return 'configs'
def load_configs(config_dir=None):
""" """
Lädt alle .json-Konfigurationsdateien aus dem configs-Ordner, Lädt alle .json-Konfigurationsdateien aus dem configs-Ordner,
außer default_sounds.json (die wird separat geladen). außer default_sounds.json (die wird separat geladen).
""" """
config_dir = _resolve_config_dir(config_dir)
configs = [] configs = []
if not os.path.exists(config_dir): if not os.path.exists(config_dir):
logger.warning(f"Config-Verzeichnis nicht gefunden: {config_dir}") logger.warning(f"Config-Verzeichnis nicht gefunden: {config_dir}")
@ -38,14 +62,14 @@ def load_configs(config_dir='configs'):
return sorted(configs, key=lambda x: x.get('name', '')) return sorted(configs, key=lambda x: x.get('name', ''))
def load_default_sounds(config_dir='configs'): def load_default_sounds(config_dir=None):
""" """
Lädt die globalen Standard-Sounds aus configs/default_sounds.json Lädt die globalen Standard-Sounds aus configs/default_sounds.json
Wird immer geladen, unabhängig von der aktuellen Lok-Konfiguration Wird immer geladen, unabhängig von der aktuellen Lok-Konfiguration
""" """
config_dir = _resolve_config_dir(config_dir)
path = os.path.join(config_dir, 'default_sounds.json') path = os.path.join(config_dir, 'default_sounds.json')
data = json.load(f)
if not os.path.exists(path): if not os.path.exists(path):
logger.info("Keine default_sounds.json gefunden → keine globalen Sounds") logger.info("Keine default_sounds.json gefunden → keine globalen Sounds")
return [] return []

View File

@ -4,11 +4,14 @@ import os
class Config: class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key-change-me' SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key-change-me'
# Alle Pfade **relativ zum Arbeitsverzeichnis** (wo app.py liegt) # Basisverzeichnis des Projekts (absolut, robust gegen anderes CWD)
CONFIG_DIR = 'configs' BASE_DIR = os.path.abspath(os.path.dirname(__file__))
LOG_DIR = 'logs'
SOUNDS_DIR = 'sounds' # Alle Pfade absolut auf Basis des Projekt-Roots
CONFIG_DIR = os.path.join(BASE_DIR, 'configs')
LOG_DIR = os.path.join(BASE_DIR, 'logs')
SOUNDS_DIR = os.path.join(BASE_DIR, 'sounds')
# Optional: absolute Pfade, falls du später Docker o.ä. nutzt # Optional: absolute Pfade, falls du später Docker o.ä. nutzt
# CONFIG_DIR = os.path.join(os.path.dirname(__file__), 'configs') # CONFIG_DIR = os.path.join(os.path.dirname(__file__), 'configs')

View File

@ -13,7 +13,7 @@
<div class="col"> <div class="col">
<div class="card h-100 shadow-sm"> <div class="card h-100 shadow-sm">
{% if cfg.image %} {% if cfg.image %}
<img src="{{ url_for('main.serve_config_file', filename=config.image) }}" <img src="{{ url_for('main.serve_config_file', filename=cfg.image) }}"
class="card-img-top" alt="{{ cfg.name }}" class="card-img-top" alt="{{ cfg.name }}"
style="height: 180px; object-fit: cover;"> style="height: 180px; object-fit: cover;">
{% else %} {% else %}
@ -53,4 +53,4 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}