Handle API errors for deezer downloads #487

This commit is contained in:
Nathan Thomas 2023-12-21 17:02:25 -08:00
parent 779533a234
commit b1e4369f5d
6 changed files with 63 additions and 18 deletions

View file

@ -56,10 +56,3 @@ class Client(ABC):
headers={"User-Agent": DEFAULT_USER_AGENT},
**headers,
)
def __del__(self):
# make sure http session is closed by end of program
# if hasattr(self, "session"):
# loop = asyncio.get_event_loop()
# loop.run_until_complete(self.session.close())
pass

View file

@ -61,7 +61,11 @@ class DeezerClient(Client):
raise Exception(f"Media type {media_type} not available on deezer")
async def get_track(self, item_id: str) -> dict:
item = await asyncio.to_thread(self.client.api.get_track, item_id)
try:
item = await asyncio.to_thread(self.client.api.get_track, item_id)
except Exception as e:
raise NonStreamable(e)
album_id = item["album"]["id"]
try:
album_metadata, album_tracks = await asyncio.gather(
@ -69,7 +73,7 @@ class DeezerClient(Client):
asyncio.to_thread(self.client.api.get_album_tracks, album_id),
)
except Exception as e:
logger.error("Got exception from deezer API %s", e)
logger.error(f"Error fetching album of track {item_id}: {e}")
return item
album_metadata["tracks"] = album_tracks["data"]

View file

@ -278,7 +278,6 @@ class QobuzClient(Client):
params = {
"query": query,
# "limit": limit,
}
epoint = f"{media_type}/search"

View file

@ -45,7 +45,11 @@ class PendingPlaylistTrack(Pending):
if self.db.downloaded(self.id):
logger.info(f"Track ({self.id}) already logged in database. Skipping.")
return None
resp = await self.client.get_metadata(self.id, "track")
try:
resp = await self.client.get_metadata(self.id, "track")
except NonStreamable as e:
logger.error(f"Could not stream track {self.id}: {e}")
return None
album = AlbumMetadata.from_track_resp(resp, self.client.source)
if album is None:

View file

@ -103,8 +103,13 @@ class PendingTrack(Pending):
)
return None
resp = await self.client.get_metadata(self.id, "track")
source = self.client.source
try:
resp = await self.client.get_metadata(self.id, "track")
except NonStreamable as e:
logger.error(f"Track {self.id} not available for stream on {source}: {e}")
return None
meta = TrackMetadata.from_resp(self.album, source, resp)
if meta is None:
logger.error(f"Track {self.id} not available for stream on {source}")
@ -149,7 +154,6 @@ class PendingSingle(Pending):
logger.error(f"Error fetching track {self.id}: {e}")
return None
# Patch for soundcloud
# self.id = resp["id"]
album = AlbumMetadata.from_track_resp(resp, self.client.source)
if album is None:
self.db.set_failed(self.client.source, "track", self.id)

View file

@ -110,12 +110,7 @@ class AlbumMetadata:
explicit = typed(resp.get("parental_warning", False), bool)
# Non-embedded information
# version = resp.get("version")
cover_urls = Covers.from_qobuz(resp)
# streamable = typed(resp.get("streamable", False), bool)
#
# if not streamable:
# raise NonStreamable(resp)
bit_depth = typed(resp.get("maximum_bit_depth"), int | None)
sampling_rate = typed(resp.get("maximum_sampling_rate"), int | float | None)
@ -162,10 +157,12 @@ class AlbumMetadata:
@classmethod
def from_deezer(cls, resp: dict) -> AlbumMetadata | None:
print(resp.keys())
album = resp.get("title", "Unknown Album")
tracktotal = typed(resp.get("track_total", 0) or resp.get("nb_tracks", 0), int)
disctotal = typed(resp["tracks"][-1]["disk_number"], int)
genres = [typed(g["name"], str) for g in resp["genres"]["data"]]
date = typed(resp["release_date"], str)
year = date[:4]
_copyright = None
@ -448,6 +445,48 @@ class AlbumMetadata:
tracktotal=tracktotal,
)
@classmethod
def from_incomplete_deezer_track_resp(cls, resp: dict) -> AlbumMetadata | None:
album_resp = resp["album"]
album_id = album_resp["id"]
album = album_resp["title"]
covers = Covers.from_deezer(album_resp)
date = album_resp["release_date"]
year = date[:4]
albumartist = ", ".join(a["name"] for a in resp["contributors"])
explicit = resp.get("explicit_lyrics", False)
info = AlbumInfo(
id=album_id,
quality=2,
container="MP4",
label=None,
explicit=explicit,
sampling_rate=None,
bit_depth=None,
booklets=None,
)
return AlbumMetadata(
info,
album,
albumartist,
year,
genre=[],
covers=covers,
albumcomposer=None,
comment=None,
compilation=None,
copyright=None,
date=date,
description=None,
disctotal=1,
encoder=None,
grouping=None,
lyrics=None,
purchase_date=None,
tracktotal=1,
)
@classmethod
def from_track_resp(cls, resp: dict, source: str) -> AlbumMetadata | None:
if source == "qobuz":
@ -457,6 +496,8 @@ class AlbumMetadata:
if source == "soundcloud":
return cls.from_soundcloud(resp)
if source == "deezer":
if "tracks" not in resp["album"]:
return cls.from_incomplete_deezer_track_resp(resp)
return cls.from_deezer(resp["album"])
raise Exception("Invalid source")