From: Jozef Kruszynski <60214390+jozefKruszynski@users.noreply.github.com> Date: Wed, 26 Feb 2025 20:20:43 +0000 (+0100) Subject: fix(tidal): refresh access token correctly (#1984) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=8126e5e0ab14a91c7ab2e6295e4a98b85588ae57;p=music-assistant-server.git fix(tidal): refresh access token correctly (#1984) --- diff --git a/music_assistant/providers/tidal/__init__.py b/music_assistant/providers/tidal/__init__.py index 20661290..d2fb5de8 100644 --- a/music_assistant/providers/tidal/__init__.py +++ b/music_assistant/providers/tidal/__init__.py @@ -7,11 +7,15 @@ import base64 import pickle from collections.abc import Callable from contextlib import suppress -from datetime import datetime, timedelta +from datetime import UTC, datetime, timedelta from enum import StrEnum from typing import TYPE_CHECKING, ParamSpec, TypeVar, cast -from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType +from music_assistant_models.config_entries import ( + ConfigEntry, + ConfigValueOption, + ConfigValueType, +) from music_assistant_models.enums import ( AlbumType, CacheCategory, @@ -48,7 +52,10 @@ from tidalapi import exceptions as tidal_exceptions from music_assistant.helpers.auth import AuthenticationHelper from music_assistant.helpers.tags import AudioTags, async_parse_tags -from music_assistant.helpers.throttle_retry import ThrottlerManager, throttle_with_retries +from music_assistant.helpers.throttle_retry import ( + ThrottlerManager, + throttle_with_retries, +) from music_assistant.models.music_provider import MusicProvider from .helpers import ( @@ -74,6 +81,7 @@ from .helpers import ( library_items_add_remove, remove_playlist_tracks, search, + token_refresh, ) if TYPE_CHECKING: @@ -658,11 +666,13 @@ class TidalProvider(MusicProvider): async def _get_tidal_session(self) -> TidalSession: """Ensure the current token is valid and return a tidal session.""" + token_expiry = datetime.fromisoformat(str(self.config.get_value(CONF_EXPIRY_TIME))) + token_expiry_with_tz = token_expiry.replace(tzinfo=UTC) + utc_now_plus_one_hour = datetime.now(UTC) + timedelta(hours=1) if ( self._tidal_session and self._tidal_session.access_token - and datetime.fromisoformat(str(self.config.get_value(CONF_EXPIRY_TIME))) - > (datetime.now() + timedelta(days=1)) + and token_expiry_with_tz > utc_now_plus_one_hour ): return self._tidal_session @@ -674,6 +684,8 @@ class TidalProvider(MusicProvider): refresh_token=str(self.config.get_value(CONF_REFRESH_TOKEN)), expiry_time=datetime.fromisoformat(str(self.config.get_value(CONF_EXPIRY_TIME))), ) + await token_refresh(self._tidal_session) + except Exception as err: if "401 Client Error: Unauthorized" in str(err): err_msg = "Credentials expired, you need to re-setup" @@ -773,7 +785,10 @@ class TidalProvider(MusicProvider): # Cache the mapping for future use await self.mass.cache.set( - cache_key, tracks[0].id, category=CacheCategory.DEFAULT, base_key=self.lookup_key + cache_key, + tracks[0].id, + category=CacheCategory.DEFAULT, + base_key=self.lookup_key, ) return tracks[0] diff --git a/music_assistant/providers/tidal/helpers.py b/music_assistant/providers/tidal/helpers.py index ec87e05b..24e1805b 100644 --- a/music_assistant/providers/tidal/helpers.py +++ b/music_assistant/providers/tidal/helpers.py @@ -422,3 +422,12 @@ async def search( return results return await asyncio.to_thread(inner) + + +async def token_refresh(session: TidalSession) -> None: + """Async wrapper around the tidalapi Session.refresh function.""" + + def inner() -> None: + session.token_refresh(session.refresh_token) + + return await asyncio.to_thread(inner)