Fix playlist checksum (#418)
authorMarvin Schenkel <marvinschenkel@gmail.com>
Fri, 15 Jul 2022 08:46:16 +0000 (10:46 +0200)
committerGitHub <noreply@github.com>
Fri, 15 Jul 2022 08:46:16 +0000 (10:46 +0200)
* Fix playlist checksum

* Improve code readability

* Update music_assistant/music_providers/ytmusic/helpers.py

Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
* Update music_assistant/music_providers/ytmusic/helpers.py

Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
music_assistant/music_providers/ytmusic/helpers.py
music_assistant/music_providers/ytmusic/ytmusic.py

index 4acbe795f33108b894c68342023df87fbd2f00fb..5a5523bfea2203d2738719609f6289fc3dbffbca 100644 (file)
@@ -9,6 +9,7 @@ This also nicely separates the parsing logic from the Youtube Music provider log
 
 import asyncio
 import json
+from time import time
 from typing import Dict, List
 
 import ytmusicapi
@@ -48,7 +49,9 @@ async def get_playlist(
 
     def _get_playlist():
         ytm = ytmusicapi.YTMusic(auth=json.dumps(headers))
-        return ytm.get_playlist(playlistId=prov_playlist_id)
+        playlist = ytm.get_playlist(playlistId=prov_playlist_id)
+        playlist["checksum"] = get_playlist_checksum(playlist)
+        return playlist
 
     loop = asyncio.get_running_loop()
     return await loop.run_in_executor(None, _get_playlist)
@@ -119,6 +122,7 @@ async def get_library_playlists(headers: Dict[str, str]) -> Dict[str, str]:
         for playlist in playlists:
             playlist["id"] = playlist["playlistId"]
             del playlist["playlistId"]
+            playlist["checksum"] = get_playlist_checksum(playlist)
         return playlists
 
     loop = asyncio.get_running_loop()
@@ -161,3 +165,11 @@ async def search(query: str, ytm_filter: str = None, limit: int = 20) -> List[Di
 
     loop = asyncio.get_running_loop()
     return await loop.run_in_executor(None, _search)
+
+
+def get_playlist_checksum(playlist_obj: dict) -> str:
+    """Try to calculate a checksum so we can detect changes in a playlist."""
+    for key in ("duration_seconds", "trackCount"):
+        if key in playlist_obj:
+            return playlist_obj[key]
+    return str(int(time()))
index a6505d835d238966dfce73920162c87b205e7850..a279d0f7910ecfd0e1d925e63d4a76fdf06b70da 100644 (file)
@@ -405,8 +405,7 @@ class YoutubeMusicProvider(MusicProvider):
                 item_id=playlist_obj["id"], prov_type=self.type, prov_id=self.id
             )
         )
-        # use duration_seconds as checksum for now by lack of something better
-        playlist.metadata.checksum = playlist_obj["duration_seconds"]
+        playlist.metadata.checksum = playlist_obj["checksum"]
         return playlist
 
     async def _parse_track(self, track_obj: dict) -> Track: