diff --git a/.gitignore b/.gitignore index 8dce8e8..76ed3a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ docs/source +vs_code/ # From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07a0128..136cc4b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ Anything tagged with "enhancement" and "help wanted" is open to whoever wants to ## Write Documentation -Cookiecutter PyPackage could always use more documentation, whether as part of the official docs, in docstrings, or even on the web in blog posts, articles, and such. +The TIDAL Downloader project could always use more documentation, whether as part of the official docs, in docstrings, or even on the web in blog posts, articles, and such. ## Submit Feedback diff --git a/README.md b/README.md index 9a3f10a..0f098d3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Commit activity](https://img.shields.io/github/commit-activity/m/exislow/tidal-dl-ng)](https://img.shields.io/github/commit-activity/m/exislow/tidal-dl-ng) [![License](https://img.shields.io/github/license/exislow/tidal-dl-ng)](https://img.shields.io/github/license/exislow/tidal-dl-ng) -This tool allows to download songs and videos from TIDAL. Multithreaded and multi-chunked downloads are supported. +This tool allows you to download songs and videos from TIDAL. Multithreaded and multi-chunked downloads are supported. ⚠️ **Windows** Defender / **Anti Virus** software / web browser alerts, while you try to download the app binary: This is a **false positive**. Please @@ -39,7 +39,7 @@ $ tidal-dl-ng --help ╰──────────────────────────────────────────────────────────────────────────────╯ ``` -If you like this projects and want to support it, feel free to buy me a coffee 🙃✌️ +If you like this project and want to support it, feel free to buy me a coffee 🙃✌️ Buy Me A Coffee 61e11d430afb112ea33c3aa5_Button-1-p-500 @@ -83,8 +83,8 @@ tdng tidal-dl-ng gui ``` -If you like to have the GUI version only as a binary, have a look at the -[release page](https://github.com/exislow/tidal-dl-ng/releases) and download the correct version for your platform. +If you would like to use the GUI version as a binary, have a look at the +[release page](https://github.com/exislow/tidal-dl-ng/releases) and download the correct version for your OS. ## 🧁 Features @@ -121,13 +121,13 @@ tidal_ng_dl/gui.py ### 📺 GUI Builder -The GUI is build with `PySide6` using the [Qt Designer](https://doc.qt.io/qt-6/qtdesigner-manual.html): +The GUI is built with `PySide6` using the [Qt Designer](https://doc.qt.io/qt-6/qtdesigner-manual.html): ```bash PYSIDE_DESIGNER_PLUGINS=tidal_dl_ng/ui pyside6-designer ``` -After all changes are saved you need to translate the Qt Designer `*.ui` file into Python code, for instance: +After all changes are saved, you need to translate the Qt Designer `*.ui` file into Python code, for instance: ``` pyside6-uic tidal_dl_ng/ui/main.ui -o tidal_dl_ng/ui/main.py @@ -144,9 +144,9 @@ To build the project use this command: make install # Build macOS GUI make gui-macos-dmg -# OR Build macOS GUI +# OR Build Windows GUI make gui-windows -# OR Build macOS GUI +# OR Build Linux GUI make gui-linux # Check build output ls dist/ @@ -206,7 +206,7 @@ sudo apt install libxcb-cursor0 ### A terminal is flashing when I run this app on Windows -Please see this isse [#103](https://github.com/exislow/tidal-dl-ng/issues/103). +Please see this issue [#103](https://github.com/exislow/tidal-dl-ng/issues/103). This is due to the Python `ffmpeg` library which is used and only happens on windows if `extract_flac` is activated. diff --git a/pyproject.toml b/pyproject.toml index ff255c5..3c2c7b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "tidal-dl-ng" authors = [{ name = "Robert Honz", email = "" }] version = "0.31.4" -description = "TIDAL Medial Downloader Next Generation!" +description = "TIDAL Media Downloader Next Generation!" readme = "README.md" license = "AGPL-3.0-only" license-files = ["LICENSE"] @@ -132,7 +132,7 @@ ignore = [ # Do not use bare `except` "E722", # PEP 484 prohibits implicit `Optional` - # Disabled only temporarely. + # Disabled only temporarily. "RUF013", ] diff --git a/tidal_dl_ng/cli.py b/tidal_dl_ng/cli.py index c2b51fa..b1e607c 100644 --- a/tidal_dl_ng/cli.py +++ b/tidal_dl_ng/cli.py @@ -171,7 +171,7 @@ def _process_url( return False if "http" not in url: - print(f"It seems like that you have supplied an invalid URL: {url}") + print(f"It seems like you have supplied an invalid URL: {url}") return True url_clean: str = url_ending_clean(url) @@ -286,7 +286,7 @@ def settings_management( Args: names (list[str] | None, optional): None (list all options), one (list the value only for this option) or two arguments (set the value for the option). Defaults to None. - editor (bool, optional): If set, your favorite system editor will be opened. Defaults to False. + editor (bool, optional): If set, your default system editor will be opened. Defaults to False. """ if editor: config_path: Path = Path(path_file_settings()) @@ -333,7 +333,7 @@ def login(ctx: typer.Context) -> bool: Returns: bool: True if login was successful, False otherwise. """ - print("Let us check, if you are already logged in... ", end="") + print("Let us check if you are already logged in... ", end="") settings = Settings() tidal = Tidal(settings) @@ -375,7 +375,7 @@ def download( writable=False, readable=True, resolve_path=True, - help="List with URLs to download. One per line", + help="File with URLs to download. One URL per line.", ), ] = None, ) -> bool: @@ -395,7 +395,7 @@ def download( text: str = file_urls.read_text() urls = text.splitlines() else: - print("Provide either URLs, IDs or a file containing URLs (one per line).") + print("Provide either URLs or a file containing URLs (one per line).") raise typer.Abort() diff --git a/tidal_dl_ng/config.py b/tidal_dl_ng/config.py index 8be4459..aa36cf6 100644 --- a/tidal_dl_ng/config.py +++ b/tidal_dl_ng/config.py @@ -71,7 +71,6 @@ class BaseConfig: # Move the invalid config file to the backup location. shutil.move(path, path_bak) - # TODO: Implement better global logger. print( "Something is wrong with your config. Maybe it is not compatible anymore due to a new app version." f" You can find a backup of your old config here: '{path_bak}'. A new default config was created." diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index 8cb93f6..336b88b 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -203,7 +203,7 @@ class DialogPreferences(QtWidgets.QDialog): ): # If a path is set, use it otherwise the users home directory. path_settings: str = os.path.expanduser(obj_line_edit.text()) if obj_line_edit.text() else "" - # Check if obj_line_edit is empty but path_default can be usd instead + # Check if obj_line_edit is empty but path_default can be used instead path_settings = ( path_settings if path_settings else os.path.expanduser(path_default) if path_default else path_settings ) @@ -223,7 +223,7 @@ class DialogPreferences(QtWidgets.QDialog): dialog.setDirectory(dir_current) - # Execute dialog and set path is something is choosen. + # Execute dialog and set path if something is chosen. if dialog.exec(): dir_name: str = dialog.selectedFiles()[0] path: Path = Path(dir_name) diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index 84b6c9b..a121f95 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -411,7 +411,7 @@ class Download: with path_file.open("wb") as f_target: for dl_segment_result in dl_segment_results: with dl_segment_result.path_segment.open("rb") as f_segment: - # Read and write junks, which gives better HDD write performance + # Read and write chunks, which gives better HDD write performance while segment := f_segment.read(CHUNK_SIZE): f_target.write(segment) @@ -1249,7 +1249,7 @@ class Download: response: requests.Response = requests.get(url, timeout=REQUESTS_TIMEOUT_SEC) result = response.content except Exception as e: - # TODO: Implement propper logging. + # TODO: Implement proper logging. print(e) finally: response.close() @@ -1258,7 +1258,7 @@ class Download: with open(path_file, "rb") as f: result = f.read() except OSError as e: - # TODO: Implement propper logging. + # TODO: Implement proper logging. print(e) return result @@ -1750,15 +1750,22 @@ class Download: pathlib.Path: Path to the converted MP4 file. """ path_file_out: pathlib.Path = path_file.with_suffix(AudioExtensions.MP4) + + self.fn_logger.debug(f"Converting video: {path_file.name} -> {path_file_out.name}") + ffmpeg = ( FFmpeg(executable=self.settings.data.path_binary_ffmpeg) .option("y") + .option("hide_banner") + .option("nostdin") .input(url=path_file) .output(url=path_file_out, codec="copy", map=0, loglevel="quiet") ) ffmpeg.execute() + self.fn_logger.debug(f"Video conversion complete: {path_file_out.name}") + return path_file_out def _extract_flac(self, path_media_src: pathlib.Path) -> pathlib.Path: @@ -1771,8 +1778,13 @@ class Download: pathlib.Path: Path to the extracted FLAC file. """ path_media_out = path_media_src.with_suffix(AudioExtensions.FLAC) + + self.fn_logger.debug(f"Extracting FLAC: {path_media_src.name} -> {path_media_out.name}") + ffmpeg = ( FFmpeg(executable=self.settings.data.path_binary_ffmpeg) + .option("hide_banner") + .option("nostdin") .input(url=path_media_src) .output( url=path_media_out, @@ -1786,6 +1798,8 @@ class Download: ffmpeg.execute() + self.fn_logger.debug(f"FLAC extraction complete: {path_media_out.name}") + return path_media_out def _extract_video_stream(self, m3u8_variant: m3u8.M3U8, quality: int) -> tuple[m3u8.M3U8 | bool, str]: diff --git a/tidal_dl_ng/model/cfg.py b/tidal_dl_ng/model/cfg.py index b43acc1..bfca708 100644 --- a/tidal_dl_ng/model/cfg.py +++ b/tidal_dl_ng/model/cfg.py @@ -69,7 +69,7 @@ class Settings: @dataclass class HelpSettings: skip_existing: str = "Skip download if file already exists." - album_cover_save: str = "Safe cover to album folder." + album_cover_save: str = "Save cover to album folder." lyrics_embed: str = "Embed lyrics in audio file, if lyrics are available." use_primary_album_artist: str = "Use only the primary album artist for folder paths instead of track artists." lyrics_file: str = "Save lyrics to separate *.lrc file, if lyrics are available." @@ -97,11 +97,11 @@ class HelpSettings: "will be converted to MP4. FFmpeg must be installed." ) path_binary_ffmpeg: str = ( - "Path to FFmpeg binary file (executable). Only necessary if FFmpeg not set in $PATH. Mandatory for Windows: " - "The directory of `ffmpeg.exe`must be set in %PATH%." + "Path to FFmpeg binary file (executable). Only necessary if FFmpeg is not set in $PATH. Mandatory for Windows: " + "The directory of `ffmpeg.exe` must be set in %PATH%." ) metadata_cover_dimension: str = ( - "The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280." + "The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640, 1280x1280." ) metadata_cover_embed: str = "Embed album cover into file." mark_explicit: str = "Mark explicit tracks with '🅴' in track title (only applies to metadata)."