mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-13 14:44:49 -04:00
Added support for Tidal artists
Also improved download message, formatting
This commit is contained in:
parent
561d2a5894
commit
b050064ccf
4 changed files with 45 additions and 42 deletions
6
setup.py
6
setup.py
|
@ -15,9 +15,9 @@ requirements = read_file("requirements.txt").strip().split()
|
||||||
setup(
|
setup(
|
||||||
name=pkg_name,
|
name=pkg_name,
|
||||||
version="0.2.8",
|
version="0.2.8",
|
||||||
author='Nathan',
|
author="Nathan",
|
||||||
author_email='nathanthomas707@gmail.com',
|
author_email="nathanthomas707@gmail.com",
|
||||||
keywords='lossless, hi-res, qobuz, tidal, deezer, audio, convert',
|
keywords="lossless, hi-res, qobuz, tidal, deezer, audio, convert",
|
||||||
description="A stream downloader for Qobuz, Tidal, and Deezer.",
|
description="A stream downloader for Qobuz, Tidal, and Deezer.",
|
||||||
long_description=read_file("README.md"),
|
long_description=read_file("README.md"),
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
|
|
@ -630,10 +630,14 @@ class TidalClient(ClientInterface):
|
||||||
self.access_token = token
|
self.access_token = token
|
||||||
|
|
||||||
def _api_get(self, item_id: str, media_type: str) -> dict:
|
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"):
|
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"]]
|
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
|
return item
|
||||||
|
|
||||||
|
|
|
@ -124,8 +124,8 @@ class MusicDL(list):
|
||||||
arguments = {
|
arguments = {
|
||||||
"database": self.db,
|
"database": self.db,
|
||||||
"parent_folder": self.config.session["downloads"]["folder"],
|
"parent_folder": self.config.session["downloads"]["folder"],
|
||||||
"keep_cover": self.config.session['keep_cover'],
|
"keep_cover": self.config.session["keep_cover"],
|
||||||
"large_cover": self.config.session['metadata']['large_cover'],
|
"large_cover": self.config.session["metadata"]["large_cover"],
|
||||||
# TODO: fully implement this
|
# TODO: fully implement this
|
||||||
# "embed_cover": self.config.session["metadata"]["embed_cover"],
|
# "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_)
|
logger.debug("Added filter argument for artist/label: %s", filters_)
|
||||||
|
|
||||||
item.load_meta()
|
item.load_meta()
|
||||||
click.secho(f"Downloading {item!s}", fg="bright_green")
|
|
||||||
|
|
||||||
if isinstance(item, Track):
|
if isinstance(item, Track):
|
||||||
# track.download doesn't automatically tag
|
# track.download doesn't automatically tag
|
||||||
|
@ -152,10 +151,6 @@ class MusicDL(list):
|
||||||
self.db.add(item.id)
|
self.db.add(item.id)
|
||||||
|
|
||||||
if self.config.session["conversion"]["enabled"]:
|
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"])
|
item.convert(**self.config.session["conversion"])
|
||||||
|
|
||||||
def get_client(self, source: str):
|
def get_client(self, source: str):
|
||||||
|
@ -165,11 +160,6 @@ class MusicDL(list):
|
||||||
self.login(client)
|
self.login(client)
|
||||||
return 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):
|
def login(self, client):
|
||||||
creds = self.config.creds(client.source)
|
creds = self.config.creds(client.source)
|
||||||
if not client.logged_in:
|
if not client.logged_in:
|
||||||
|
|
|
@ -506,20 +506,6 @@ class Tracklist(list):
|
||||||
IndexError
|
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]):
|
def get(self, key: Union[str, int], default: Optional[Any]):
|
||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
if hasattr(self, key):
|
if hasattr(self, key):
|
||||||
|
@ -596,6 +582,12 @@ class Tracklist(list):
|
||||||
|
|
||||||
return cover_obj
|
return cover_obj
|
||||||
|
|
||||||
|
def download_message(self):
|
||||||
|
click.secho(
|
||||||
|
f"\nDownloading {self.title} ({self.__class__.__name__})\n",
|
||||||
|
fg="blue",
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_get_resp(item, client):
|
def _parse_get_resp(item, client):
|
||||||
pass
|
pass
|
||||||
|
@ -616,6 +608,20 @@ class Tracklist(list):
|
||||||
|
|
||||||
return album
|
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):
|
class Album(Tracklist):
|
||||||
"""Represents a downloadable album.
|
"""Represents a downloadable album.
|
||||||
|
@ -809,10 +815,11 @@ class Album(Tracklist):
|
||||||
if os.path.isfile(cover_path):
|
if os.path.isfile(cover_path):
|
||||||
logger.debug("Cover already downloaded: %s. Skipping", cover_path)
|
logger.debug("Cover already downloaded: %s. Skipping", cover_path)
|
||||||
else:
|
else:
|
||||||
|
click.secho("Downloading cover art", fg="magenta")
|
||||||
if kwargs.get("large_cover", False):
|
if kwargs.get("large_cover", False):
|
||||||
cover_url = self.cover_urls.get("large")
|
cover_url = self.cover_urls.get("large")
|
||||||
if self.client.source == 'qobuz':
|
if self.client.source == "qobuz":
|
||||||
tqdm_download(cover_url.replace('600', 'org'), cover_path)
|
tqdm_download(cover_url.replace("600", "org"), cover_path)
|
||||||
else:
|
else:
|
||||||
tqdm_download(cover_url, cover_path)
|
tqdm_download(cover_url, cover_path)
|
||||||
|
|
||||||
|
@ -825,15 +832,17 @@ class Album(Tracklist):
|
||||||
shutil.move(cover_path, large_cover_path)
|
shutil.move(cover_path, large_cover_path)
|
||||||
tqdm_download(self.cover_urls["small"], cover_path)
|
tqdm_download(self.cover_urls["small"], cover_path)
|
||||||
else:
|
else:
|
||||||
tqdm_download(self.cover_urls['small'], cover_path)
|
tqdm_download(self.cover_urls["small"], cover_path)
|
||||||
|
|
||||||
if self.client.source != "deezer":
|
if self.client.source != "deezer":
|
||||||
cover = self.get_cover_obj(cover_path, quality)
|
cover = self.get_cover_obj(cover_path, quality)
|
||||||
|
|
||||||
|
self.download_message()
|
||||||
for track in self:
|
for track in self:
|
||||||
logger.debug("Downloading track to %s", folder)
|
logger.debug("Downloading track to %s", folder)
|
||||||
|
track.download(
|
||||||
track.download(quality, folder, kwargs.get("progress_bar", True), database=database)
|
quality, folder, kwargs.get("progress_bar", True), database=database
|
||||||
|
)
|
||||||
if kwargs.get("tag_tracks", True) and self.client.source != "deezer":
|
if kwargs.get("tag_tracks", True) and self.client.source != "deezer":
|
||||||
track.tag(cover=cover)
|
track.tag(cover=cover)
|
||||||
|
|
||||||
|
@ -1030,6 +1039,7 @@ class Playlist(Tracklist):
|
||||||
folder = os.path.join(parent_folder, folder)
|
folder = os.path.join(parent_folder, folder)
|
||||||
logger.debug(f"Parent folder {folder}")
|
logger.debug(f"Parent folder {folder}")
|
||||||
|
|
||||||
|
self.download_message()
|
||||||
for track in self:
|
for track in self:
|
||||||
track.download(parent_folder=folder, quality=quality, database=database)
|
track.download(parent_folder=folder, quality=quality, database=database)
|
||||||
if self.client.source != "deezer":
|
if self.client.source != "deezer":
|
||||||
|
@ -1121,8 +1131,8 @@ class Artist(Tracklist):
|
||||||
albums = self.meta["albums"]["items"]
|
albums = self.meta["albums"]["items"]
|
||||||
|
|
||||||
elif self.client.source == "tidal":
|
elif self.client.source == "tidal":
|
||||||
self.name = self.meta["items"][0]["artist"]["name"]
|
self.name = self.meta["name"]
|
||||||
albums = self.meta["items"]
|
albums = self.meta["albums"]
|
||||||
|
|
||||||
elif self.client.source == "deezer":
|
elif self.client.source == "deezer":
|
||||||
# TODO: load artist name
|
# TODO: load artist name
|
||||||
|
@ -1142,6 +1152,7 @@ class Artist(Tracklist):
|
||||||
no_repeats: bool = False,
|
no_repeats: bool = False,
|
||||||
quality: int = 6,
|
quality: int = 6,
|
||||||
database: MusicDB = None,
|
database: MusicDB = None,
|
||||||
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Download all albums in the discography.
|
"""Download all albums in the discography.
|
||||||
|
|
||||||
|
@ -1175,9 +1186,8 @@ class Artist(Tracklist):
|
||||||
|
|
||||||
final = filter(inter, final)
|
final = filter(inter, final)
|
||||||
|
|
||||||
i = 0
|
self.download_message()
|
||||||
for album in final:
|
for album in final:
|
||||||
i += 1
|
|
||||||
click.secho(f"Downloading album: {album}", fg="blue")
|
click.secho(f"Downloading album: {album}", fg="blue")
|
||||||
try:
|
try:
|
||||||
album.load_meta()
|
album.load_meta()
|
||||||
|
@ -1187,10 +1197,9 @@ class Artist(Tracklist):
|
||||||
parent_folder=folder,
|
parent_folder=folder,
|
||||||
quality=quality,
|
quality=quality,
|
||||||
database=database,
|
database=database,
|
||||||
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f"{i} albums downloaded")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title(self):
|
def title(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue