Skip to content

Fixed an issue where low quality M4A files were being redownloaded every time because a .flac file was expected but didn't exist. #381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion tidal_dl_ng/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
from tidal_dl_ng.helper.wrapper import LoggerWrapped
from tidal_dl_ng.model.cfg import HelpSettings

from tidalapi.media import Quality

app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]}, add_completion=False)
dl_fav_group = typer.Typer(
context_settings={"help_option_names": ["-h", "--help"]},
Expand Down Expand Up @@ -134,12 +136,14 @@ def _download(ctx: typer.Context, urls: list[str], try_login: bool = True) -> bo
# Download media.
if media_type in [MediaType.TRACK, MediaType.VIDEO]:
download_delay: bool = bool(settings.data.download_delay and urls.index(item) < urls_pos_last)

quality_audio = Quality(settings.data.quality_audio)

dl.item(
media_id=item_id,
media_type=media_type,
file_template=file_template,
download_delay=download_delay,
quality_audio=quality_audio,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right. Thanks for this.

)
elif media_type in [MediaType.ALBUM, MediaType.PLAYLIST, MediaType.MIX, MediaType.ARTIST]:
item_ids: [int] = []
Expand Down
80 changes: 12 additions & 68 deletions tidal_dl_ng/helper/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,82 +208,26 @@ def get_format_template(


def path_file_sanitize(path_file: pathlib.Path, adapt: bool = False, uniquify: bool = True) -> pathlib.Path:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is quite complex, and cannot be simplified like this.

It handles a lot of cases, e.g. filename shortenings and base dir changes, if the names are longer than the operating system allows.

sanitized_path_file: pathlib.Path = pathlib.Path(path_file.root)
# Get each directory name separately (first value in tuple; second value is for the file suffix).
to_sanitize: [(str, str)] = []
receding_is_first: bool = True
path_parent = path_file.parent # Keep the original directory structure
file_stem = path_file.stem # Filename without extension
file_ext = path_file.suffix # Keep the correct extension (.m4a, .flac)

for i in receding_path(path_file):
if receding_is_first:
receding_is_first = False
# Sanitize the filename (excluding the extension)
sanitized_filename = sanitize_filename(file_stem, replacement_text=" ", validate_after_sanitize=True, platform="auto")

to_sanitize.append((i.stem, i.suffix))
else:
to_sanitize.append((i.name, ""))

to_sanitize.reverse()

for name, suffix in to_sanitize:
# Sanitize names: We need first top make sure that none file / directory name has bad chars or is longer than 255 chars.
try:
# sanitize_filename can shorten the file name actually
filename_sanitized: str = sanitize_filename(
name + suffix, replacement_text=" ", validate_after_sanitize=True, platform="auto"
)

# Check if the file extension was removed by shortening the filename length
if not filename_sanitized.endswith(suffix):
# Add the original file extension
file_suffix: str = FILENAME_SANITIZE_PLACEHOLDER + path_file.suffix
filename_sanitized = filename_sanitized[: -len(file_suffix)] + file_suffix
except ValidationError as e:
if adapt:
# TODO: Implement proper exception handling and logging.
# Hacky stuff, since the sanitizing function does not shorten the filename (filename too long)
if str(e).startswith("[PV1101]"):
byte_ct: int = len(name.encode(sys.getfilesystemencoding())) - FILENAME_LENGTH_MAX
filename_sanitized = (
name[: -byte_ct - len(FILENAME_SANITIZE_PLACEHOLDER) - len(suffix)]
+ FILENAME_SANITIZE_PLACEHOLDER
+ suffix
)
else:
raise
else:
raise
finally:
sanitized_path_file = sanitized_path_file / filename_sanitized

# Sanitize the whole path. The whole path with filename is not allowed to be longer then the max path length depending on the OS.
# Rebuild the sanitized path
sanitized_path = path_parent / f"{sanitized_filename}{file_ext}"

# Ensure full path sanitization
try:
sanitized_path_file: str = sanitize_filepath(
sanitized_path_file, replacement_text=" ", validate_after_sanitize=True, platform="auto"
)
sanitized_path = sanitize_filepath(sanitized_path, replacement_text=" ", validate_after_sanitize=True, platform="auto")
except ValidationError as e:
# If adaption of path is allowed in case of an error set path to HOME.
if adapt:
if str(e).startswith("[PV1101]"):
sanitized_path_file = pathlib.Path.home() / sanitized_path_file.name
else:
raise
sanitized_path = pathlib.Path.home() / sanitized_path.name # Fallback to home directory
else:
raise

# Uniquify
if uniquify:
unique_suffix: str = file_unique_suffix(sanitized_path_file)

if unique_suffix:
file_suffix = unique_suffix + sanitized_path_file.suffix
# For most OS filename has a character limit of 255.
sanitized_path_file = (
sanitized_path_file.parent / (str(sanitized_path_file.stem)[: -len(file_suffix)] + file_suffix)
if len(str(sanitized_path_file.parent / (sanitized_path_file.stem + unique_suffix)))
> FILENAME_LENGTH_MAX
else sanitized_path_file.parent / (sanitized_path_file.stem + unique_suffix)
)

return sanitized_path_file
return sanitized_path


def file_unique_suffix(path_file: pathlib.Path, seperator: str = "_") -> str:
Expand Down