This commit is contained in:
@@ -12,6 +12,7 @@ CHUNK_SIZE: int = BLOCK_SIZE * BLOCKS
|
|||||||
PLAYLIST_EXTENSION: str = ".m3u"
|
PLAYLIST_EXTENSION: str = ".m3u"
|
||||||
PLAYLIST_PREFIX: str = "_"
|
PLAYLIST_PREFIX: str = "_"
|
||||||
FILENAME_LENGTH_MAX: int = 255
|
FILENAME_LENGTH_MAX: int = 255
|
||||||
|
FORMAT_TEMPLATE_EXPLICIT: str = " (Explicit)"
|
||||||
|
|
||||||
|
|
||||||
class QualityVideo(StrEnum):
|
class QualityVideo(StrEnum):
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from uuid import uuid4
|
|||||||
import m3u8
|
import m3u8
|
||||||
import requests
|
import requests
|
||||||
from ffmpeg import FFmpeg
|
from ffmpeg import FFmpeg
|
||||||
|
from pathvalidate import sanitize_filename
|
||||||
from requests.adapters import HTTPAdapter, Retry
|
from requests.adapters import HTTPAdapter, Retry
|
||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
from rich.progress import Progress, TaskID
|
from rich.progress import Progress, TaskID
|
||||||
@@ -36,7 +37,6 @@ from tidal_dl_ng.helper.path import (
|
|||||||
check_file_exists,
|
check_file_exists,
|
||||||
format_path_media,
|
format_path_media,
|
||||||
path_file_sanitize,
|
path_file_sanitize,
|
||||||
sanitize_filename,
|
|
||||||
url_to_filename,
|
url_to_filename,
|
||||||
)
|
)
|
||||||
from tidal_dl_ng.helper.tidal import (
|
from tidal_dl_ng.helper.tidal import (
|
||||||
@@ -437,9 +437,12 @@ class Download:
|
|||||||
elif isinstance(media, Video):
|
elif isinstance(media, Video):
|
||||||
file_extension = AudioExtensions.MP4 if self.settings.data.video_convert_mp4 else VideoExtensions.TS
|
file_extension = AudioExtensions.MP4 if self.settings.data.video_convert_mp4 else VideoExtensions.TS
|
||||||
|
|
||||||
# Compute file name, sanitize once again and create destination directory
|
# 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 = path_media_dst.with_suffix(file_extension)
|
||||||
path_media_dst = pathlib.Path(path_file_sanitize(path_media_dst, adapt=True))
|
path_media_dst = pathlib.Path(path_file_sanitize(path_media_dst, adapt=True))
|
||||||
|
|
||||||
os.makedirs(path_media_dst.parent, exist_ok=True)
|
os.makedirs(path_media_dst.parent, exist_ok=True)
|
||||||
|
|
||||||
if not skip_download:
|
if not skip_download:
|
||||||
|
|||||||
@@ -13,7 +13,13 @@ from tidalapi import Album, Mix, Playlist, Track, UserPlaylist, Video
|
|||||||
from tidalapi.media import AudioExtensions
|
from tidalapi.media import AudioExtensions
|
||||||
|
|
||||||
from tidal_dl_ng import __name_display__
|
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
|
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)
|
result_fmt = format_str_media(match.group(1), media, album_track_num_pad_min, list_pos, list_total)
|
||||||
|
|
||||||
if result_fmt != match.group(1):
|
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)
|
result = result.replace(template_str, value)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -164,10 +174,10 @@ def format_str_media(
|
|||||||
result = ", ".join(tag for tag in media.media_metadata_tags)
|
result = ", ".join(tag for tag in media.media_metadata_tags)
|
||||||
case "track_explicit":
|
case "track_explicit":
|
||||||
if isinstance(media, Track | Video):
|
if isinstance(media, Track | Video):
|
||||||
result = " (Explicit)" if media.explicit else ""
|
result = FORMAT_TEMPLATE_EXPLICIT if media.explicit else ""
|
||||||
case "album_explicit":
|
case "album_explicit":
|
||||||
if isinstance(media, Album):
|
if isinstance(media, Album):
|
||||||
result = " (Explicit)" if media.explicit else ""
|
result = FORMAT_TEMPLATE_EXPLICIT if media.explicit else ""
|
||||||
case "album_num_volumes":
|
case "album_num_volumes":
|
||||||
if isinstance(media, Album):
|
if isinstance(media, Album):
|
||||||
result = str(media.num_volumes)
|
result = str(media.num_volumes)
|
||||||
@@ -264,6 +274,19 @@ def path_file_sanitize(path_file: pathlib.Path, adapt: bool = False, uniquify: b
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
# Sanitize the path.
|
# 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:
|
try:
|
||||||
sanitized_path: pathlib.Path = sanitize_filepath(
|
sanitized_path: pathlib.Path = sanitize_filepath(
|
||||||
sanitized_path, replacement_text="_", validate_after_sanitize=True, platform="auto"
|
sanitized_path, replacement_text="_", validate_after_sanitize=True, platform="auto"
|
||||||
|
|||||||
Reference in New Issue
Block a user