From: Marcel van der Veldt Date: Tue, 7 Jan 2025 23:58:26 +0000 (+0100) Subject: Feat: Add removal flag to unload callback X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=bb9e22cf21dfe721cf909853fdfbc1206c2b787a;p=music-assistant-server.git Feat: Add removal flag to unload callback --- diff --git a/music_assistant/controllers/config.py b/music_assistant/controllers/config.py index 6cefe509..6beae0dc 100644 --- a/music_assistant/controllers/config.py +++ b/music_assistant/controllers/config.py @@ -291,7 +291,7 @@ class ConfigController: msg = f"Builtin provider {prov_manifest.name} can not be removed." raise RuntimeError(msg) self.remove(conf_key) - await self.mass.unload_provider(instance_id) + await self.mass.unload_provider(instance_id, True) if existing["type"] == "music": # cleanup entries in library await self.mass.music.cleanup_provider(instance_id) diff --git a/music_assistant/mass.py b/music_assistant/mass.py index 5f2174d5..4b9c8298 100644 --- a/music_assistant/mass.py +++ b/music_assistant/mass.py @@ -504,7 +504,7 @@ class MusicAssistant: if dep_prov.manifest.depends_on == prov_conf.domain: await self.unload_provider(dep_prov.instance_id) - async def unload_provider(self, instance_id: str) -> None: + async def unload_provider(self, instance_id: str, is_removed: bool = False) -> None: """Unload a provider.""" if provider := self._providers.get(instance_id): # remove mdns discovery if needed @@ -525,7 +525,7 @@ class MusicAssistant: player.available = False self.players.update(player.player_id) try: - await provider.unload() + await provider.unload(is_removed) except Exception as err: LOGGER.warning("Error while unload provider %s: %s", provider.name, str(err)) finally: diff --git a/music_assistant/models/provider.py b/music_assistant/models/provider.py index 7b406df6..81d951db 100644 --- a/music_assistant/models/provider.py +++ b/music_assistant/models/provider.py @@ -58,11 +58,12 @@ class Provider: async def loaded_in_mass(self) -> None: """Call after the provider has been loaded.""" - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. Called when provider is deregistered (e.g. MA exiting or config reloading). + is_removed will be set to True when the provider is removed from the configuration. """ async def on_mdns_service_state_change( diff --git a/music_assistant/providers/_template_music_provider/__init__.py b/music_assistant/providers/_template_music_provider/__init__.py index 5dc0adf6..7eaba12a 100644 --- a/music_assistant/providers/_template_music_provider/__init__.py +++ b/music_assistant/providers/_template_music_provider/__init__.py @@ -167,11 +167,12 @@ class MyDemoMusicprovider(MusicProvider): # relevant or leave out completely if not needed. # In most cases this can be omitted for music providers. - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. Called when provider is deregistered (e.g. MA exiting or config reloading). + is_removed will be set to True when the provider is removed from the configuration. """ # OPTIONAL # This is an optional method that you can implement if diff --git a/music_assistant/providers/_template_player_provider/__init__.py b/music_assistant/providers/_template_player_provider/__init__.py index 104fa89f..7a6467a4 100644 --- a/music_assistant/providers/_template_player_provider/__init__.py +++ b/music_assistant/providers/_template_player_provider/__init__.py @@ -122,11 +122,12 @@ class MyDemoPlayerprovider(PlayerProvider): # you can use this for instance to trigger custom (non-mdns) discovery of players # or any other logic that needs to run after the provider is fully loaded. - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. Called when provider is deregistered (e.g. MA exiting or config reloading). + is_removed will be set to True when the provider is removed from the configuration. """ # OPTIONAL # this is an optional method that you can implement if diff --git a/music_assistant/providers/airplay/provider.py b/music_assistant/providers/airplay/provider.py index 9fcfefd2..d4496303 100644 --- a/music_assistant/providers/airplay/provider.py +++ b/music_assistant/providers/airplay/provider.py @@ -221,8 +221,8 @@ class AirplayProvider(PlayerProvider): # handle new player await self._setup_player(player_id, display_name, info) - async def unload(self) -> None: - """Handle close/cleanup of the provider.""" + async def unload(self, is_removed: bool = False) -> None: + """Handle unload/close of the provider.""" # power off all players (will disconnect and close cliraop) for player_id in self._players: await self.cmd_power(player_id, False) diff --git a/music_assistant/providers/chromecast/__init__.py b/music_assistant/providers/chromecast/__init__.py index b206bde9..dd8c334b 100644 --- a/music_assistant/providers/chromecast/__init__.py +++ b/music_assistant/providers/chromecast/__init__.py @@ -153,7 +153,7 @@ class ChromecastProvider(PlayerProvider): # start discovery in executor await self.mass.loop.run_in_executor(None, self.browser.start_discovery) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Handle close/cleanup of the provider.""" if not self.browser: return diff --git a/music_assistant/providers/dlna/__init__.py b/music_assistant/providers/dlna/__init__.py index ce0d966c..028ab326 100644 --- a/music_assistant/providers/dlna/__init__.py +++ b/music_assistant/providers/dlna/__init__.py @@ -250,7 +250,7 @@ class DLNAPlayerProvider(PlayerProvider): self.upnp_factory = UpnpFactory(self.requester, non_strict=True) self.notify_server = DLNANotifyServer(self.requester, self.mass) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. diff --git a/music_assistant/providers/filesystem_smb/__init__.py b/music_assistant/providers/filesystem_smb/__init__.py index b43245dd..a510876d 100644 --- a/music_assistant/providers/filesystem_smb/__init__.py +++ b/music_assistant/providers/filesystem_smb/__init__.py @@ -149,7 +149,7 @@ class SMBFileSystemProvider(LocalFileSystemProvider): await self.check_write_access() - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. diff --git a/music_assistant/providers/hass/__init__.py b/music_assistant/providers/hass/__init__.py index dc243eb4..0d620365 100644 --- a/music_assistant/providers/hass/__init__.py +++ b/music_assistant/providers/hass/__init__.py @@ -185,7 +185,7 @@ class HomeAssistant(PluginProvider): raise SetupFailedError(err_msg) from err self._listen_task = self.mass.create_task(self._hass_listener()) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. diff --git a/music_assistant/providers/player_group/__init__.py b/music_assistant/providers/player_group/__init__.py index 11adea4d..bea0788b 100644 --- a/music_assistant/providers/player_group/__init__.py +++ b/music_assistant/providers/player_group/__init__.py @@ -202,7 +202,7 @@ class PlayerGroupProvider(PlayerProvider): self.mass.subscribe(self._on_mass_player_added_event, EventType.PLAYER_ADDED) ) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. diff --git a/music_assistant/providers/siriusxm/__init__.py b/music_assistant/providers/siriusxm/__init__.py index 36724642..d5ed26f2 100644 --- a/music_assistant/providers/siriusxm/__init__.py +++ b/music_assistant/providers/siriusxm/__init__.py @@ -175,7 +175,7 @@ class SiriusXMProvider(MusicProvider): self.logger.debug(f"SXM Proxy server running at {bind_ip}:{bind_port}") - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """ Handle unload/close of the provider. diff --git a/music_assistant/providers/slimproto/__init__.py b/music_assistant/providers/slimproto/__init__.py index 234578e7..ab50aa94 100644 --- a/music_assistant/providers/slimproto/__init__.py +++ b/music_assistant/providers/slimproto/__init__.py @@ -266,7 +266,7 @@ class SlimprotoProvider(PlayerProvider): "/slimproto/multi", self._serve_multi_client_stream ) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Handle close/cleanup of the provider.""" self.mass.streams.unregister_dynamic_route("/slimproto/multi") await self.slimproto.stop() diff --git a/music_assistant/providers/snapcast/__init__.py b/music_assistant/providers/snapcast/__init__.py index 4991436d..11bb1a56 100644 --- a/music_assistant/providers/snapcast/__init__.py +++ b/music_assistant/providers/snapcast/__init__.py @@ -332,7 +332,7 @@ class SnapCastProvider(PlayerProvider): # initial load of players self._handle_update() - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Handle close/cleanup of the provider.""" self._stop_called = True for snap_client_id in self._snapserver.clients: diff --git a/music_assistant/providers/sonos/player.py b/music_assistant/providers/sonos/player.py index 7b729068..78794a5c 100644 --- a/music_assistant/providers/sonos/player.py +++ b/music_assistant/providers/sonos/player.py @@ -165,7 +165,7 @@ class SonosPlayer: ) ) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Unload the player (disconnect + cleanup).""" await self._disconnect() self.mass.players.remove(self.player_id, False) diff --git a/music_assistant/providers/sonos/provider.py b/music_assistant/providers/sonos/provider.py index f7c060ce..5b59b16a 100644 --- a/music_assistant/providers/sonos/provider.py +++ b/music_assistant/providers/sonos/provider.py @@ -67,7 +67,7 @@ class SonosPlayerProvider(PlayerProvider): "/sonos_queue/v2.3/timePlayed", self._handle_sonos_queue_time_played ) - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Handle close/cleanup of the provider.""" # disconnect all players await asyncio.gather(*(player.unload() for player in self.sonos_players.values())) diff --git a/music_assistant/providers/sonos_s1/__init__.py b/music_assistant/providers/sonos_s1/__init__.py index a35d3952..ed62855a 100644 --- a/music_assistant/providers/sonos_s1/__init__.py +++ b/music_assistant/providers/sonos_s1/__init__.py @@ -155,7 +155,7 @@ class SonosPlayerProvider(PlayerProvider): self.creation_lock = asyncio.Lock() self._known_invisible: set[SoCo] = set() - async def unload(self) -> None: + async def unload(self, is_removed: bool = False) -> None: """Handle close/cleanup of the provider.""" if self._discovery_reschedule_timer: self._discovery_reschedule_timer.cancel()