mirror of
https://github.com/darkzoul5/YoutubePlaylistSync.git
synced 2026-09-22 06:12:21 +03:00
refactor: unified settings for cli and gui
This commit is contained in:
@@ -24,11 +24,45 @@ DEFAULT_CONFIG: Dict[str, Any] = {
|
||||
}
|
||||
|
||||
|
||||
def load_config(path: Path) -> Dict[str, Any]:
|
||||
"""Load configuration from a JSON file."""
|
||||
try:
|
||||
raw = json.loads(path.read_text(encoding="utf-8"))
|
||||
if not isinstance(raw, dict):
|
||||
raise ValueError("config root must be a JSON object")
|
||||
return raw
|
||||
except Exception:
|
||||
# Return empty dict if file doesn't exist or is invalid
|
||||
return {}
|
||||
|
||||
|
||||
def save_config(path: Path, data: Dict[str, Any]) -> None:
|
||||
"""Save configuration to a JSON file."""
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
payload = json.dumps(data, indent=2, ensure_ascii=False) + "\n"
|
||||
path.write_text(payload, encoding="utf-8")
|
||||
|
||||
|
||||
def normalize_config(data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Ensure basic expected shape for config dict. Keeps unknown keys intact."""
|
||||
out = dict(data)
|
||||
pls = out.get("playlists")
|
||||
if not isinstance(pls, list):
|
||||
out["playlists"] = []
|
||||
return out
|
||||
|
||||
|
||||
class Settings:
|
||||
def __init__(self) -> None:
|
||||
"""Unified configuration loader that combines file I/O and playlist merging."""
|
||||
|
||||
def __init__(self, config_path: Path | None = None) -> None:
|
||||
if config_path is None:
|
||||
base_dir = Path("config")
|
||||
base_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.path = (base_dir / "yt-playlist-config.json").resolve()
|
||||
else:
|
||||
self.path = config_path.resolve()
|
||||
|
||||
self.data: Dict[str, Any] = dict(DEFAULT_CONFIG)
|
||||
|
||||
# Ensure there is always a config file at the default path.
|
||||
@@ -38,13 +72,13 @@ class Settings:
|
||||
self._load_from_path(self.path)
|
||||
|
||||
def _load_from_path(self, path: Path) -> None:
|
||||
try:
|
||||
self.data.update(json.loads(path.read_text(encoding="utf-8")))
|
||||
except Exception:
|
||||
# Leave defaults if invalid JSON; validation can be added later.
|
||||
pass
|
||||
"""Load and merge config from file."""
|
||||
loaded = load_config(path)
|
||||
if loaded:
|
||||
self.data.update(normalize_config(loaded))
|
||||
|
||||
def _write_default_config(self, path: Path) -> None:
|
||||
"""Write a default config file."""
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
default_payload: Dict[str, Any] = {
|
||||
"playlists": [
|
||||
@@ -57,10 +91,11 @@ class Settings:
|
||||
],
|
||||
"ffmpeg_path": _default_ffmpeg_path(),
|
||||
}
|
||||
path.write_text(json.dumps(default_payload, indent=2) + "\n", encoding="utf-8")
|
||||
save_config(path, default_payload)
|
||||
|
||||
@property
|
||||
def playlists(self) -> List[Dict[str, Any]]:
|
||||
"""Get playlists with global defaults merged in."""
|
||||
global_defaults = {
|
||||
"download_mode": self.data.get("download_mode", DEFAULT_CONFIG["download_mode"]),
|
||||
"max_download_quality": self.data.get("max_download_quality", DEFAULT_CONFIG["max_download_quality"]),
|
||||
|
||||
+1
-2
@@ -5,11 +5,10 @@ import threading
|
||||
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from ..config.settings import Settings
|
||||
from ..config.settings import Settings, load_config
|
||||
from ..core.events.event_bus import EventBus
|
||||
from .bus_bridge import BusBridge
|
||||
from .app_icon import load_app_icon
|
||||
from .config_store import load_config
|
||||
from .runner import SyncRequest, SyncRunner
|
||||
from .pages.playlists import PlaylistManagerPage
|
||||
from .pages.queue import QueuePage
|
||||
|
||||
@@ -6,11 +6,10 @@ from pathlib import Path
|
||||
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from ...config.settings import Settings
|
||||
from ...config.settings import Settings, load_config, normalize_config, save_config
|
||||
from ...core.database.db import Database
|
||||
from ...core.utils.yt import extract_playlist_id
|
||||
from ..smooth_scroll import enable_smooth_scrolling
|
||||
from ..config_store import load_config, normalize_config, save_config
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any
|
||||
|
||||
from PySide6 import QtCore, QtWidgets
|
||||
|
||||
from ..config_store import load_config, save_config
|
||||
from ..config.settings import load_config, save_config
|
||||
|
||||
|
||||
class SettingsPage(QtWidgets.QWidget):
|
||||
|
||||
Reference in New Issue
Block a user