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:
+45
-10
@@ -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:
|
class Settings:
|
||||||
def __init__(self) -> None:
|
"""Unified configuration loader that combines file I/O and playlist merging."""
|
||||||
base_dir = Path("config")
|
|
||||||
base_dir.mkdir(parents=True, exist_ok=True)
|
def __init__(self, config_path: Path | None = None) -> None:
|
||||||
self.path = (base_dir / "yt-playlist-config.json").resolve()
|
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)
|
self.data: Dict[str, Any] = dict(DEFAULT_CONFIG)
|
||||||
|
|
||||||
# Ensure there is always a config file at the default path.
|
# Ensure there is always a config file at the default path.
|
||||||
@@ -38,13 +72,13 @@ class Settings:
|
|||||||
self._load_from_path(self.path)
|
self._load_from_path(self.path)
|
||||||
|
|
||||||
def _load_from_path(self, path: Path) -> None:
|
def _load_from_path(self, path: Path) -> None:
|
||||||
try:
|
"""Load and merge config from file."""
|
||||||
self.data.update(json.loads(path.read_text(encoding="utf-8")))
|
loaded = load_config(path)
|
||||||
except Exception:
|
if loaded:
|
||||||
# Leave defaults if invalid JSON; validation can be added later.
|
self.data.update(normalize_config(loaded))
|
||||||
pass
|
|
||||||
|
|
||||||
def _write_default_config(self, path: Path) -> None:
|
def _write_default_config(self, path: Path) -> None:
|
||||||
|
"""Write a default config file."""
|
||||||
path.parent.mkdir(parents=True, exist_ok=True)
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
default_payload: Dict[str, Any] = {
|
default_payload: Dict[str, Any] = {
|
||||||
"playlists": [
|
"playlists": [
|
||||||
@@ -57,10 +91,11 @@ class Settings:
|
|||||||
],
|
],
|
||||||
"ffmpeg_path": _default_ffmpeg_path(),
|
"ffmpeg_path": _default_ffmpeg_path(),
|
||||||
}
|
}
|
||||||
path.write_text(json.dumps(default_payload, indent=2) + "\n", encoding="utf-8")
|
save_config(path, default_payload)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def playlists(self) -> List[Dict[str, Any]]:
|
def playlists(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Get playlists with global defaults merged in."""
|
||||||
global_defaults = {
|
global_defaults = {
|
||||||
"download_mode": self.data.get("download_mode", DEFAULT_CONFIG["download_mode"]),
|
"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"]),
|
"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 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 ..core.events.event_bus import EventBus
|
||||||
from .bus_bridge import BusBridge
|
from .bus_bridge import BusBridge
|
||||||
from .app_icon import load_app_icon
|
from .app_icon import load_app_icon
|
||||||
from .config_store import load_config
|
|
||||||
from .runner import SyncRequest, SyncRunner
|
from .runner import SyncRequest, SyncRunner
|
||||||
from .pages.playlists import PlaylistManagerPage
|
from .pages.playlists import PlaylistManagerPage
|
||||||
from .pages.queue import QueuePage
|
from .pages.queue import QueuePage
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ from pathlib import Path
|
|||||||
|
|
||||||
from PySide6 import QtCore, QtGui, QtWidgets
|
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.database.db import Database
|
||||||
from ...core.utils.yt import extract_playlist_id
|
from ...core.utils.yt import extract_playlist_id
|
||||||
from ..smooth_scroll import enable_smooth_scrolling
|
from ..smooth_scroll import enable_smooth_scrolling
|
||||||
from ..config_store import load_config, normalize_config, save_config
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from typing import Any
|
|||||||
|
|
||||||
from PySide6 import QtCore, QtWidgets
|
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):
|
class SettingsPage(QtWidgets.QWidget):
|
||||||
|
|||||||
Reference in New Issue
Block a user