diff options
| author | Robert Honz <exislow+github@gmail.com> | 2024-11-29 17:41:25 +0100 |
|---|---|---|
| committer | Robert Honz <exislow+github@gmail.com> | 2024-11-29 17:41:25 +0100 |
| commit | 33a30537e9a205dd4b43e891b00c0b5f15a9b71b (patch) | |
| tree | 9ccb8c4c273ce96fd6ebce8ea2077d281d812712 /tidal_dl_ng/helper | |
| parent | f2b3cc2505f4c64f09efacd775de3390ae204be0 (diff) | |
| parent | 4deaf94fb53ad304db73f9384f817b29afcac4a8 (diff) | |
| download | tidal-dl-ng-33a30537e9a205dd4b43e891b00c0b5f15a9b71b.tar.gz | |
✨ Merge with master.
Diffstat (limited to 'tidal_dl_ng/helper')
| -rw-r--r-- | tidal_dl_ng/helper/decryption.py | 7 | ||||
| -rw-r--r-- | tidal_dl_ng/helper/path.py | 36 | ||||
| -rw-r--r-- | tidal_dl_ng/helper/tidal.py | 8 | ||||
| -rw-r--r-- | tidal_dl_ng/helper/wrapper.py | 3 |
4 files changed, 40 insertions, 14 deletions
diff --git a/tidal_dl_ng/helper/decryption.py b/tidal_dl_ng/helper/decryption.py index ebb946a..17ea19b 100644 --- a/tidal_dl_ng/helper/decryption.py +++ b/tidal_dl_ng/helper/decryption.py @@ -1,4 +1,5 @@ import base64 +import pathlib from Crypto.Cipher import AES from Crypto.Util import Counter @@ -35,7 +36,7 @@ def decrypt_security_token(security_token: str) -> (str, str): return key, nonce -def decrypt_file(path_file_encrypted: str, path_file_destination: str, key: str, nonce: str) -> None: +def decrypt_file(path_file_encrypted: pathlib.Path, path_file_destination: pathlib.Path, key: str, nonce: str) -> None: """ Decrypts an encrypted MQA file given the file, key and nonce. TODO: Is it really only necessary for MQA of for all other formats, too? @@ -46,9 +47,9 @@ def decrypt_file(path_file_encrypted: str, path_file_destination: str, key: str, decryptor = AES.new(key, AES.MODE_CTR, counter=counter) # Open and decrypt - with open(path_file_encrypted, "rb") as f_src: + with path_file_encrypted.open("rb") as f_src: audio_decrypted = decryptor.decrypt(f_src.read()) # Replace with decrypted file - with open(path_file_destination, "wb") as f_dst: + with path_file_destination.open("wb") as f_dst: f_dst.write(audio_decrypted) diff --git a/tidal_dl_ng/helper/path.py b/tidal_dl_ng/helper/path.py index cc8d5b6..fb7bb87 100644 --- a/tidal_dl_ng/helper/path.py +++ b/tidal_dl_ng/helper/path.py @@ -1,8 +1,10 @@ import math import os +import pathlib +import posixpath import re import sys -from pathlib import Path, PosixPath +from urllib.parse import unquote, urlsplit from pathvalidate import sanitize_filename, sanitize_filepath from pathvalidate.error import ValidationError @@ -77,8 +79,7 @@ def format_str_media(name: str, media: Track | Album | Playlist | UserPlaylist | elif hasattr(media, "artist"): result = media.artist.name case "album_artist": - if isinstance(media, Album): - result = name_builder_album_artist(media) + result = name_builder_album_artist(media) case "track_title": if isinstance(media, Track | Video): result = name_builder_title(media) @@ -195,7 +196,7 @@ def get_format_template( def path_file_sanitize(path_file: str, adapt: bool = False, uniquify: bool = False) -> (bool, str): # Split into path and filename pathname, filename = os.path.split(path_file) - file_extension: str = Path(path_file).suffix + file_extension: str = pathlib.Path(path_file).suffix # Sanitize path try: @@ -205,7 +206,7 @@ def path_file_sanitize(path_file: str, adapt: bool = False, uniquify: bool = Fal except ValidationError: # If adaption of path is allowed in case of an error set path to HOME. if adapt: - pathname_sanitized: str = Path.home() + pathname_sanitized: str = str(pathlib.Path.home()) else: raise @@ -272,10 +273,10 @@ def file_unique_suffix(path_file: str, seperator: str = "_") -> str: return unique_suffix -def check_file_exists(path_file: str, extension_ignore: bool = False) -> bool: +def check_file_exists(path_file: pathlib.Path, extension_ignore: bool = False) -> bool: if extension_ignore: - path_file_stem: str = Path(path_file).stem - path_parent: PosixPath = Path(path_file).parent + path_file_stem: str = pathlib.Path(path_file).stem + path_parent: pathlib.Path = pathlib.Path(path_file).parent path_files: [str] = [] for extension in AudioExtensions: @@ -295,3 +296,22 @@ def resource_path(relative_path): base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) + + +def url_to_filename(url: str) -> str: + """Return basename corresponding to url. + >>> print(url_to_filename('http://example.com/path/to/file%C3%80?opt=1')) + fileÀ + >>> print(url_to_filename('http://example.com/slash%2fname')) # '/' in name + Taken from https://gist.github.com/zed/c2168b9c52b032b5fb7d + Traceback (most recent call last): + ... + ValueError + """ + urlpath: str = urlsplit(url).path + basename: str = posixpath.basename(unquote(urlpath)) + + if os.path.basename(basename) != basename or unquote(posixpath.basename(urlpath)) != basename: + raise ValueError # reject '%2f' or 'dir%5Cbasename.ext' on Windows + + return basename diff --git a/tidal_dl_ng/helper/tidal.py b/tidal_dl_ng/helper/tidal.py index d679d5e..e568cc6 100644 --- a/tidal_dl_ng/helper/tidal.py +++ b/tidal_dl_ng/helper/tidal.py @@ -25,8 +25,10 @@ def name_builder_album_artist(media: Track | Album) -> str: return ", ".join(artists_tmp) -def name_builder_title(media: Track | Video) -> str: - result: str = media.full_name if hasattr(media, "full_name") else media.name +def name_builder_title(media: Track | Video | Mix | Playlist | Album | Video) -> str: + result: str = ( + media.title if isinstance(media, Mix) else media.full_name if hasattr(media, "full_name") else media.name + ) return result @@ -186,7 +188,7 @@ def instantiate_media( def quality_audio_highest(media: Track | Album) -> Quality: quality: Quality - if MediaMetadataTags.hires_lossless in media.media_metadata_tags: + if MediaMetadataTags.hi_res_lossless in media.media_metadata_tags: quality = Quality.hi_res_lossless elif MediaMetadataTags.lossless in media.media_metadata_tags: quality = Quality.high_lossless diff --git a/tidal_dl_ng/helper/wrapper.py b/tidal_dl_ng/helper/wrapper.py index d8ffb09..cd8e6ba 100644 --- a/tidal_dl_ng/helper/wrapper.py +++ b/tidal_dl_ng/helper/wrapper.py @@ -21,3 +21,6 @@ class LoggerWrapped: def critical(self, value): self.fn_print(value) + + def exception(self, value): + self.fn_print(value) |
