modularisierung von app.py und app.js - erster versuch
This commit is contained in:
@@ -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 []
|
||||
@@ -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")
|
||||
Reference in New Issue
Block a user