Added support for Tidal artists

Also improved download message, formatting
This commit is contained in:
nathom 2021-03-29 18:00:14 -07:00
parent 561d2a5894
commit b050064ccf
4 changed files with 45 additions and 42 deletions

View file

@ -15,9 +15,9 @@ requirements = read_file("requirements.txt").strip().split()
setup(
name=pkg_name,
version="0.2.8",
author='Nathan',
author_email='nathanthomas707@gmail.com',
keywords='lossless, hi-res, qobuz, tidal, deezer, audio, convert',
author="Nathan",
author_email="nathanthomas707@gmail.com",
keywords="lossless, hi-res, qobuz, tidal, deezer, audio, convert",
description="A stream downloader for Qobuz, Tidal, and Deezer.",
long_description=read_file("README.md"),
long_description_content_type="text/markdown",

View file

@ -630,10 +630,14 @@ class TidalClient(ClientInterface):
self.access_token = token
def _api_get(self, item_id: str, media_type: str) -> dict:
item = self._api_request(f"{media_type}s/{item_id}")
url = f"{media_type}s/{item_id}"
item = self._api_request(url)
if media_type in ("playlist", "album"):
resp = self._api_request(f"{media_type}s/{item_id}/items")
resp = self._api_request(f"{url}/items")
item["tracks"] = [item["item"] for item in resp["items"]]
elif media_type == "artist":
resp = self._api_request(f"{url}/albums")
item["albums"] = resp["items"]
return item

View file

@ -124,8 +124,8 @@ class MusicDL(list):
arguments = {
"database": self.db,
"parent_folder": self.config.session["downloads"]["folder"],
"keep_cover": self.config.session['keep_cover'],
"large_cover": self.config.session['metadata']['large_cover'],
"keep_cover": self.config.session["keep_cover"],
"large_cover": self.config.session["metadata"]["large_cover"],
# TODO: fully implement this
# "embed_cover": self.config.session["metadata"]["embed_cover"],
}
@ -140,7 +140,6 @@ class MusicDL(list):
logger.debug("Added filter argument for artist/label: %s", filters_)
item.load_meta()
click.secho(f"Downloading {item!s}", fg="bright_green")
if isinstance(item, Track):
# track.download doesn't automatically tag
@ -152,10 +151,6 @@ class MusicDL(list):
self.db.add(item.id)
if self.config.session["conversion"]["enabled"]:
click.secho(
f"Converting {item!s} to {self.config.session['conversion']['codec']}",
fg="cyan",
)
item.convert(**self.config.session["conversion"])
def get_client(self, source: str):
@ -165,11 +160,6 @@ class MusicDL(list):
self.login(client)
return client
def convert_all(self, codec, **kwargs):
click.secho("Converting the downloaded tracks...", fg="cyan")
for item in self:
item.convert(codec, **kwargs)
def login(self, client):
creds = self.config.creds(client.source)
if not client.logged_in:

View file

@ -506,20 +506,6 @@ class Tracklist(list):
IndexError
"""
def __getitem__(self, key: Union[str, int]):
if isinstance(key, str):
return getattr(self, key)
if isinstance(key, int):
return super().__getitem__(key)
def __setitem__(self, key: Union[str, int], val: Any):
if isinstance(key, str):
setattr(self, key, val)
if isinstance(key, int):
super().__setitem__(key, val)
def get(self, key: Union[str, int], default: Optional[Any]):
if isinstance(key, str):
if hasattr(self, key):
@ -596,6 +582,12 @@ class Tracklist(list):
return cover_obj
def download_message(self):
click.secho(
f"\nDownloading {self.title} ({self.__class__.__name__})\n",
fg="blue",
)
@staticmethod
def _parse_get_resp(item, client):
pass
@ -616,6 +608,20 @@ class Tracklist(list):
return album
def __getitem__(self, key: Union[str, int]):
if isinstance(key, str):
return getattr(self, key)
if isinstance(key, int):
return super().__getitem__(key)
def __setitem__(self, key: Union[str, int], val: Any):
if isinstance(key, str):
setattr(self, key, val)
if isinstance(key, int):
super().__setitem__(key, val)
class Album(Tracklist):
"""Represents a downloadable album.
@ -809,10 +815,11 @@ class Album(Tracklist):
if os.path.isfile(cover_path):
logger.debug("Cover already downloaded: %s. Skipping", cover_path)
else:
click.secho("Downloading cover art", fg="magenta")
if kwargs.get("large_cover", False):
cover_url = self.cover_urls.get("large")
if self.client.source == 'qobuz':
tqdm_download(cover_url.replace('600', 'org'), cover_path)
if self.client.source == "qobuz":
tqdm_download(cover_url.replace("600", "org"), cover_path)
else:
tqdm_download(cover_url, cover_path)
@ -825,15 +832,17 @@ class Album(Tracklist):
shutil.move(cover_path, large_cover_path)
tqdm_download(self.cover_urls["small"], cover_path)
else:
tqdm_download(self.cover_urls['small'], cover_path)
tqdm_download(self.cover_urls["small"], cover_path)
if self.client.source != "deezer":
cover = self.get_cover_obj(cover_path, quality)
self.download_message()
for track in self:
logger.debug("Downloading track to %s", folder)
track.download(quality, folder, kwargs.get("progress_bar", True), database=database)
track.download(
quality, folder, kwargs.get("progress_bar", True), database=database
)
if kwargs.get("tag_tracks", True) and self.client.source != "deezer":
track.tag(cover=cover)
@ -1030,6 +1039,7 @@ class Playlist(Tracklist):
folder = os.path.join(parent_folder, folder)
logger.debug(f"Parent folder {folder}")
self.download_message()
for track in self:
track.download(parent_folder=folder, quality=quality, database=database)
if self.client.source != "deezer":
@ -1121,8 +1131,8 @@ class Artist(Tracklist):
albums = self.meta["albums"]["items"]
elif self.client.source == "tidal":
self.name = self.meta["items"][0]["artist"]["name"]
albums = self.meta["items"]
self.name = self.meta["name"]
albums = self.meta["albums"]
elif self.client.source == "deezer":
# TODO: load artist name
@ -1142,6 +1152,7 @@ class Artist(Tracklist):
no_repeats: bool = False,
quality: int = 6,
database: MusicDB = None,
**kwargs,
):
"""Download all albums in the discography.
@ -1175,9 +1186,8 @@ class Artist(Tracklist):
final = filter(inter, final)
i = 0
self.download_message()
for album in final:
i += 1
click.secho(f"Downloading album: {album}", fg="blue")
try:
album.load_meta()
@ -1187,10 +1197,9 @@ class Artist(Tracklist):
parent_folder=folder,
quality=quality,
database=database,
**kwargs,
)
logger.debug(f"{i} albums downloaded")
@property
def title(self):
return self.name