diff --git a/setup.py b/setup.py index 2602d06..cc941e9 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ requirements = read_file("requirements.txt").strip().split() # https://github.com/pypa/sampleproject/blob/main/setup.py setup( name=pkg_name, - version="0.3", + version="0.3.1", author="Nathan", author_email="nathanthomas707@gmail.com", keywords="lossless, hi-res, qobuz, tidal, deezer, audio, convert", @@ -30,14 +30,12 @@ setup( }, packages=find_packages(), classifiers=[ - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", - "Development Status :: 3 - Alpha", ], - python_requires=">=3.7", + python_requires=">=3.8", project_urls={ "Source": "https://github.com/nathom/streamrip", "Bug Reports": "https://github.com/nathom/streamrip/issues", diff --git a/streamrip/clients.py b/streamrip/clients.py index 3c2b45d..6b3479e 100644 --- a/streamrip/clients.py +++ b/streamrip/clients.py @@ -628,7 +628,17 @@ class TidalClient(ClientInterface): url = f"{media_type}s/{item_id}" item = self._api_request(url) if media_type in ("playlist", "album"): + resp = self._api_request(f"{url}/items") + if (tracks_left := item["numberOfTracks"]) > 100: + offset = 0 + while tracks_left > 0: + offset += 100 + tracks_left -= 100 + resp["items"].extend( + self._api_request(f"{url}/items", {"offset": offset})["items"] + ) + item["tracks"] = [item["item"] for item in resp["items"]] elif media_type == "artist": resp = self._api_request(f"{url}/albums") diff --git a/streamrip/downloader.py b/streamrip/downloader.py index 0169214..229b987 100644 --- a/streamrip/downloader.py +++ b/streamrip/downloader.py @@ -335,6 +335,7 @@ class Track: """ tracklist = cls._get_tracklist(album, client.source) + logger.debug(len(tracklist)) track = tracklist[pos] meta = TrackMetadata(album=album, track=track, source=client.source) return cls(client=client, meta=meta, id=track["id"]) @@ -783,7 +784,7 @@ class Album(Tracklist): "bit_depth": 24 if resp.get("audioQuality") == "HI_RES" else 16, "sampling_rate": 44100, # always 44.1 kHz "tracktotal": resp.get("numberOfTracks"), - "disctotal": 1, + "disctotal": resp.get("numberOfVolumes"), } elif client.source == "deezer": if resp.get("release_date", False): diff --git a/streamrip/metadata.py b/streamrip/metadata.py index 27ea068..ee23d9f 100644 --- a/streamrip/metadata.py +++ b/streamrip/metadata.py @@ -110,6 +110,8 @@ class TrackMetadata: self.date = resp.get("releaseDate") self.copyright = resp.get("copyright") self.albumartist = resp.get("artist", {}).get("name") + self.disctotal = resp.get("numberOfVolumes") + self.isrc = resp.get("isrc") # label not returned by API elif self.__source == "deezer": diff --git a/streamrip/utils.py b/streamrip/utils.py index 62099cf..1c84816 100644 --- a/streamrip/utils.py +++ b/streamrip/utils.py @@ -2,8 +2,9 @@ import base64 import logging import logging.handlers as handlers import os +import time from string import Formatter -from typing import Optional, Union +from typing import Hashable, Optional, Union import requests from Crypto.Cipher import AES @@ -17,7 +18,7 @@ from .exceptions import InvalidSourceError, NonStreamable logger = logging.getLogger(__name__) -def safe_get(d: dict, *keys, default=None): +def safe_get(d: dict, *keys: Hashable, default=None): """A replacement for chained `get()` statements on dicts: >>> d = {'foo': {'bar': 'baz'}} >>> _safe_get(d, 'baz') @@ -157,12 +158,8 @@ def tidal_cover_url(uuid, size): return TIDAL_COVER_URL.format(uuid=uuid.replace("-", "/"), height=size, width=size) -def init_log( - path: Optional[str] = None, level: str = "DEBUG", rotate: str = "midnight" -): - """ - Initialize a log instance with a stream handler and a rotating file handler. - If a path is not set, fallback to the default app log directory. +def init_log(path: Optional[str] = None, level: str = "DEBUG"): + """Create a log. :param path: :type path: Optional[str] @@ -171,29 +168,9 @@ def init_log( :param rotate: :type rotate: str """ - if not path: - os.makedirs(LOG_DIR, exist_ok=True) - path = os.path.join(LOG_DIR, "streamrip") - - logger = logging.getLogger() + path = os.path.join(LOG_DIR, "streamrip.log") level = logging.getLevelName(level) - logger.setLevel(level) - - formatter = logging.Formatter( - fmt="%(asctime)s - %(module)s.%(funcName)s.%(levelname)s: %(message)s", - datefmt="%H:%M:%S", - ) - - rotable = handlers.TimedRotatingFileHandler(path, when=rotate) - printable = logging.StreamHandler() - - rotable.setFormatter(formatter) - printable.setFormatter(formatter) - - logger.addHandler(printable) - logger.addHandler(rotable) - - logging.getLogger("urllib3").setLevel(logging.DEBUG) + logging.basicConfig(filename=path, filemode="a", level=level) def capitalize(s: str) -> str: