Various fixes for Tidal (#1174)
authorJozef Kruszynski <60214390+jozefKruszynski@users.noreply.github.com>
Mon, 25 Mar 2024 21:55:49 +0000 (22:55 +0100)
committerGitHub <noreply@github.com>
Mon, 25 Mar 2024 21:55:49 +0000 (22:55 +0100)
* Hopefully caught all the errors and fixed urls for tracks and playlists

* use https for browse links

* change image retrieval method, split into one for tracks, one for all others

* lint

* const for browse url

* lint

music_assistant/server/providers/tidal/__init__.py
music_assistant/server/providers/tidal/helpers.py

index 0c9fd7756f6f99fda039badc898ef72906c3a128..4ea764c8dfb3829fe673759dc357c868f3f9b171 100644 (file)
@@ -88,6 +88,8 @@ CONF_USER_ID = "user_id"
 CONF_EXPIRY_TIME = "expiry_time"
 CONF_QUALITY = "quality"
 
+BROWSE_URL = "https://tidal.com/browse"
+
 
 async def setup(
     mass: MusicAssistant, manifest: ProviderManifest, config: ProviderConfig
@@ -550,14 +552,14 @@ class TidalProvider(MusicProvider):
                     item_id=str(artist_id),
                     provider_domain=self.domain,
                     provider_instance=self.instance_id,
-                    url=f"http://www.tidal.com/artist/{artist_id}",
+                    url=f"{BROWSE_URL}/artist/{artist_id}",
                 )
             },
         )
         # metadata
         if full_details and artist_obj.name != "Various Artists":
             try:
-                image_url = await self._get_image_url(artist_obj, 750)
+                image_url = await self._get_image_url(artist_obj, size=750)
                 artist.metadata.images = [
                     MediaItemImage(
                         type=ImageType.THUMB,
@@ -587,7 +589,7 @@ class TidalProvider(MusicProvider):
                     audio_format=AudioFormat(
                         content_type=ContentType.FLAC,
                     ),
-                    url=f"http://www.tidal.com/album/{album_id}",
+                    url=f"{BROWSE_URL}/album/{album_id}",
                     available=album_obj.available,
                 )
             },
@@ -611,7 +613,7 @@ class TidalProvider(MusicProvider):
         album.metadata.popularity = album_obj.popularity
         if full_details:
             try:
-                image_url = await self._get_image_url(album_obj, 1280)
+                image_url = await self._get_image_url(album_obj, size=1280)
                 album.metadata.images = [
                     MediaItemImage(
                         type=ImageType.THUMB,
@@ -655,7 +657,7 @@ class TidalProvider(MusicProvider):
                         content_type=ContentType.FLAC,
                         bit_depth=24 if self._is_hi_res(track_obj=track_obj) else 16,
                     ),
-                    url=f"http://www.tidal.com/tracks/{track_id}",
+                    url=f"{BROWSE_URL}/track/{track_id}",
                     available=track_obj.available,
                 )
             },
@@ -678,18 +680,33 @@ class TidalProvider(MusicProvider):
         track.metadata.popularity = track_obj.popularity
         track.metadata.copyright = track_obj.copyright
         if full_details:
+            image_url = None
             try:
                 if lyrics_obj := await self._get_lyrics(track_obj):
                     track.metadata.lyrics = lyrics_obj.text
             except Exception:
                 self.logger.info(f"Track {track_obj.id} has no available lyrics")
-        if not track.image and track_obj.album and (image_url := track_obj.album.image(640, None)):
-            track.metadata.images = [
-                MediaItemImage(
-                    type=ImageType.THUMB,
-                    path=image_url,
-                )
-            ]
+            try:
+                image_url = await self._get_track_image_url(track_obj, width=1080, height=720)
+                track.metadata.images = [
+                    MediaItemImage(
+                        type=ImageType.THUMB,
+                        path=image_url,
+                    )
+                ]
+            except Exception:
+                self.logger.info(f"Track {track_obj.id} has no available picture")
+            if image_url is None:
+                try:
+                    image_url = await self._get_image_url(track_obj.album, size=1280)
+                    track_obj.album.metadata.images = [
+                        MediaItemImage(
+                            type=ImageType.THUMB,
+                            path=image_url,
+                        )
+                    ]
+                except Exception:
+                    self.logger.info(f"Album {track_obj.album.id} has no available picture")
 
         return track
 
@@ -710,7 +727,7 @@ class TidalProvider(MusicProvider):
                     item_id=str(playlist_id),
                     provider_domain=self.domain,
                     provider_instance=self.instance_id,
-                    url=f"http://www.tidal.com/playlists/{playlist_id}",
+                    url=f"{BROWSE_URL}/playlist/{playlist_id}",
                 )
             },
         )
@@ -721,7 +738,7 @@ class TidalProvider(MusicProvider):
         playlist.metadata.popularity = playlist_obj.popularity
         if full_details:
             try:
-                image_url = await self._get_image_url(playlist_obj, 1080)
+                image_url = await self._get_image_url(playlist_obj, size=1080)
                 playlist.metadata.images = [
                     MediaItemImage(
                         type=ImageType.THUMB,
@@ -734,11 +751,21 @@ class TidalProvider(MusicProvider):
         return playlist
 
     async def _get_image_url(
-        self, item: TidalArtist | TidalAlbum | TidalPlaylist, size: int
+        self, item: TidalArtist | TidalAlbum | TidalPlaylist, size: int = 0
+    ) -> str:
+        def inner() -> str:
+            return item.image(size)
+
+        return await asyncio.to_thread(inner)
+
+    async def _get_track_image_url(
+        self,
+        item: TidalTrack,
+        width: int = 0,
+        height: int = 0,
     ) -> str:
         def inner() -> str:
-            image_url: str = item.image(size)
-            return image_url
+            return item.image(width, height)
 
         return await asyncio.to_thread(inner)
 
index 9b4db3a7de1abd242a93a95e60056734760bccea..5ce409480e4c5cf10578b581bffeb5de971c2fbd 100644 (file)
@@ -20,7 +20,12 @@ from tidalapi import Playlist as TidalPlaylist
 from tidalapi import Session as TidalSession
 from tidalapi import Track as TidalTrack
 from tidalapi import UserPlaylist as TidalUserPlaylist
-from tidalapi.exceptions import ObjectNotFound, TooManyRequests
+from tidalapi.exceptions import (
+    MetadataNotAvailable,
+    ObjectNotFound,
+    TooManyRequests,
+    URLNotAvailable,
+)
 
 from music_assistant.common.models.enums import MediaType
 from music_assistant.common.models.errors import MediaNotFoundError
@@ -179,7 +184,7 @@ async def get_track_url(session: TidalSession, prov_track_id: str) -> str:
         try:
             track_url: str = TidalTrack(session, prov_track_id).get_url()
             return track_url
-        except (ObjectNotFound, TooManyRequests) as err:
+        except (ObjectNotFound, TooManyRequests, URLNotAvailable) as err:
             msg = f"Track {prov_track_id} not found"
             raise MediaNotFoundError(msg) from err
 
@@ -301,7 +306,7 @@ async def get_similar_tracks(
                 limit=limit
             )
             return tracks
-        except (ObjectNotFound, TooManyRequests) as err:
+        except (MetadataNotAvailable, ObjectNotFound, TooManyRequests) as err:
             msg = f"Track {prov_track_id} not found"
             raise MediaNotFoundError(msg) from err