Removed get_file_url cache, misc bug fixes
The file url expires after some time, so caching it created an error where an empty file would be downloaded.
This commit is contained in:
@@ -6,9 +6,9 @@ import os
|
||||
import click
|
||||
|
||||
from qobuz_dl_rewrite.config import Config
|
||||
from qobuz_dl_rewrite.constants import CACHE_DIR, CONFIG_DIR
|
||||
from qobuz_dl_rewrite.core import QobuzDL
|
||||
from qobuz_dl_rewrite.utils import init_log
|
||||
from qobuz_dl_rewrite.constants import CONFIG_DIR, CACHE_DIR
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ class QobuzClient(ClientInterface):
|
||||
logger.debug("Already logged in")
|
||||
return
|
||||
|
||||
if (kwargs.get("app_id") or kwargs.get("secrets")) in (None, ['']):
|
||||
if (kwargs.get("app_id") or kwargs.get("secrets")) in (None, [""]):
|
||||
logger.info("Fetching tokens from Qobuz")
|
||||
spoofer = Spoofer()
|
||||
kwargs["app_id"] = spoofer.get_app_id()
|
||||
@@ -190,7 +190,6 @@ class QobuzClient(ClientInterface):
|
||||
def get(self, item_id: Union[str, int], media_type: str = "album") -> dict:
|
||||
return self._api_get(media_type, item_id=item_id)
|
||||
|
||||
@region.cache_on_arguments(expiration_time=TRACK_CACHE_TIME)
|
||||
def get_file_url(self, item_id, quality=6) -> dict:
|
||||
return self._api_get_file_url(item_id, quality=quality)
|
||||
|
||||
@@ -314,10 +313,10 @@ class QobuzClient(ClientInterface):
|
||||
|
||||
if sec is not None:
|
||||
secret = sec
|
||||
elif hasattr(self, 'sec'):
|
||||
elif hasattr(self, "sec"):
|
||||
secret = self.sec
|
||||
else:
|
||||
raise InvalidAppSecretError('Cannot find app secret')
|
||||
raise InvalidAppSecretError("Cannot find app secret")
|
||||
|
||||
r_sig = f"trackgetFileUrlformat_id{quality}intentstreamtrack_id{track_id}{unix_ts}{secret}"
|
||||
logger.debug("Raw request signature: %s", r_sig)
|
||||
@@ -459,7 +458,6 @@ class TidalClient(ClientInterface):
|
||||
"""
|
||||
return self._get(meta_id, media_type)
|
||||
|
||||
@region.cache_on_arguments(expiration_time=TRACK_CACHE_TIME)
|
||||
def get_file_url(self, meta_id: Union[str, int], quality: int = 6):
|
||||
"""
|
||||
:param meta_id:
|
||||
|
||||
@@ -107,7 +107,7 @@ class Converter:
|
||||
if self.lossless:
|
||||
if isinstance(self.sampling_rate, int):
|
||||
command.extend(["-ar", str(self.sampling_rate)])
|
||||
else:
|
||||
elif self.sampling_rate is not None:
|
||||
raise TypeError(
|
||||
f"Sampling rate must be int, not {type(self.sampling_rate)}"
|
||||
)
|
||||
@@ -119,7 +119,7 @@ class Converter:
|
||||
command.extend(["-sample_fmt", "s32"])
|
||||
else:
|
||||
raise ValueError("Bit depth must be 16, 24, or 32")
|
||||
else:
|
||||
elif self.bit_depth is not None:
|
||||
raise TypeError(f"Bit depth must be int, not {type(self.bit_depth)}")
|
||||
|
||||
command.extend(["-y", self.tempfile])
|
||||
|
||||
@@ -21,6 +21,7 @@ Media = Union[Album, Playlist, Artist] # type hint
|
||||
|
||||
# TODO: add support for database
|
||||
|
||||
|
||||
class QobuzDL:
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from pprint import pprint
|
||||
import sys
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from abc import ABC, abstractmethod
|
||||
from pprint import pprint
|
||||
from tempfile import gettempdir
|
||||
from typing import Any, Callable, Optional, Tuple, Union
|
||||
|
||||
@@ -218,13 +219,13 @@ class Track:
|
||||
def format_final_path(self) -> str:
|
||||
"""Return the final filepath of the downloaded file.
|
||||
|
||||
This uses the `_get_formatter` method of TrackMetadata, which returns
|
||||
This uses the `get_formatter` method of TrackMetadata, which returns
|
||||
a dict with the keys allowed in formatter strings, and their values in
|
||||
the TrackMetadata object.
|
||||
"""
|
||||
formatter = self.meta._get_formatter()
|
||||
formatter = self.meta.get_formatter()
|
||||
# filename = sanitize_filepath(self.file_format.format(**formatter))
|
||||
filename = clean_format(self.file_format, **formatter)
|
||||
filename = clean_format(self.file_format, formatter)
|
||||
self.final_path = (
|
||||
os.path.join(self.folder, filename)[:250].strip()
|
||||
+ EXT[self.quality] # file extension dict
|
||||
@@ -375,6 +376,9 @@ class Track:
|
||||
|
||||
self.container = codec.upper()
|
||||
|
||||
print(self.final_path)
|
||||
print(kwargs.get("sampling_rate"))
|
||||
print(kwargs.get("remove_source"))
|
||||
engine = CONV_CLASS[codec.upper()](
|
||||
filename=self.final_path,
|
||||
sampling_rate=kwargs.get("sampling_rate"),
|
||||
@@ -673,7 +677,7 @@ class Album(Tracklist):
|
||||
"tracktotal": resp.get("track_total"),
|
||||
}
|
||||
|
||||
raise NotImplementedError(client.source)
|
||||
raise InvalidSourceError(client.source)
|
||||
|
||||
def _load_tracks(self):
|
||||
"""Given an album metadata dict returned by the API, append all of its
|
||||
@@ -748,15 +752,16 @@ class Album(Tracklist):
|
||||
|
||||
img = requests.head(cover_url)
|
||||
|
||||
if int(img.headers["Content-Length"]) > 5 * 10 ** 6: # 5MB
|
||||
logger.debug("Requested key (%s) size is too large. Falling back")
|
||||
if int(img.headers["Content-Length"]) > FLAC_MAX_BLOCKSIZE: # 16.7 MB
|
||||
logger.info(
|
||||
f"{cover_key} cover size is too large to "
|
||||
"embed. Using small cover instead"
|
||||
)
|
||||
cover_url = self.cover_urls.get("small")
|
||||
|
||||
tqdm_download(cover_url, cover_path)
|
||||
|
||||
# create a single cover object and use them for all tracks
|
||||
# TODO: avoid this method if embeded covers are not requested
|
||||
if self.client.source != "deezer":
|
||||
if self.client.source != "deezer" and embed_cover:
|
||||
cover = self.get_cover_obj(cover_path, quality)
|
||||
|
||||
for track in self:
|
||||
@@ -778,15 +783,20 @@ class Album(Tracklist):
|
||||
else:
|
||||
dict_[key] = None
|
||||
|
||||
dict_['sampling_rate'] /= 1000
|
||||
# 48.0kHz -> 48kHz, 44.1kHz -> 44.1kHz
|
||||
if dict_['sampling_rate'] % 1 == 0.0:
|
||||
dict_['sampling_rate'] = int(dict_['sampling_rate'])
|
||||
|
||||
return dict_
|
||||
|
||||
def _get_formatted_folder(self, parent_folder: str) -> str:
|
||||
if self.bit_depth is not None and self.sampling_rate is not None:
|
||||
self.container = 'FLAC'
|
||||
elif self.client.source == 'qobuz':
|
||||
self.container = 'MP3'
|
||||
elif self.client.source == 'tidal':
|
||||
self.container = 'AAC'
|
||||
self.container = "FLAC"
|
||||
elif self.client.source == "qobuz":
|
||||
self.container = "MP3"
|
||||
elif self.client.source == "tidal":
|
||||
self.container = "AAC"
|
||||
else:
|
||||
raise Exception(f"{self.bit_depth=}, {self.sampling_rate=}")
|
||||
|
||||
@@ -1241,11 +1251,11 @@ class Artist(Tracklist):
|
||||
|
||||
class Label(Artist):
|
||||
def load_meta(self):
|
||||
assert self.client.source == 'qobuz', 'Label source must be qobuz'
|
||||
assert self.client.source == "qobuz", "Label source must be qobuz"
|
||||
|
||||
resp = self.client.get(self.id, 'label')
|
||||
self.name = resp['name']
|
||||
for album in resp['albums']['items']:
|
||||
resp = self.client.get(self.id, "label")
|
||||
self.name = resp["name"]
|
||||
for album in resp["albums"]["items"]:
|
||||
pprint(album)
|
||||
self.append(Album.from_api(album, client=self.client))
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ def clean_format(formatter: str, format_info):
|
||||
|
||||
clean_dict = dict()
|
||||
for key in fmt_keys:
|
||||
if isinstance(format_info.get(key), (str, int)): # int for track numbers
|
||||
if isinstance(format_info.get(key), (str, int, float)): # int for track numbers
|
||||
clean_dict[key] = sanitize_filename(str(format_info[key]))
|
||||
else:
|
||||
clean_dict[key] = "Unknown"
|
||||
|
||||
Reference in New Issue
Block a user