Add feature to transfer a queue (#1606)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sat, 24 Aug 2024 20:12:40 +0000 (22:12 +0200)
committerGitHub <noreply@github.com>
Sat, 24 Aug 2024 20:12:40 +0000 (22:12 +0200)
music_assistant/client/player_queues.py
music_assistant/constants.py
music_assistant/server/controllers/player_queues.py

index 2a2d4d94b788e1b15a05e4188345b51facbd1fbc..a52bf692f2e5c5b62f5e8d8138cd716009a81948 100644 (file)
@@ -214,6 +214,21 @@ class PlayerQueues:
             start_item=start_item,
         )
 
+    async def transfer_queue(
+        self,
+        source_queue_id: str,
+        target_queue_id: str,
+        auto_play: bool | None = None,
+    ) -> None:
+        """Transfer queue to another queue."""
+        await self.client.send_command(
+            "player_queues/transfer",
+            source_queue_id=source_queue_id,
+            target_queue_id=target_queue_id,
+            auto_play=auto_play,
+            require_schema=25,
+        )
+
     # Other endpoints/commands
 
     async def _get_player_queues(self) -> list[PlayerQueue]:
index 9c2708d1f4e3b810ebbe67d441557c1d2c0b5c71..3d1ced95e83a7421322402b346a890775fa05f01 100644 (file)
@@ -3,7 +3,7 @@
 import pathlib
 from typing import Final
 
-API_SCHEMA_VERSION: Final[int] = 24
+API_SCHEMA_VERSION: Final[int] = 25
 MIN_SCHEMA_VERSION: Final[int] = 24
 
 
index ff66ac51a4cf260f1bcc8f0b50979afdd58751ed..63c4e155af2ac145a840c7d871b475526a1777be 100644 (file)
@@ -765,6 +765,37 @@ class PlayerQueuesController(CoreController):
             task_id=f"play_media_{queue_id}",
         )
 
+    @api_command("player_queues/transfer")
+    async def transfer_queue(
+        self,
+        source_queue_id: str,
+        target_queue_id: str,
+        auto_play: bool | None = None,
+    ) -> None:
+        """Transfer queue to another queue."""
+        if not (source_queue := self.get(source_queue_id)):
+            raise PlayerUnavailableError("Queue {source_queue_id} is not available")
+        if not (target_queue := self.get(target_queue_id)):
+            raise PlayerUnavailableError("Queue {target_queue_id} is not available")
+        if auto_play is None:
+            auto_play = source_queue.state == PlayerState.PLAYING
+        source_items = self._queue_items[source_queue_id]
+        target_queue.repeat_mode = source_queue.repeat_mode
+        target_queue.shuffle_enabled = source_queue.shuffle_enabled
+        target_queue.radio_source = source_queue.radio_source
+        target_queue.resume_pos = source_queue.elapsed_time
+        target_queue.current_index = source_queue.current_index
+        if source_queue.current_item:
+            target_queue.current_item = source_queue.current_item
+            target_queue.current_item.queue_id = target_queue_id
+        self.clear(source_queue_id)
+        self.load(target_queue_id, source_items, keep_remaining=False, keep_played=False)
+        for item in source_items:
+            item.queue_id = target_queue_id
+        self.update_items(target_queue_id, source_items)
+        if auto_play:
+            await self.resume(target_queue_id)
+
     # Interaction with player
 
     async def on_player_register(self, player: Player) -> None: