Files
fcco-Converter/fcco_converter/config.py
T

186 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
fcco-Converter V2 Konfigurationsmodul
Lädt und speichert Anwendungseinstellungen plattformübergreifend.
Verwendet pathlib für alle Pfadoperationen.
"""
import json
import platform
import sys
from pathlib import Path
# ---- Globale App-Informationen (aus config.json) ----
APP_INFO = {
"app_name": "fcco Converter",
"app_version": "2.0.0",
"repo_owner": "public",
"repo_name": "fcco-Converter",
"gitea_api_base": "https://git.joelunger.de/api/v1"
}
def _load_app_info():
try:
# Finde config.json relativ zum Skript oder im PyInstaller Bundle
if getattr(sys, "frozen", False):
base_dir = Path(sys.executable).parent
else:
base_dir = Path(__file__).parent.parent
config_path = base_dir / "config.json"
if config_path.exists():
with open(config_path, "r", encoding="utf-8") as f:
data = json.load(f)
APP_INFO.update(data)
except Exception:
pass
_load_app_info()
# =========================================================================
# Farbschema
# =========================================================================
T = {
"bg": "#000000",
"surface": "#111111",
"elevated": "#1a1a1a",
"card": "#222222",
"input": "#000000",
"accent": "#ffffff",
"accent_h": "#e6e6e6",
"success": "#ffffff",
"success_h": "#e6e6e6",
"warn": "#ffffff",
"error": "#ffffff",
"text": "#ffffff",
"text2": "#b3b3b3",
"muted": "#808080",
"border": "#333333",
"btn2": "#1a1a1a",
"btn2_h": "#333333",
}
# Standardmäßige Export-Kategorien
DEFAULT_EXPORT_PATHS = {
"Gottesdienst": "gottesdienste",
"Hochzeit": "hochzeiten",
"Weissagung": "weissagungen",
"Jugend": "jugend",
}
# Kurze deutsche Wochentagsnamen für Ordnerbenennung
WEEKDAY_SHORT_DE = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
# ---- Audio-Einstellungen: Gültige Werte ----
BITRATE_OPTIONS = ["64", "96", "128", "160", "192", "224", "256", "320"]
SAMPLERATE_OPTIONS = ["Original", "22050", "44100", "48000"]
CHANNEL_OPTIONS = ["Original", "Mono", "Stereo"]
ENCODING_MODE_OPTIONS = ["CBR", "VBR"]
VBR_QUALITY_OPTIONS = [str(i) for i in range(10)] # 0 (beste) bis 9 (schlechteste)
OUTPUT_FORMAT_OPTIONS = ["mp3", "flac", "ogg", "wav"]
def _get_config_dir() -> Path:
"""Gibt das plattformabhängige Konfigurationsverzeichnis zurück."""
system = platform.system()
if system == "Windows":
base = Path.home() / "AppData" / "Roaming"
elif system == "Darwin":
base = Path.home() / "Library" / "Application Support"
else: # Linux / andere
base = Path.home() / ".config"
config_dir = base / "fcco-Converter"
config_dir.mkdir(parents=True, exist_ok=True)
return config_dir
CONFIG_DIR = _get_config_dir()
SETTINGS_FILE = CONFIG_DIR / "settings.json"
HISTORY_FILE = CONFIG_DIR / "history.json"
# ---- Standard-Einstellungen ----
DEFAULT_SETTINGS = {
# Allgemein
"threads": 0, # 0 = auto (alle verfügbaren Kerne)
"appearance_mode": "Dark", # Dark / Light / System
"check_updates_on_start": True,
# Audio & Konvertierung
"audio": {
"output_format": "mp3",
"bitrate": "192", # kbit/s (nur CBR)
"encoding_mode": "CBR", # CBR oder VBR
"vbr_quality": "2", # 0 (beste) bis 9 (schlechteste)
"sample_rate": "Original", # Original, 22050, 44100, 48000
"channels": "Original", # Original, Mono, Stereo
"overwrite_existing": True,
},
# Metadaten
"metadata": {
"artist": "",
"cover": "",
"auto_track_number": True,
"auto_album_from_folder": True,
},
# Export-Pfade
"export_paths": DEFAULT_EXPORT_PATHS.copy(),
}
def _deep_merge(base: dict, override: dict) -> dict:
"""Merged override-Werte in base, ohne fehlende Schlüssel zu verlieren."""
result = base.copy()
for key, value in override.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = _deep_merge(result[key], value)
else:
result[key] = value
return result
def load_settings() -> dict:
"""Lädt die Einstellungen aus der JSON-Datei.
Fehlende Schlüssel werden mit Standardwerten aufgefüllt.
"""
settings = DEFAULT_SETTINGS.copy()
# Deep-copy verschachtelter Dicts
settings["audio"] = DEFAULT_SETTINGS["audio"].copy()
settings["metadata"] = DEFAULT_SETTINGS["metadata"].copy()
settings["export_paths"] = DEFAULT_SETTINGS["export_paths"].copy()
if SETTINGS_FILE.exists():
try:
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
loaded = json.load(f)
settings = _deep_merge(settings, loaded)
except (json.JSONDecodeError, OSError):
pass # Bei fehlerhafter Datei: Standardwerte nutzen
return settings
def save_settings(settings: dict) -> None:
"""Speichert die Einstellungen in die JSON-Datei."""
with open(SETTINGS_FILE, "w", encoding="utf-8") as f:
json.dump(settings, f, indent=2, ensure_ascii=False)
def save_export_history(entry: dict) -> None:
"""Fügt einen Export-Eintrag zur Historie hinzu."""
history = []
if HISTORY_FILE.exists():
try:
with open(HISTORY_FILE, "r", encoding="utf-8") as f:
history = json.load(f)
except (json.JSONDecodeError, OSError):
history = []
history.append(entry)
with open(HISTORY_FILE, "w", encoding="utf-8") as f:
json.dump(history, f, indent=2, ensure_ascii=False)