modularisierung von app.py und app.js - erster versuch

This commit is contained in:
2026-02-16 13:57:57 +01:00
parent f6fba252e4
commit 174e64e480
17 changed files with 1341 additions and 629 deletions
View File
+58
View File
@@ -0,0 +1,58 @@
# app/utils/helpers.py
import os
import json
import logging
logger = logging.getLogger(__name__)
def load_configs(config_dir='configs'):
"""
Lädt alle .json-Konfigurationsdateien aus dem configs-Ordner,
außer default_sounds.json (die wird separat geladen).
"""
configs = []
if not os.path.exists(config_dir):
logger.warning(f"Config-Verzeichnis nicht gefunden: {config_dir}")
return configs
for filename in os.listdir(config_dir):
if filename.lower().endswith('.json') and filename != 'default_sounds.json':
path = os.path.join(config_dir, filename)
try:
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
data['filename'] = filename
data.setdefault('name', filename.replace('.json', '').replace('_', ' ').title())
configs.append(data)
except json.JSONDecodeError as e:
logger.error(f"Ungültiges JSON in {filename}: {e}")
except Exception as e:
logger.error(f"Fehler beim Laden von {filename}: {e}")
return sorted(configs, key=lambda x: x.get('name', ''))
def load_default_sounds(config_dir='configs'):
"""
Lädt die globalen Standard-Sounds aus configs/default_sounds.json
Wird immer geladen, unabhängig von der aktuellen Lok-Konfiguration
"""
path = os.path.join(config_dir, 'default_sounds.json')
if not os.path.exists(path):
logger.info("Keine default_sounds.json gefunden → keine globalen Sounds")
return []
try:
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
# Flexibel: entweder 'global_sounds' oder direkt 'sounds'
sounds = data.get('global_sounds', data.get('sounds', []))
logger.info(f"Globale Default-Sounds geladen: {len(sounds)} Einträge")
return sounds
except json.JSONDecodeError as e:
logger.error(f"Ungültiges JSON in default_sounds.json: {e}")
return []
except Exception as e:
logger.error(f"Fehler beim Laden default_sounds.json: {e}")
return []
+87
View File
@@ -0,0 +1,87 @@
# app/utils/logging.py
import logging
import os
import shutil
from logging.handlers import TimedRotatingFileHandler
from datetime import datetime, timedelta
LOG_DIR = app.config['LOG_DIR']
os.makedirs(LOG_DIR, exist_ok=True)
def cleanup_old_log_dirs(max_age_days=90):
"""
Löscht Monatsordner in logs/, die älter als max_age_days sind.
Beispiel: logs/2025-11/ wird gelöscht, wenn älter als 90 Tage.
"""
if not os.path.exists(LOG_DIR):
return
cutoff_date = datetime.now() - timedelta(days=max_age_days)
cutoff_str = cutoff_date.strftime('%Y-%m')
deleted = 0
for subdir in os.listdir(LOG_DIR):
subdir_path = os.path.join(LOG_DIR, subdir)
if os.path.isdir(subdir_path):
try:
subdir_date = datetime.strptime(subdir, '%Y-%m')
if subdir_date < cutoff_date:
shutil.rmtree(subdir_path)
deleted += 1
logger.info(f"Alten Log-Ordner gelöscht: {subdir_path}")
except ValueError:
# Kein gültiges Datumsformat → überspringen
continue
except Exception as e:
logger.error(f"Fehler beim Löschen von {subdir_path}: {e}")
if deleted > 0:
logger.info(f"Insgesamt {deleted} alte Log-Ordner bereinigt")
else:
logger.debug("Keine alten Log-Ordner zum Bereinigen gefunden")
def setup_logging(app):
"""
Richtet das Logging ein: tägliche Dateien in Unterordnern + Trennung info/error.
Ruft auch einmalig cleanup auf.
"""
# Cleanup beim Start
cleanup_old_log_dirs(90)
today = datetime.now().strftime('%Y-%m')
subdir = os.path.join(LOG_DIR, today)
os.makedirs(subdir, exist_ok=True)
base = os.path.join(subdir, datetime.now().strftime('%d'))
# Info-Handler
info_handler = logging.FileHandler(f"{base}-info.log")
info_handler.setLevel(logging.INFO)
info_handler.setFormatter(logging.Formatter(
'%(asctime)s | %(levelname)-8s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
))
# Error-Handler
error_handler = logging.FileHandler(f"{base}-error.log")
error_handler.setLevel(logging.WARNING)
error_handler.setFormatter(logging.Formatter(
'%(asctime)s | %(levelname)-8s | %(message)s\n%(pathname)s:%(lineno)d\n',
datefmt='%Y-%m-%d %H:%M:%S'
))
# Root-Logger konfigurieren
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.handlers.clear()
logger.addHandler(info_handler)
logger.addHandler(error_handler)
# Konsole
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(info_handler.formatter)
logger.addHandler(console)
logger.info("Logging eingerichtet tägliche Trennung info/error")
logger.info(f"Logs heute: {base}-info.log / {base}-error.log")