From 1bf8bb16def69accb6486d2487722328046abc7d Mon Sep 17 00:00:00 2001 From: vitiko98 Date: Wed, 16 Dec 2020 19:07:40 -0400 Subject: [PATCH] Add the option to disable quality fallback (close #35) Also stop the version number heresy --- qobuz_dl/cli.py | 1 + qobuz_dl/commands.py | 11 ++++++--- qobuz_dl/core.py | 4 +++- qobuz_dl/downloader.py | 52 +++++++++++++++++++++++++++++++++--------- setup.py | 2 +- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/qobuz_dl/cli.py b/qobuz_dl/cli.py index b25489a..69abc2c 100644 --- a/qobuz_dl/cli.py +++ b/qobuz_dl/cli.py @@ -87,6 +87,7 @@ def main(): arguments.embed_art, ignore_singles_eps=arguments.albums_only, no_m3u_for_playlists=arguments.no_m3u, + quality_fallback=not arguments.no_fallback, ) qobuz.initialize_client(email, password, app_id, secrets) diff --git a/qobuz_dl/commands.py b/qobuz_dl/commands.py index 397026e..9cadd7f 100644 --- a/qobuz_dl/commands.py +++ b/qobuz_dl/commands.py @@ -56,9 +56,6 @@ def dl_args(subparsers): def add_common_arg(custom_parser, default_folder, default_quality): - custom_parser.add_argument( - "-e", "--embed-art", action="store_true", help="embed cover art into files" - ) custom_parser.add_argument( "-d", "--directory", @@ -86,6 +83,14 @@ def add_common_arg(custom_parser, default_folder, default_quality): action="store_true", help="don't create .m3u files when downloading playlists", ) + custom_parser.add_argument( + "--no-fallback", + action="store_true", + help="disable quality fallback (skip releases not available in set quality)", + ) + custom_parser.add_argument( + "-e", "--embed-art", action="store_true", help="embed cover art into files" + ) def qobuz_dl_args( diff --git a/qobuz_dl/core.py b/qobuz_dl/core.py index 60f4157..eb46e3c 100644 --- a/qobuz_dl/core.py +++ b/qobuz_dl/core.py @@ -53,7 +53,7 @@ class QobuzDL: interactive_limit=20, ignore_singles_eps=False, no_m3u_for_playlists=False, - raise_request_exceptions=False, + quality_fallback=True, ): self.directory = self.create_dir(directory) self.quality = quality @@ -63,6 +63,7 @@ class QobuzDL: self.interactive_limit = interactive_limit self.ignore_singles_eps = ignore_singles_eps self.no_m3u_for_playlists = no_m3u_for_playlists + self.quality_fallback = quality_fallback def initialize_client(self, email, pwd, app_id, secrets): self.client = qopy.Client(email, pwd, app_id, secrets) @@ -96,6 +97,7 @@ class QobuzDL: album, self.embed_art, self.ignore_singles_eps, + self.quality_fallback, ) def handle_url(self, url): diff --git a/qobuz_dl/downloader.py b/qobuz_dl/downloader.py index 5c35782..9cb0241 100644 --- a/qobuz_dl/downloader.py +++ b/qobuz_dl/downloader.py @@ -6,6 +6,8 @@ from tqdm import tqdm import qobuz_dl.metadata as metadata +QL_DOWNGRADE = "FormatRestrictedByFormatAvailability" + def tqdm_download(url, fname, track_name): r = requests.get(url, allow_redirects=True, stream=True) @@ -31,23 +33,34 @@ def get_description(u, mt, multiple=None): ) -def get_format(client, item_dict, quality, is_track_id=False): +def get_format(client, item_dict, quality, is_track_id=False, track_url_dict=None): + quality_met = True if int(quality) == 5: - return "MP3" + return "MP3", quality_met track_dict = item_dict if not is_track_id: track_dict = item_dict["tracks"]["items"][0] try: - new_track_dict = client.get_track_url(track_dict["id"], quality) + new_track_dict = ( + client.get_track_url(track_dict["id"], quality) + if not track_url_dict + else track_url_dict + ) + restrictions = new_track_dict.get("restrictions") + if isinstance(restrictions, list): + if any( + restriction.get("code") == QL_DOWNGRADE for restriction in restrictions + ): + quality_met = False if ( new_track_dict["bit_depth"] == 16 and new_track_dict["sampling_rate"] == 44.1 ): - return "FLAC" - return "Hi-Res" + return "FLAC", quality_met + return "Hi-Res", quality_met except (KeyError, requests.exceptions.HTTPError): - return "Unknown" + return "Unknown", quality_met def get_title(item_dict): @@ -151,7 +164,14 @@ def download_and_tag( def download_id_by_type( - client, item_id, path, quality, album=False, embed_art=False, albums_only=False + client, + item_id, + path, + quality, + album=False, + embed_art=False, + albums_only=False, + downgrade_quality=True, ): """ Download and get metadata by ID and type (album or track) @@ -163,6 +183,7 @@ def download_id_by_type( :param bool album: album type or not :param embed_art album: Embed cover art into files :param bool albums_only: Ignore Singles, EPs and VA releases + :param bool downgrade: Skip releases not available in set quality """ count = 0 @@ -177,12 +198,17 @@ def download_id_by_type( return album_title = get_title(meta) + album_format, quality_met = get_format(client, meta, quality) + if not downgrade_quality and not quality_met: + print("Skipping release as doesn't met quality requirement") + return + print("\nDownloading: {}\n".format(album_title)) dirT = ( meta["artist"]["name"], album_title, meta["release_date_original"].split("-")[0], - get_format(client, meta, quality), + album_format, ) sanitized_title = sanitize_filename("{} - {} [{}] [{}]".format(*dirT)) dirn = os.path.join(path, sanitized_title) @@ -191,8 +217,8 @@ def download_id_by_type( if "goodies" in meta: try: get_extra(meta["goodies"][0]["url"], dirn, "booklet.pdf") - except Exception as e: - print("Error: " + e) + except: # noqa + pass media_numbers = [track["media_number"] for track in meta["tracks"]["items"]] is_multiple = True if len([*{*media_numbers}]) > 1 else False for i in meta["tracks"]["items"]: @@ -228,11 +254,15 @@ def download_id_by_type( meta = client.get_track_meta(item_id) track_title = get_title(meta) print("\nDownloading: {}\n".format(track_title)) + track_format, quality_met = get_format(client, meta, quality, True, parse) + if not downgrade_quality and not quality_met: + print("Skipping track as doesn't met quality requirement") + return dirT = ( meta["album"]["artist"]["name"], track_title, meta["album"]["release_date_original"].split("-")[0], - get_format(client, meta, quality, True), + track_format, ) sanitized_title = sanitize_filename("{} - {} [{}] [{}]".format(*dirT)) dirn = os.path.join(path, sanitized_title) diff --git a/setup.py b/setup.py index 2f78adf..fca4107 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ requirements = read_file("requirements.txt").strip().split() setup( name=pkg_name, - version="0.5.6", + version="0.6.0", author="Vitiko", author_email="vhnz98@gmail.com", description="The complete Lossless and Hi-Res music downloader for Qobuz",