feat: config file

refactor: as the config module changed
test: add test for config
test: add test for local fetcher and local enrichers
test: add test for manual insertion
fix: some random bugs left by the last commit
This commit is contained in:
2026-04-09 15:16:21 +02:00
parent e6b8583868
commit d2a3e64b89
34 changed files with 749 additions and 413 deletions
+9 -8
View File
@@ -9,8 +9,8 @@ from dbus_next.constants import BusType
from dbus_next.message import Message
from loguru import logger
from ..config import AppConfig
from ..models import TrackMeta
from .options import WatchOptions
def _variant_value(item: object) -> object | None:
@@ -75,7 +75,7 @@ def _keyword_match(text: str, keyword: str) -> bool:
class PlayerMonitor:
"""Tracks MPRIS players and forwards signal-driven state updates to session callbacks."""
_options: WatchOptions
_config: AppConfig
_on_players_changed: Callable[[], None]
_on_seeked: Callable[[str, int], None]
_on_playback_status: Callable[[str, str], None]
@@ -89,16 +89,16 @@ class PlayerMonitor:
on_players_changed: Callable[[], None],
on_seeked: Callable[[str, int], None],
on_playback_status: Callable[[str, str], None],
options: WatchOptions,
config: AppConfig,
target: Optional[PlayerTarget] = None,
) -> None:
"""Initialize monitor callbacks, runtime options, and player target filter."""
self._options = options
self._config = config
self._on_players_changed = on_players_changed
self._on_seeked = on_seeked
self._on_playback_status = on_playback_status
self._target = target or PlayerTarget(
player_blacklist=self._options.player_blacklist
player_blacklist=self._config.general.player_blacklist
)
self.players: dict[str, PlayerState] = {}
self._bus: MessageBus | None = None
@@ -184,7 +184,8 @@ class PlayerMonitor:
if not name.startswith("org.mpris.MediaPlayer2."):
continue
if any(
x.lower() in name.lower() for x in self._options.player_blacklist
x.lower() in name.lower()
for x in self._config.general.player_blacklist
):
continue
if not self._target.allows(name):
@@ -388,7 +389,7 @@ class ActivePlayerSelector:
def select(
players: dict[str, PlayerState],
last_active: str | None,
options: WatchOptions,
config: AppConfig,
) -> str | None:
"""Select active player by playing state, preferred keyword, and continuity."""
if not players:
@@ -398,7 +399,7 @@ class ActivePlayerSelector:
if len(playing) == 1:
return playing[0]
preferred = options.preferred_player.lower().strip()
preferred = config.general.preferred_player.lower().strip()
candidates = playing if playing else list(players.keys())
if preferred:
for name in candidates: