140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Optional
|
|
import yaml
|
|
|
|
|
|
@dataclass
|
|
class JellyfinConfig:
|
|
server_url: str = "http://127.0.0.1:8096"
|
|
username: str = ""
|
|
password: str = ""
|
|
token: Optional[str] = None
|
|
client_name: str = "Jellyfin HTPC Client"
|
|
device_name: str = "HTPC"
|
|
device_id: str = "htpc-default-01"
|
|
|
|
|
|
@dataclass
|
|
class PlayerConfig:
|
|
mpv_path: str = "mpv"
|
|
ipc_socket: str = "/tmp/mpv-jellyfin.sock"
|
|
hwdec: str = "auto"
|
|
vo: str = "gpu"
|
|
fullscreen: bool = True
|
|
audio_device: str = "auto"
|
|
extra_args: List[str] = field(default_factory=lambda: [
|
|
"--keep-open=yes",
|
|
"--force-window=immediate",
|
|
"--osd-font=sans-serif",
|
|
"--osd-font-size=28",
|
|
])
|
|
|
|
|
|
@dataclass
|
|
class KodiRpcConfig:
|
|
enabled: bool = True
|
|
http_port: int = 8080
|
|
ws_port: int = 9090
|
|
|
|
|
|
@dataclass
|
|
class WebApiConfig:
|
|
enabled: bool = True
|
|
host: str = "0.0.0.0"
|
|
port: int = 8097
|
|
|
|
|
|
@dataclass
|
|
class YoutubeConfig:
|
|
max_height: int = 1080
|
|
fetch_metadata: bool = True
|
|
|
|
|
|
@dataclass
|
|
class AppConfig:
|
|
jellyfin: JellyfinConfig = field(default_factory=JellyfinConfig)
|
|
player: PlayerConfig = field(default_factory=PlayerConfig)
|
|
kodi_rpc: KodiRpcConfig = field(default_factory=KodiRpcConfig)
|
|
web_api: WebApiConfig = field(default_factory=WebApiConfig)
|
|
youtube: YoutubeConfig = field(default_factory=YoutubeConfig)
|
|
|
|
@classmethod
|
|
def load(cls, config_path: Optional[str | Path] = None) -> AppConfig:
|
|
paths_to_check = []
|
|
if config_path:
|
|
paths_to_check.append(Path(config_path))
|
|
if env_path := os.environ.get("JELLYFIN_CLIENT_CONFIG"):
|
|
paths_to_check.append(Path(env_path))
|
|
|
|
paths_to_check.extend([
|
|
Path.cwd() / "config.yaml",
|
|
Path.home() / ".config" / "jellyfin-client" / "config.yaml",
|
|
Path("/etc/jellyfin-client/config.yaml"),
|
|
])
|
|
|
|
data: Dict[str, Any] = {}
|
|
found_path = None
|
|
for p in paths_to_check:
|
|
if p.is_file():
|
|
found_path = p
|
|
with open(p, "r", encoding="utf-8") as f:
|
|
data = yaml.safe_load(f) or {}
|
|
break
|
|
|
|
cfg = cls()
|
|
if not data:
|
|
return cfg
|
|
|
|
if "jellyfin" in data:
|
|
jf = data["jellyfin"]
|
|
cfg.jellyfin = JellyfinConfig(
|
|
server_url=jf.get("server_url", cfg.jellyfin.server_url).rstrip("/"),
|
|
username=jf.get("username", cfg.jellyfin.username),
|
|
password=jf.get("password", cfg.jellyfin.password),
|
|
token=jf.get("token", cfg.jellyfin.token),
|
|
client_name=jf.get("client_name", cfg.jellyfin.client_name),
|
|
device_name=jf.get("device_name", cfg.jellyfin.device_name),
|
|
device_id=jf.get("device_id", cfg.jellyfin.device_id),
|
|
)
|
|
|
|
if "player" in data:
|
|
pl = data["player"]
|
|
cfg.player = PlayerConfig(
|
|
mpv_path=pl.get("mpv_path", cfg.player.mpv_path),
|
|
ipc_socket=pl.get("ipc_socket", cfg.player.ipc_socket),
|
|
hwdec=pl.get("hwdec", cfg.player.hwdec),
|
|
vo=pl.get("vo", cfg.player.vo),
|
|
fullscreen=pl.get("fullscreen", cfg.player.fullscreen),
|
|
audio_device=pl.get("audio_device", cfg.player.audio_device),
|
|
extra_args=pl.get("extra_args", cfg.player.extra_args),
|
|
)
|
|
|
|
if "kodi_rpc" in data:
|
|
kr = data["kodi_rpc"]
|
|
cfg.kodi_rpc = KodiRpcConfig(
|
|
enabled=kr.get("enabled", cfg.kodi_rpc.enabled),
|
|
http_port=kr.get("http_port", cfg.kodi_rpc.http_port),
|
|
ws_port=kr.get("ws_port", cfg.kodi_rpc.ws_port),
|
|
)
|
|
|
|
if "web_api" in data:
|
|
wa = data["web_api"]
|
|
cfg.web_api = WebApiConfig(
|
|
enabled=wa.get("enabled", cfg.web_api.enabled),
|
|
host=wa.get("host", cfg.web_api.host),
|
|
port=wa.get("port", cfg.web_api.port),
|
|
)
|
|
|
|
if "youtube" in data:
|
|
yt = data["youtube"]
|
|
cfg.youtube = YoutubeConfig(
|
|
max_height=yt.get("max_height", cfg.youtube.max_height),
|
|
fetch_metadata=yt.get("fetch_metadata", cfg.youtube.fetch_metadata),
|
|
)
|
|
|
|
return cfg
|