summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorexislow <exislow@users.noreply.github.com>2025-06-30 16:36:01 +0200
committerGitHub <noreply@github.com>2025-06-30 16:36:01 +0200
commit28f15e0bffab3c55f6335530b080637ce187a429 (patch)
treef43cd0b021db36a71b53acd6247187fc6919b6fa
parent0eaeed533fbdc8790413f178cadb73b0ac6949aa (diff)
parent70e29771b930fe1a862fdacf58b244f227e017f2 (diff)
downloadtidal-dl-ng-28f15e0bffab3c55f6335530b080637ce187a429.tar.gz
Merge pull request #471 from exislow/447-character-limits-on-album-name
🛠️ Directory length limit is checked and adapted correctly now. Fixes #447 & #436
-rw-r--r--tidal_dl_ng/constants.py1
-rw-r--r--tidal_dl_ng/download.py11
-rw-r--r--tidal_dl_ng/helper/path.py31
3 files changed, 35 insertions, 8 deletions
diff --git a/tidal_dl_ng/constants.py b/tidal_dl_ng/constants.py
index 802fedf..0e0bb2c 100644
--- a/tidal_dl_ng/constants.py
+++ b/tidal_dl_ng/constants.py
@@ -12,6 +12,7 @@ CHUNK_SIZE: int = BLOCK_SIZE * BLOCKS
PLAYLIST_EXTENSION: str = ".m3u"
PLAYLIST_PREFIX: str = "_"
FILENAME_LENGTH_MAX: int = 255
+FORMAT_TEMPLATE_EXPLICIT: str = " (Explicit)"
class QualityVideo(StrEnum):
diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py
index c7c4af7..9b13053 100644
--- a/tidal_dl_ng/download.py
+++ b/tidal_dl_ng/download.py
@@ -12,6 +12,7 @@ from uuid import uuid4
import m3u8
import requests
from ffmpeg import FFmpeg
+from pathvalidate import sanitize_filename
from requests.adapters import HTTPAdapter, Retry
from requests.exceptions import HTTPError
from rich.progress import Progress, TaskID
@@ -36,7 +37,6 @@ from tidal_dl_ng.helper.path import (
check_file_exists,
format_path_media,
path_file_sanitize,
- sanitize_filename,
url_to_filename,
)
from tidal_dl_ng.helper.tidal import (
@@ -437,9 +437,12 @@ class Download:
elif isinstance(media, Video):
file_extension = AudioExtensions.MP4 if self.settings.data.video_convert_mp4 else VideoExtensions.TS
- # Compute file name, sanitize once again and create destination directory
- path_media_dst = path_media_dst.with_suffix(file_extension)
- path_media_dst = pathlib.Path(path_file_sanitize(path_media_dst, adapt=True))
+ # If file extension was guessed wrong in the beginning
+ if path_media_dst.suffix != file_extension:
+ # Compute file name, sanitize once again, because file extension could have been replaced after guessing it first and create destination directory
+ path_media_dst = path_media_dst.with_suffix(file_extension)
+ path_media_dst = pathlib.Path(path_file_sanitize(path_media_dst, adapt=True))
+
os.makedirs(path_media_dst.parent, exist_ok=True)
if not skip_download:
diff --git a/tidal_dl_ng/helper/path.py b/tidal_dl_ng/helper/path.py
index 5f8695a..db0a17c 100644
--- a/tidal_dl_ng/helper/path.py
+++ b/tidal_dl_ng/helper/path.py
@@ -13,7 +13,13 @@ from tidalapi import Album, Mix, Playlist, Track, UserPlaylist, Video
from tidalapi.media import AudioExtensions
from tidal_dl_ng import __name_display__
-from tidal_dl_ng.constants import FILENAME_LENGTH_MAX, FILENAME_SANITIZE_PLACEHOLDER, UNIQUIFY_THRESHOLD, MediaType
+from tidal_dl_ng.constants import (
+ FILENAME_LENGTH_MAX,
+ FILENAME_SANITIZE_PLACEHOLDER,
+ FORMAT_TEMPLATE_EXPLICIT,
+ UNIQUIFY_THRESHOLD,
+ MediaType,
+)
from tidal_dl_ng.helper.tidal import name_builder_album_artist, name_builder_artist, name_builder_title
@@ -68,7 +74,11 @@ def format_path_media(
result_fmt = format_str_media(match.group(1), media, album_track_num_pad_min, list_pos, list_total)
if result_fmt != match.group(1):
- value = sanitize_filename(result_fmt)
+ # Sanitize here, in case of the filename has slashes or something, which will be recognized later as a directory separator.
+ # Do not sanitize if value is the FORMAT_TEMPLATE_EXPLICIT placeholder, since it has a leading whitespace which otherwise gets removed.
+ value = (
+ sanitize_filename(result_fmt) if result_fmt != FORMAT_TEMPLATE_EXPLICIT else FORMAT_TEMPLATE_EXPLICIT
+ )
result = result.replace(template_str, value)
return result
@@ -164,10 +174,10 @@ def format_str_media(
result = ", ".join(tag for tag in media.media_metadata_tags)
case "track_explicit":
if isinstance(media, Track | Video):
- result = " (Explicit)" if media.explicit else ""
+ result = FORMAT_TEMPLATE_EXPLICIT if media.explicit else ""
case "album_explicit":
if isinstance(media, Album):
- result = " (Explicit)" if media.explicit else ""
+ result = FORMAT_TEMPLATE_EXPLICIT if media.explicit else ""
case "album_num_volumes":
if isinstance(media, Album):
result = str(media.num_volumes)
@@ -264,6 +274,19 @@ def path_file_sanitize(path_file: pathlib.Path, adapt: bool = False, uniquify: b
raise
# Sanitize the path.
+ # First sanitize sanitize each part of the path. Each part of the path is not allowed to be longer then 'PC_NAME_MAX'.
+ sanitized_parts = []
+
+ for part in sanitized_path.parts:
+ if part in sanitized_path.root:
+ sanitized_parts.append(part)
+ else:
+ sanitized_parts.append(
+ sanitize_filename(part, replacement_text="_", validate_after_sanitize=True, platform="auto")
+ )
+ sanitized_path = pathlib.Path(*sanitized_parts)
+
+ # Then sanitize the whole path itself. The whole path is not allowed to be longer than 'PC_NAME_MAX'.
try:
sanitized_path: pathlib.Path = sanitize_filepath(
sanitized_path, replacement_text="_", validate_after_sanitize=True, platform="auto"