huge refactor of the entire codebase, with the goal of improving maintainability, readability, and extensibility. This commit includes changes to almost every file in the project, including:

This commit is contained in:
2026-04-19 00:41:09 -07:00
parent d9e736172a
commit bafd37fdfb
50 changed files with 3258 additions and 4177 deletions
+59 -3
View File
@@ -64,7 +64,7 @@ def _format_total_seconds(seconds: Any) -> str:
class Tidal(Provider):
PROVIDER_NAME = "tidal"
PLUGIN_NAME = "tidal"
TABLE_AUTO_STAGES = {
"tidal.track": ["download-file"],
@@ -82,7 +82,7 @@ class Tidal(Provider):
"tidal.com",
"listen.tidal.com",
)
URL = URL_DOMAINS
URL = URL_DOMAINS + ("tidal:",)
"""Provider that targets the Tidal search endpoint.
The CLI can supply a list of fail-over URLs via ``provider.tidal.api_urls`` or
@@ -210,6 +210,9 @@ class Tidal(Provider):
self.api_timeout = 10.0
self.api_clients = [TidalApiClient(base_url=url, timeout=self.api_timeout) for url in self.api_urls]
def resolve_playback_path(self, item: Any, **_kwargs: Any) -> Optional[str]:
return resolve_tidal_manifest_path(item)
def extract_query_arguments(self, query: str) -> Tuple[str, Dict[str, Any]]:
"""Parse inline `key:value` query arguments.
@@ -2398,4 +2401,57 @@ class Tidal(Provider):
except Exception:
pass
return True
return True
def expand_selection(
self,
selected_items: List[Any],
*,
ctx: Any,
stage_is_last: bool = True,
table_type: str = "",
**_kwargs: Any,
) -> Optional[List[Any]]:
_ = ctx
if stage_is_last:
return None
normalized_table = str(table_type or "").strip().lower()
if normalized_table != "tidal.album":
return None
try:
contexts = self._extract_album_selection_context(selected_items)
except Exception:
return None
if not contexts:
return None
track_items: List[Any] = []
seen_track_ids: set[int] = set()
for album_id, album_title, artist_name in contexts:
try:
track_results = self._tracks_for_album(
album_id=album_id,
album_title=album_title,
artist_name=artist_name,
limit=500,
)
except Exception:
track_results = []
for track in track_results or []:
try:
metadata = getattr(track, "full_metadata", None)
track_id = None
if isinstance(metadata, dict):
raw_id = metadata.get("trackId") or metadata.get("id")
track_id = int(raw_id) if raw_id is not None else None
if track_id is not None:
if track_id in seen_track_ids:
continue
seen_track_ids.add(track_id)
except Exception:
pass
track_items.append(track)
return track_items or None