Tidal provider maintenance: add tidaluser class (#2010)
authorJozef Kruszynski <60214390+jozefKruszynski@users.noreply.github.com>
Sat, 8 Mar 2025 23:50:39 +0000 (00:50 +0100)
committerGitHub <noreply@github.com>
Sat, 8 Mar 2025 23:50:39 +0000 (00:50 +0100)
music_assistant/providers/tidal/__init__.py
music_assistant/providers/tidal/auth_manager.py

index be57780336296e232112b8682666e3dfdb774bc4..fb03c7b971cffc2095c407127dc536439e381e2a 100644 (file)
@@ -377,7 +377,8 @@ class TidalProvider(MusicProvider):
         # Get user information from sessions API
         api_result = await self._get_data("sessions")
         user_info = self._extract_data(api_result)
-        await self.auth.update_user_info(user_info)
+        logged_in_user = await self.get_user(str(user_info.get("userId")))
+        await self.auth.update_user_info(logged_in_user, str(user_info.get("sessionId")))
 
     @property
     def supported_features(self) -> set[ProviderFeature]:
@@ -614,6 +615,11 @@ class TidalProvider(MusicProvider):
     # SEARCH & DISCOVERY
     #
 
+    async def get_user(self, prov_user_id: str) -> dict[str, Any]:
+        """Get user information."""
+        api_result = await self._get_data(f"users/{prov_user_id}")
+        return self._extract_data(api_result)
+
     async def search(
         self,
         search_query: str,
@@ -1313,11 +1319,20 @@ class TidalProvider(MusicProvider):
         if playlist_obj["creator"]:
             creator_id = playlist_obj["creator"]["id"]
         is_editable = bool(creator_id and str(creator_id) == str(self.auth.user_id))
+
+        owner_name = "Tidal"
+        if is_editable:
+            if self.auth.user.profile_name:
+                owner_name = self.auth.user.profile_name
+            elif self.auth.user.user_name:
+                owner_name = self.auth.user.user_name
+            else:
+                owner_name = str(self.auth.user_id or "Unknown")
         playlist = Playlist(
             item_id=playlist_id,
             provider=self.instance_id if is_editable else self.lookup_key,
             name=playlist_obj["title"],
-            owner=creator_id or "Tidal",
+            owner=owner_name,
             provider_mappings={
                 ProviderMapping(
                     item_id=playlist_id,
index b6b636348f37126732d57e77a5a42458245f09b7..e55f0099b53df3339ea65ceb2b30e1aa0ebb8e7f 100644 (file)
@@ -5,6 +5,7 @@ import random
 import time
 import urllib
 from collections.abc import Callable
+from dataclasses import dataclass
 from types import TracebackType
 from typing import TYPE_CHECKING, Any
 
@@ -24,6 +25,18 @@ AUTH_URL = "https://auth.tidal.com/v1/oauth2"
 REDIRECT_URI = "https://tidal.com/android/login/auth"
 
 
+@dataclass
+class TidalUser:
+    """Represent a Tidal user with their associated account information."""
+
+    user_id: str | None = None
+    country_code: str | None = None
+    session_id: str | None = None
+    profile_name: str | None = None
+    user_name: str | None = None
+    email: str | None = None
+
+
 class ManualAuthenticationHelper:
     """Helper for authentication flows that require manual user intervention.
 
@@ -68,9 +81,7 @@ class TidalAuthManager:
         self.update_config = config_updater
         self.logger = logger
         self._auth_info = None
-        self._user_id = None
-        self._country_code = None
-        self._session_id = None
+        self.user = TidalUser()
 
     async def initialize(self, auth_data: str) -> bool:
         """Initialize the auth manager with stored auth data."""
@@ -86,17 +97,17 @@ class TidalAuthManager:
     @property
     def user_id(self) -> str | None:
         """Return the current user ID."""
-        return self._user_id
+        return self.user.user_id
 
     @property
     def country_code(self) -> str | None:
         """Return the current country code."""
-        return self._country_code
+        return self.user.country_code
 
     @property
     def session_id(self) -> str | None:
         """Return the current session ID."""
-        return self._session_id
+        return self.user.session_id
 
     @property
     def access_token(self) -> str | None:
@@ -159,11 +170,16 @@ class TidalAuthManager:
 
             return True
 
-    async def update_user_info(self, user_info: dict[str, Any]) -> None:
+    async def update_user_info(self, user_info: dict[str, Any], session_id: str) -> None:
         """Update user info from API response."""
-        self._user_id = user_info.get("userId")
-        self._country_code = user_info.get("countryCode")
-        self._session_id = user_info.get("sessionId")
+        # Update the TidalUser dataclass with values from API response
+        self.user = TidalUser(
+            user_id=user_info.get("id"),
+            country_code=user_info.get("countryCode"),
+            session_id=session_id,
+            profile_name=user_info.get("profileName"),
+            user_name=user_info.get("username"),
+        )
 
     @staticmethod
     async def generate_auth_url(auth_helper: ManualAuthenticationHelper, quality: str) -> str: