Fix API compatibility (#1662)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sat, 14 Sep 2024 08:01:28 +0000 (10:01 +0200)
committerGitHub <noreply@github.com>
Sat, 14 Sep 2024 08:01:28 +0000 (10:01 +0200)
music_assistant/common/models/player.py
music_assistant/common/models/queue_item.py
music_assistant/constants.py
music_assistant/server/controllers/player_queues.py

index 567b1b124ee30ffda1a370a76ac37c99336b0069..e3a15634474c5b663639813a8e41b5038cd19b0d 100644 (file)
@@ -49,12 +49,11 @@ class Player(DataClassDictMixin):
     device_info: DeviceInfo
     supported_features: tuple[PlayerFeature, ...] = field(default=())
 
-    elapsed_time: float = 0
-    elapsed_time_last_updated: float = time.time()
-    state: PlayerState = PlayerState.IDLE
-
-    volume_level: int = 100
-    volume_muted: bool = False
+    elapsed_time: float | None = None
+    elapsed_time_last_updated: float | None = None
+    state: PlayerState | None = None
+    volume_level: int | None = None
+    volume_muted: bool | None = None
 
     # group_childs: Return list of player group child id's or synced child`s.
     # - If this player is a dedicated group player,
@@ -138,8 +137,10 @@ class Player(DataClassDictMixin):
     _prev_volume_level: int = 0
 
     @property
-    def corrected_elapsed_time(self) -> float:
+    def corrected_elapsed_time(self) -> float | None:
         """Return the corrected/realtime elapsed time."""
+        if self.elapsed_time is None or self.elapsed_time_last_updated is None:
+            return None
         if self.state == PlayerState.PLAYING:
             return self.elapsed_time + (time.time() - self.elapsed_time_last_updated)
         return self.elapsed_time
@@ -155,3 +156,19 @@ class Player(DataClassDictMixin):
     def current_item_id(self, uri: str) -> None:
         """Set current_item_id (for backwards compatibility)."""
         self.current_media = PlayerMedia(uri)
+
+    def __post_serialize__(self, d: dict[Any, Any]) -> dict[Any, Any]:
+        """Execute action(s) on serialization."""
+        # TEMP: convert values to prevent api breakage
+        # this may be removed after 2.3 has been launched to stable
+        if self.elapsed_time is None:
+            d["elapsed_time"] = 0
+        if self.elapsed_time_last_updated is None:
+            d["elapsed_time_last_updated"] = 0
+        if self.volume_level is None:
+            d["volume_level"] = 0
+        if self.volume_muted is None:
+            d["volume_muted"] = False
+        if self.state is None:
+            d["state"] = PlayerState.IDLE
+        return d
index 716e2b1be49e0edef756b5e8f76f0b61ce71b546..0c7d2aa1bf70dd8dcd046b0f81018dca8ed839b4 100644 (file)
@@ -44,6 +44,11 @@ class QueueItem(DataClassDictMixin):
             streamdetails.pop("expires", None)
             streamdetails.pop("path", None)
             streamdetails.pop("decryption_key", None)
+            # pop loudness from streamdetails in api to keep api from breaking
+            # (due to the loudness field's type change in 2.3)
+            # this may be removed after 2.3 has been launched to stable
+            streamdetails.pop("loudness", None)
+            streamdetails.pop("loudness_album", None)
         return d
 
     @property
index 820f909aa07a850d24bf32f4dc9021a246f8e210..017371ca45fcadb34c44ba913286153ce9606020 100644 (file)
@@ -3,7 +3,7 @@
 import pathlib
 from typing import Final
 
-API_SCHEMA_VERSION: Final[int] = 25
+API_SCHEMA_VERSION: Final[int] = 26
 MIN_SCHEMA_VERSION: Final[int] = 24
 
 
index 411f96e4ce175644d3b767de17044b05578b14f5..f723c9937f5cfc84f712ed9d951a66c8dfa55c64 100644 (file)
@@ -949,12 +949,12 @@ class PlayerQueuesController(CoreController):
             if item_id := self._parse_player_current_item_id(queue_id, player):
                 queue.current_index = self.index_by_id(queue_id, item_id)
             if player.state in (PlayerState.PLAYING, PlayerState.PAUSED):
-                queue.elapsed_time = int(player.corrected_elapsed_time)
-                queue.elapsed_time_last_updated = player.elapsed_time_last_updated
+                queue.elapsed_time = int(player.corrected_elapsed_time or 0)
+                queue.elapsed_time_last_updated = player.elapsed_time_last_updated or 0
 
         # only update these attributes if the queue is active
         # and has an item loaded so we are able to resume it
-        queue.state = player.state
+        queue.state = player.state or PlayerState.IDLE
         queue.current_item = self.get_item(queue_id, queue.current_index)
         queue.next_item = self._get_next_item(queue_id)
 
@@ -1448,7 +1448,7 @@ class PlayerQueuesController(CoreController):
         """Calculate current queue index and current track elapsed time."""
         # player is playing a constant stream so we need to do this the hard way
         queue_index = 0
-        elapsed_time_queue = player.corrected_elapsed_time
+        elapsed_time_queue = player.corrected_elapsed_time or 0
         total_time = 0
         track_time = 0
         queue_items = self._queue_items[queue.queue_id]