mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-17 00:24:50 -04:00
Reformat track numbers, make progress bars look better
This commit is contained in:
parent
1f4e796d40
commit
13e8b548ea
6 changed files with 31 additions and 17 deletions
|
@ -489,7 +489,7 @@ class TidalClient(ClientInterface):
|
||||||
try:
|
try:
|
||||||
manifest = json.loads(base64.b64decode(resp["manifest"]).decode("utf-8"))
|
manifest = json.loads(base64.b64decode(resp["manifest"]).decode("utf-8"))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise Exception("You must have a TIDAL Hi-Fi account to download tracks.")
|
raise Exception(resp['userMessage'])
|
||||||
|
|
||||||
logger.debug(manifest)
|
logger.debug(manifest)
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -27,14 +27,12 @@ class Config:
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
>>> config = Config('test_config.yaml')
|
>>> config = Config('test_config.yaml')
|
||||||
|
>>> config.defaults['qobuz']['quality']
|
||||||
|
3
|
||||||
|
|
||||||
If test_config was already initialized with values, this will load them
|
If test_config was already initialized with values, this will load them
|
||||||
into `config`. Otherwise, a new config file is created with the default
|
into `config`. Otherwise, a new config file is created with the default
|
||||||
values.
|
values.
|
||||||
|
|
||||||
>>> config.update_from_cli(**args)
|
|
||||||
|
|
||||||
This will update the config values based on command line args.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
|
@ -42,7 +40,7 @@ class Config:
|
||||||
"quality": 3,
|
"quality": 3,
|
||||||
"email": None,
|
"email": None,
|
||||||
"password": None,
|
"password": None,
|
||||||
"app_id": "", # Avoid NoneType error
|
"app_id": "",
|
||||||
"secrets": [],
|
"secrets": [],
|
||||||
},
|
},
|
||||||
"tidal": {
|
"tidal": {
|
||||||
|
@ -82,6 +80,7 @@ class Config:
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"set_playlist_to_album": False,
|
"set_playlist_to_album": False,
|
||||||
|
"new_playlist_tracknumbers": True,
|
||||||
},
|
},
|
||||||
"path_format": {"folder": FOLDER_FORMAT, "track": TRACK_FORMAT},
|
"path_format": {"folder": FOLDER_FORMAT, "track": TRACK_FORMAT},
|
||||||
"check_for_updates": True,
|
"check_for_updates": True,
|
||||||
|
|
|
@ -170,6 +170,7 @@ class MusicDL(list):
|
||||||
"concurrent_downloads": self.config.session["concurrent_downloads"][
|
"concurrent_downloads": self.config.session["concurrent_downloads"][
|
||||||
"enabled"
|
"enabled"
|
||||||
],
|
],
|
||||||
|
"new_tracknumbers": self.config.session['metadata']['new_playlist_tracknumbers']
|
||||||
}
|
}
|
||||||
logger.debug("Arguments from config: %s", arguments)
|
logger.debug("Arguments from config: %s", arguments)
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,11 @@ class Track:
|
||||||
else:
|
else:
|
||||||
url_id = self.id
|
url_id = self.id
|
||||||
|
|
||||||
|
try:
|
||||||
dl_info = self.client.get_file_url(url_id, self.quality)
|
dl_info = self.client.get_file_url(url_id, self.quality)
|
||||||
|
except Exception as e:
|
||||||
|
click.secho(f"Unable to download track. {e}", fg='red')
|
||||||
|
return False
|
||||||
|
|
||||||
self.path = os.path.join(gettempdir(), f"{hash(self.id)}_{self.quality}.tmp")
|
self.path = os.path.join(gettempdir(), f"{hash(self.id)}_{self.quality}.tmp")
|
||||||
logger.debug("Temporary file path: %s", self.path)
|
logger.debug("Temporary file path: %s", self.path)
|
||||||
|
@ -233,10 +237,10 @@ class Track:
|
||||||
# --------- Download Track ----------
|
# --------- Download Track ----------
|
||||||
if self.client.source in ("qobuz", "tidal"):
|
if self.client.source in ("qobuz", "tidal"):
|
||||||
logger.debug("Downloadable URL found: %s", dl_info.get("url"))
|
logger.debug("Downloadable URL found: %s", dl_info.get("url"))
|
||||||
tqdm_download(dl_info["url"], self.path) # downloads file
|
tqdm_download(dl_info["url"], self.path, desc=self._progress_desc) # downloads file
|
||||||
|
|
||||||
elif self.client.source == "deezer": # Deezer
|
elif self.client.source == "deezer": # Deezer
|
||||||
logger.debug("Downloadable URL found: %s", dl_info)
|
logger.debug("Downloadable URL found: %s", dl_info, desc=self._progress_desc)
|
||||||
try:
|
try:
|
||||||
tqdm_download(dl_info, self.path) # downloads file
|
tqdm_download(dl_info, self.path) # downloads file
|
||||||
except NonStreamable:
|
except NonStreamable:
|
||||||
|
@ -301,7 +305,7 @@ class Track:
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
elif dl_info["type"] == "original":
|
elif dl_info["type"] == "original":
|
||||||
tqdm_download(dl_info["url"], self.path)
|
tqdm_download(dl_info["url"], self.path, desc=self._progress_desc)
|
||||||
|
|
||||||
# if a wav is returned, convert to flac
|
# if a wav is returned, convert to flac
|
||||||
engine = converter.FLAC(self.path)
|
engine = converter.FLAC(self.path)
|
||||||
|
@ -311,6 +315,10 @@ class Track:
|
||||||
self.final_path = self.final_path.replace(".mp3", ".flac")
|
self.final_path = self.final_path.replace(".mp3", ".flac")
|
||||||
self.quality = 2
|
self.quality = 2
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _progress_desc(self):
|
||||||
|
return click.style(f"Track {int(self.meta.tracknumber):02}", fg='blue')
|
||||||
|
|
||||||
def download_cover(self):
|
def download_cover(self):
|
||||||
"""Downloads the cover art, if cover_url is given."""
|
"""Downloads the cover art, if cover_url is given."""
|
||||||
|
|
||||||
|
@ -318,10 +326,10 @@ class Track:
|
||||||
|
|
||||||
self.cover_path = os.path.join(self.folder, f"cover{hash(self.cover_url)}.jpg")
|
self.cover_path = os.path.join(self.folder, f"cover{hash(self.cover_url)}.jpg")
|
||||||
logger.debug(f"Downloading cover from {self.cover_url}")
|
logger.debug(f"Downloading cover from {self.cover_url}")
|
||||||
click.secho(f"\nDownloading cover art for {self!s}", fg="blue")
|
# click.secho(f"\nDownloading cover art for {self!s}", fg="blue")
|
||||||
|
|
||||||
if not os.path.exists(self.cover_path):
|
if not os.path.exists(self.cover_path):
|
||||||
tqdm_download(self.cover_url, self.cover_path)
|
tqdm_download(self.cover_url, self.cover_path, desc=click.style('Cover', fg='cyan'))
|
||||||
else:
|
else:
|
||||||
logger.debug("Cover already exists, skipping download")
|
logger.debug("Cover already exists, skipping download")
|
||||||
|
|
||||||
|
@ -1244,7 +1252,9 @@ class Playlist(Tracklist):
|
||||||
item["albumartist"] = self.creator
|
item["albumartist"] = self.creator
|
||||||
|
|
||||||
if kwargs.get("new_tracknumbers", True):
|
if kwargs.get("new_tracknumbers", True):
|
||||||
item.meta["tracknumber"] = str(self.__download_index)
|
item["tracknumber"] = self.__download_index
|
||||||
|
item['discnumber'] = 1
|
||||||
|
|
||||||
self.__download_index += 1
|
self.__download_index += 1
|
||||||
|
|
||||||
self.downloaded = item.download(**kwargs)
|
self.downloaded = item.download(**kwargs)
|
||||||
|
|
|
@ -361,6 +361,9 @@ class TrackMetadata:
|
||||||
for k, v in FLAC_KEY.items():
|
for k, v in FLAC_KEY.items():
|
||||||
tag = getattr(self, k)
|
tag = getattr(self, k)
|
||||||
if tag:
|
if tag:
|
||||||
|
if k in ('tracknumber', 'discnumber', 'tracktotal', 'disctotal'):
|
||||||
|
tag = f"{int(tag):02}"
|
||||||
|
|
||||||
logger.debug("Adding tag %s: %s", v, tag)
|
logger.debug("Adding tag %s: %s", v, tag)
|
||||||
yield (v, str(tag))
|
yield (v, str(tag))
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ def get_quality_id(bit_depth: Optional[int], sampling_rate: Optional[int]):
|
||||||
return 4
|
return 4
|
||||||
|
|
||||||
|
|
||||||
def tqdm_download(url: str, filepath: str, params: dict = None):
|
def tqdm_download(url: str, filepath: str, params: dict = None, desc: str = None):
|
||||||
"""Downloads a file with a progress bar.
|
"""Downloads a file with a progress bar.
|
||||||
|
|
||||||
:param url: url to direct download
|
:param url: url to direct download
|
||||||
|
@ -114,12 +114,11 @@ def tqdm_download(url: str, filepath: str, params: dict = None):
|
||||||
total = int(r.headers.get("content-length", 0))
|
total = int(r.headers.get("content-length", 0))
|
||||||
logger.debug(f"File size = {total}")
|
logger.debug(f"File size = {total}")
|
||||||
if total < 1000 and not url.endswith("jpg") and not url.endswith("png"):
|
if total < 1000 and not url.endswith("jpg") and not url.endswith("png"):
|
||||||
print(url)
|
|
||||||
raise NonStreamable(url)
|
raise NonStreamable(url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(filepath, "wb") as file, tqdm(
|
with open(filepath, "wb") as file, tqdm(
|
||||||
total=total, unit="iB", unit_scale=True, unit_divisor=1024
|
total=total, unit="iB", unit_scale=True, unit_divisor=1024, desc=desc
|
||||||
) as bar:
|
) as bar:
|
||||||
for data in r.iter_content(chunk_size=1024):
|
for data in r.iter_content(chunk_size=1024):
|
||||||
size = file.write(data)
|
size = file.write(data)
|
||||||
|
@ -145,8 +144,10 @@ def clean_format(formatter: str, format_info):
|
||||||
|
|
||||||
clean_dict = dict()
|
clean_dict = dict()
|
||||||
for key in fmt_keys:
|
for key in fmt_keys:
|
||||||
if isinstance(format_info.get(key), (str, int, float)): # int for track numbers
|
if isinstance(format_info.get(key), (str, float)):
|
||||||
clean_dict[key] = sanitize_filename(str(format_info[key]))
|
clean_dict[key] = sanitize_filename(str(format_info[key]))
|
||||||
|
elif isinstance(format_info.get(key), int): # track/discnumber
|
||||||
|
clean_dict[key] = f"{format_info[key]:02}"
|
||||||
else:
|
else:
|
||||||
clean_dict[key] = "Unknown"
|
clean_dict[key] = "Unknown"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue