Added clarity and grammar fixes to documentation and to some strings on the program itself.

This commit is contained in:
E.J. Talevi
2025-11-25 23:56:56 -03:00
parent 28a6fe5a7d
commit 0e74ac32d6
8 changed files with 32 additions and 33 deletions
+2 -2
View File
@@ -29,7 +29,7 @@ Anything tagged with "enhancement" and "help wanted" is open to whoever wants to
## Write Documentation ## 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 ## Submit Feedback
@@ -110,7 +110,7 @@ make test
tox tox
``` ```
This requires you to have multiple versions of python installed. This requires you to have multiple versions of Python installed.
This step is also triggered in the CI/CD pipeline, so you could also choose to skip this step locally. This step is also triggered in the CI/CD pipeline, so you could also choose to skip this step locally.
10. Commit your changes and push your branch to GitHub: 10. Commit your changes and push your branch to GitHub:
+14 -14
View File
@@ -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) [![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) [![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 read [this issue](https://github.com/exislow/tidal-dl-ng/issues/231), [PyInstaller (used by this project) statement](https://github.com/pyinstaller/pyinstaller/blob/develop/.github/ISSUE_TEMPLATE/antivirus.md) and [the alternative installation solution](https://github.com/exislow/tidal-dl-ng/?tab=readme-ov-file#-installation--upgrade). ⚠️ **Windows** Defender / **Anti Virus** software / web browser alerts, while you try to download the app binary: This is a **false positive**. Please read [this issue](https://github.com/exislow/tidal-dl-ng/issues/231), [PyInstaller (used by this project) statement](https://github.com/pyinstaller/pyinstaller/blob/develop/.github/ISSUE_TEMPLATE/antivirus.md) and [the alternative installation solution](https://github.com/exislow/tidal-dl-ng/?tab=readme-ov-file#-installation--upgrade).
@@ -35,7 +35,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 🙃✌️
<a href="https://www.buymeacoffee.com/exislow" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/arial-orange.png" alt="Buy Me A Coffee" style="height: 51px !important;width: 217px !important;" ></a> <a href="https://www.buymeacoffee.com/exislow" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/arial-orange.png" alt="Buy Me A Coffee" style="height: 51px !important;width: 217px !important;" ></a>
<a href="https://ko-fi.com/exislow" target="_blank" rel="noopener noreferrer"><img src="https://help.ko-fi.com/hc/article_attachments/11833788361117" alt="61e11d430afb112ea33c3aa5_Button-1-p-500"></a> <a href="https://ko-fi.com/exislow" target="_blank" rel="noopener noreferrer"><img src="https://help.ko-fi.com/hc/article_attachments/11833788361117" alt="61e11d430afb112ea33c3aa5_Button-1-p-500"></a>
@@ -79,8 +79,8 @@ tdng
tidal-dl-ng gui tidal-dl-ng gui
``` ```
If you like to have the GUI version only as a binary, have a look at the 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 platform. [release page](https://github.com/exislow/tidal-dl-ng/releases) and download the correct version for your OS.
## 🧁 Features ## 🧁 Features
@@ -91,7 +91,7 @@ If you like to have the GUI version only as a binary, have a look at the
- FLAC extraction from MP4 containers - FLAC extraction from MP4 containers
- Lyrics and album art / cover download - Lyrics and album art / cover download
- Creates playlist files - Creates playlist files
- Can symlink tracks instead of having several copies, if added to different playlist - Can symlink tracks instead of having several copies, if added to different playlists
## ▶️ Getting started with development ## ▶️ Getting started with development
@@ -114,13 +114,13 @@ tidal_ng_dl/gui.py
### 📺 GUI Builder ### 📺 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 ```bash
PYSIDE_DESIGNER_PLUGINS=tidal_dl_ng/ui pyside6-designer 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 pyside6-uic tidal_dl_ng/ui/main.ui -o tidal_dl_ng/ui/main.py
@@ -137,9 +137,9 @@ To build the project use this command:
make install make install
# Build macOS GUI # Build macOS GUI
make gui-macos-dmg make gui-macos-dmg
# OR Build macOS GUI # OR Build Windows GUI
make gui-windows make gui-windows
# OR Build macOS GUI # OR Build Linux GUI
make gui-linux make gui-linux
# Check build output # Check build output
ls dist/ ls dist/
@@ -157,7 +157,7 @@ To enable the code coverage reports, see [here](https://fpgmaas.github.io/cookie
### macOS Error Message: File/App is damaged and cannot be opened. You should move it to Trash ### macOS Error Message: File/App is damaged and cannot be opened. You should move it to Trash
If you download an (unsigned) app from any source other than those that Apple seems suited, the application gets an extended attribute "com.apple.Quarantine". This triggers the message: "<application> is damaged and can't be opened. You should move it to the Bin." If you download an (unsigned) app from any source other than those that Apple deems trusted, the application gets an extended attribute "com.apple.Quarantine". This triggers the message: "<application> is damaged and can't be opened. You should move it to the Bin."
Remove the attribute and you can launch the application. [Source 1](https://discussions.apple.com/thread/253714860?sortBy=rank) [Source 2](https://www.reddit.com/r/macsysadmin/comments/13vu7f3/app_is_damaged_and_cant_be_opened_error_on_ventura/) Remove the attribute and you can launch the application. [Source 1](https://discussions.apple.com/thread/253714860?sortBy=rank) [Source 2](https://www.reddit.com/r/macsysadmin/comments/13vu7f3/app_is_damaged_and_cant_be_opened_error_on_ventura/)
@@ -165,9 +165,9 @@ Remove the attribute and you can launch the application. [Source 1](https://disc
sudo xattr -dr com.apple.quarantine /Applications/TIDAL-Downloader-NG.app/ sudo xattr -dr com.apple.quarantine /Applications/TIDAL-Downloader-NG.app/
``` ```
Why is this app unsigned? Only developer enrolled in the paid Apple developer program are allowed to sign (legal) apps. Without this subscription app signing is not possible. Why is this app unsigned? Only developers enrolled in the paid Apple Developer Program are allowed to sign (legal) apps. Without this subscription, app signing is not possible.
Gatekeeper really annoys you, and you like to disable it completely? Follow this [link](https://iboysoft.com/tips/how-to-disable-gatekeeper-macos-sequoia.html) Does Gatekeeper really annoy you, and you'd like to disable it completely? Follow this [link](https://iboysoft.com/tips/how-to-disable-gatekeeper-macos-sequoia.html)
### My (Windows) antivirus app XYZ says the GUI version of this app is harmful ### My (Windows) antivirus app XYZ says the GUI version of this app is harmful
@@ -191,13 +191,13 @@ sudo apt install libxcb-cursor0
### A terminal is flashing when I run this app on Windows ### 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. This is due to the Python `ffmpeg` library which is used and only happens on windows if `extract_flac` is activated.
### How can I download Dolby Atmos files? ### How can I download Dolby Atmos files?
You need to activate `download_dolby_atmos` in the settings. Then, if an item is available in Dolby Atmos, it will be downloaded as an Dolby Atmos file instead of as an stereo audio file. Dolby Atmos ist only available as 320kbps at TIDAL (you cannot adjust the quality for Dolby Atmos downloads). If an item is available in Dolby Atmos the "Quality" column in the GUI will indicate this with `Dolby Atmos` You need to activate `download_dolby_atmos` in the settings. Then, if an item is available in Dolby Atmos, it will be downloaded as a Dolby Atmos file instead of a stereo audio file. Dolby Atmos is only available as 320kbps at TIDAL (you cannot adjust the quality for Dolby Atmos downloads). If an item is available in Dolby Atmos, the "Quality" column in the GUI will indicate this with `Dolby Atmos`.
## ‼️ Disclaimer ## ‼️ Disclaimer
+2 -2
View File
@@ -2,7 +2,7 @@
name = "tidal-dl-ng" name = "tidal-dl-ng"
authors = [{ name = "Robert Honz", email = "<cen.sored@gmail.com>" }] authors = [{ name = "Robert Honz", email = "<cen.sored@gmail.com>" }]
version = "0.31.4" version = "0.31.4"
description = "TIDAL Medial Downloader Next Generation!" description = "TIDAL Media Downloader Next Generation!"
readme = "README.md" readme = "README.md"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
license-files = ["LICENSE"] license-files = ["LICENSE"]
@@ -132,7 +132,7 @@ ignore = [
# Do not use bare `except` # Do not use bare `except`
"E722", "E722",
# PEP 484 prohibits implicit `Optional` # PEP 484 prohibits implicit `Optional`
# Disabled only temporarely. # Disabled only temporarily.
"RUF013", "RUF013",
] ]
+5 -5
View File
@@ -171,7 +171,7 @@ def _process_url(
return False return False
if "http" not in url: 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 return True
url_clean: str = url_ending_clean(url) url_clean: str = url_ending_clean(url)
@@ -286,7 +286,7 @@ def settings_management(
Args: 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. 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: if editor:
config_path: Path = Path(path_file_settings()) config_path: Path = Path(path_file_settings())
@@ -333,7 +333,7 @@ def login(ctx: typer.Context) -> bool:
Returns: Returns:
bool: True if login was successful, False otherwise. 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() settings = Settings()
tidal = Tidal(settings) tidal = Tidal(settings)
@@ -375,7 +375,7 @@ def download(
writable=False, writable=False,
readable=True, readable=True,
resolve_path=True, resolve_path=True,
help="List with URLs to download. One per line", help="File with URLs to download. One URL per line.",
), ),
] = None, ] = None,
) -> bool: ) -> bool:
@@ -395,7 +395,7 @@ def download(
text: str = file_urls.read_text() text: str = file_urls.read_text()
urls = text.splitlines() urls = text.splitlines()
else: 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() raise typer.Abort()
-1
View File
@@ -71,7 +71,6 @@ class BaseConfig:
# Move the invalid config file to the backup location. # Move the invalid config file to the backup location.
shutil.move(path, path_bak) shutil.move(path, path_bak)
# TODO: Implement better global logger.
print( print(
"Something is wrong with your config. Maybe it is not compatible anymore due to a new app version." "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." f" You can find a backup of your old config here: '{path_bak}'. A new default config was created."
+2 -2
View File
@@ -203,7 +203,7 @@ class DialogPreferences(QtWidgets.QDialog):
): ):
# If a path is set, use it otherwise the users home directory. # 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 "" 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 = (
path_settings if path_settings else os.path.expanduser(path_default) if path_default else 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) 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(): if dialog.exec():
dir_name: str = dialog.selectedFiles()[0] dir_name: str = dialog.selectedFiles()[0]
path: Path = Path(dir_name) path: Path = Path(dir_name)
+3 -3
View File
@@ -406,7 +406,7 @@ class Download:
with path_file.open("wb") as f_target: with path_file.open("wb") as f_target:
for dl_segment_result in dl_segment_results: for dl_segment_result in dl_segment_results:
with dl_segment_result.path_segment.open("rb") as f_segment: 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): while segment := f_segment.read(CHUNK_SIZE):
f_target.write(segment) f_target.write(segment)
@@ -1244,7 +1244,7 @@ class Download:
response: requests.Response = requests.get(url, timeout=REQUESTS_TIMEOUT_SEC) response: requests.Response = requests.get(url, timeout=REQUESTS_TIMEOUT_SEC)
result = response.content result = response.content
except Exception as e: except Exception as e:
# TODO: Implement propper logging. # TODO: Implement proper logging.
print(e) print(e)
finally: finally:
response.close() response.close()
@@ -1253,7 +1253,7 @@ class Download:
with open(path_file, "rb") as f: with open(path_file, "rb") as f:
result = f.read() result = f.read()
except OSError as e: except OSError as e:
# TODO: Implement propper logging. # TODO: Implement proper logging.
print(e) print(e)
return result return result
+4 -4
View File
@@ -69,7 +69,7 @@ class Settings:
@dataclass @dataclass
class HelpSettings: class HelpSettings:
skip_existing: str = "Skip download if file already exists." 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." 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." 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." 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." "will be converted to MP4. FFmpeg must be installed."
) )
path_binary_ffmpeg: str = ( path_binary_ffmpeg: str = (
"Path to FFmpeg binary file (executable). Only necessary if FFmpeg not set in $PATH. Mandatory for Windows: " "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%." "The directory of `ffmpeg.exe` must be set in %PATH%."
) )
metadata_cover_dimension: str = ( 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." metadata_cover_embed: str = "Embed album cover into file."
mark_explicit: str = "Mark explicit tracks with '🅴' in track title (only applies to metadata)." mark_explicit: str = "Mark explicit tracks with '🅴' in track title (only applies to metadata)."