Added change_settings and refresh_players to the players, still need to hook up UI
This commit is contained in:
@@ -617,7 +617,7 @@ class SublimeMusicApp(Gtk.Application):
|
||||
if confirm_dialog.run() == Gtk.ResponseType.YES:
|
||||
assert self.app_config.cache_location
|
||||
provider_dir = self.app_config.cache_location.joinpath(provider.id)
|
||||
shutil.rmtree(str(provider_dir))
|
||||
shutil.rmtree(str(provider_dir), ignore_errors=True)
|
||||
del self.app_config.providers[provider.id]
|
||||
|
||||
confirm_dialog.destroy()
|
||||
|
@@ -99,7 +99,7 @@ class Player(abc.ABC):
|
||||
def get_configuration_options() -> Dict[str, Union[Type, Tuple[str, ...]]]:
|
||||
"""
|
||||
:returns: a dictionary of configuration key -> type of the option or tuple of
|
||||
options (for a dropdown menu)
|
||||
options (for a dropdown menu).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
@@ -114,7 +114,27 @@ class Player(abc.ABC):
|
||||
"""
|
||||
Initialize the player.
|
||||
|
||||
:param config: A dictionary of configuration key -> configuration value
|
||||
:param config: A dictionary of configuration key -> configuration value.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def change_settings(self, config: Dict[str, Union[str, int, bool]]):
|
||||
"""
|
||||
This function is called when the player settings are changed (normally this
|
||||
happens when the user changes the settings in the UI).
|
||||
|
||||
:param config: A dictionary of configuration key -> configuration value.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def refresh_players(self):
|
||||
"""
|
||||
This function is called when the user requests the player list to be refreshed
|
||||
in the UI.
|
||||
|
||||
This function should call the ``player_device_change_callback`` with the delta
|
||||
events to indicate changes to the UI. If there is no reason to refresh (for
|
||||
example, the MPV player), then this function can do nothing.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@@ -6,7 +6,7 @@ import multiprocessing
|
||||
import os
|
||||
import socket
|
||||
from datetime import timedelta
|
||||
from typing import Any, Callable, Dict, Optional, Set, Tuple, Type, Union
|
||||
from typing import Any, Callable, cast, Dict, Optional, Set, Tuple, Type, Union
|
||||
from urllib.parse import urlparse
|
||||
from uuid import UUID
|
||||
|
||||
@@ -65,37 +65,74 @@ class ChromecastPlayer(Player):
|
||||
player_device_change_callback: Callable[[PlayerDeviceEvent], None],
|
||||
config: Dict[str, Union[str, int, bool]],
|
||||
):
|
||||
self.server_process = None
|
||||
self.config = config
|
||||
self.server_process: Optional[multiprocessing.Process] = None
|
||||
self.on_timepos_change = on_timepos_change
|
||||
self.on_track_end = on_track_end
|
||||
self.on_player_event = on_player_event
|
||||
self.player_device_change_callback = player_device_change_callback
|
||||
|
||||
self.change_settings(config)
|
||||
|
||||
if chromecast_imported:
|
||||
self._chromecasts: Dict[UUID, pychromecast.Chromecast] = {}
|
||||
self._current_chromecast: Optional[pychromecast.Chromecast] = None
|
||||
|
||||
self.get_chromecasts_job = None
|
||||
self.refresh_players()
|
||||
|
||||
def chromecast_discovered_callback(self, chromecast: Any):
|
||||
chromecast = cast(pychromecast.Chromecast, chromecast)
|
||||
self._chromecasts[chromecast.device.uuid] = chromecast
|
||||
self.player_device_change_callback(
|
||||
PlayerDeviceEvent(
|
||||
PlayerDeviceEvent.Delta.ADD,
|
||||
type(self),
|
||||
str(chromecast.device.uuid),
|
||||
chromecast.device.friendly_name,
|
||||
)
|
||||
)
|
||||
|
||||
def change_settings(self, config: Dict[str, Union[str, int, bool]]):
|
||||
if not chromecast_imported:
|
||||
return
|
||||
|
||||
self.config = config
|
||||
if bottle_imported and self.config.get(SERVE_FILES_KEY):
|
||||
# TODO (#222): should have a mechanism to update this. Maybe it should be
|
||||
# determined every time we try and play a song.
|
||||
# Try and terminate the existing process if it exists.
|
||||
if self.server_process is not None:
|
||||
try:
|
||||
self.server_process.terminate()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.server_process = multiprocessing.Process(
|
||||
target=self._run_server_process,
|
||||
args=("0.0.0.0", self.config.get(LAN_PORT_KEY)),
|
||||
)
|
||||
self.server_process.start()
|
||||
|
||||
if chromecast_imported:
|
||||
self._chromecasts: Dict[UUID, pychromecast.Chromecast] = {}
|
||||
self._current_chromecast: Optional[pychromecast.Chromecast] = None
|
||||
def refresh_players(self):
|
||||
if not chromecast_imported:
|
||||
return
|
||||
|
||||
def discovered_callback(chromecast: pychromecast.Chromecast):
|
||||
self._chromecasts[chromecast.device.uuid] = chromecast
|
||||
player_device_change_callback(
|
||||
PlayerDeviceEvent(
|
||||
PlayerDeviceEvent.Delta.ADD,
|
||||
type(self),
|
||||
str(chromecast.device.uuid),
|
||||
chromecast.device.friendly_name,
|
||||
)
|
||||
if self.get_chromecasts_job is not None:
|
||||
pychromecast.discovery.stop_discovery(self.get_chromecasts_job)
|
||||
|
||||
for id_, chromecast in self._chromecasts.items():
|
||||
self.player_device_change_callback(
|
||||
PlayerDeviceEvent(
|
||||
PlayerDeviceEvent.Delta.REMOVE,
|
||||
type(self),
|
||||
id_,
|
||||
chromecast.device.friendly_name,
|
||||
)
|
||||
)
|
||||
|
||||
pychromecast.get_chromecasts(blocking=False, callback=discovered_callback)
|
||||
self._chromecasts = {}
|
||||
|
||||
self.get_chromecasts_job = pychromecast.get_chromecasts(
|
||||
blocking=False, callback=self.chromecast_discovered_callback
|
||||
)
|
||||
|
||||
def set_current_device_id(self, device_id: str):
|
||||
self._current_chromecast = self._chromecasts[UUID(device_id)]
|
||||
|
@@ -66,7 +66,16 @@ class PlayerManager:
|
||||
for player_type in PlayerManager.available_player_types
|
||||
}
|
||||
|
||||
has_done_one_retrieval = multiprocessing.Value("b", False)
|
||||
def change_settings(
|
||||
self, config: Dict[str, Dict[str, Union[Type, Tuple[str, ...]]]],
|
||||
):
|
||||
self.config = config
|
||||
for player_type, player in self.players.items():
|
||||
player.change_settings(config.get(player_type.name))
|
||||
|
||||
def refresh_players(self):
|
||||
for player in self.players.values():
|
||||
player.refresh_players()
|
||||
|
||||
def shutdown(self):
|
||||
for p in self.players.values():
|
||||
|
@@ -38,11 +38,7 @@ class MPVPlayer(Player):
|
||||
):
|
||||
self.mpv = mpv.MPV()
|
||||
self.mpv.audio_client_name = "sublime-music"
|
||||
self.mpv.replaygain = {
|
||||
"Disabled": "no",
|
||||
"Track": "track",
|
||||
"Album": "album",
|
||||
}.get(cast(str, config.get(REPLAY_GAIN_KEY, "Disabled")), "no")
|
||||
self.change_settings(config)
|
||||
|
||||
@self.mpv.property_observer("time-pos")
|
||||
def time_observer(_, value: Optional[float]):
|
||||
@@ -72,6 +68,18 @@ class MPVPlayer(Player):
|
||||
)
|
||||
)
|
||||
|
||||
def change_settings(self, config: Dict[str, Union[str, int, bool]]):
|
||||
self.config = config
|
||||
self.mpv.replaygain = {
|
||||
"Disabled": "no",
|
||||
"Track": "track",
|
||||
"Album": "album",
|
||||
}.get(cast(str, config.get(REPLAY_GAIN_KEY, "Disabled")), "no")
|
||||
|
||||
def refresh_players(self):
|
||||
# Don't do anything
|
||||
pass
|
||||
|
||||
def set_current_device_id(self, device_id: str):
|
||||
# Don't do anything beacuse it should always be the "this device" ID.
|
||||
pass
|
||||
|
Reference in New Issue
Block a user