3 Commits

Author SHA1 Message Date
Andy
07574d8d02 refactor(binaries): remove unused mypy import 2025-10-22 20:47:46 +00:00
Andy
9b5d233c69 fix(dl): validate HYBRID mode requirements before download
Add validation to check that both HDR10 and DV tracks are available when HYBRID mode is requested. This prevents wasted downloads when the hybrid processing would fail due to missing tracks.
2025-10-22 20:46:52 +00:00
Andy
98d4bb4333 fix(config): support config in user config directory across platforms
Fixes #23
2025-10-22 16:48:03 +00:00
3 changed files with 25 additions and 4 deletions

View File

@@ -1002,6 +1002,29 @@ class dl:
selected_videos.append(match) selected_videos.append(match)
title.tracks.videos = selected_videos title.tracks.videos = selected_videos
# validate hybrid mode requirements
if any(r == Video.Range.HYBRID for r in range_):
hdr10_tracks = [v for v in title.tracks.videos if v.range == Video.Range.HDR10]
dv_tracks = [v for v in title.tracks.videos if v.range == Video.Range.DV]
if not hdr10_tracks and not dv_tracks:
available_ranges = sorted(set(v.range.name for v in title.tracks.videos))
self.log.error("HYBRID mode requires both HDR10 and DV tracks, but neither is available")
self.log.error(
f"Available ranges: {', '.join(available_ranges) if available_ranges else 'none'}"
)
sys.exit(1)
elif not hdr10_tracks:
available_ranges = sorted(set(v.range.name for v in title.tracks.videos))
self.log.error("HYBRID mode requires both HDR10 and DV tracks, but only DV is available")
self.log.error(f"Available ranges: {', '.join(available_ranges)}")
sys.exit(1)
elif not dv_tracks:
available_ranges = sorted(set(v.range.name for v in title.tracks.videos))
self.log.error("HYBRID mode requires both HDR10 and DV tracks, but only HDR10 is available")
self.log.error(f"Available ranges: {', '.join(available_ranges)}")
sys.exit(1)
# filter subtitle tracks # filter subtitle tracks
if require_subs: if require_subs:
missing_langs = [ missing_langs = [

View File

@@ -3,8 +3,6 @@ import sys
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from mypy.types import names
__shaka_platform = {"win32": "win", "darwin": "osx"}.get(sys.platform, sys.platform) __shaka_platform = {"win32": "win", "darwin": "osx"}.get(sys.platform, sys.platform)

View File

@@ -118,8 +118,8 @@ POSSIBLE_CONFIG_PATHS = (
Config._Directories.namespace_dir / Config._Filenames.root_config, Config._Directories.namespace_dir / Config._Filenames.root_config,
# The Parent Folder to the unshackle Namespace Folder (e.g., %appdata%/Python/Python311/site-packages) # The Parent Folder to the unshackle Namespace Folder (e.g., %appdata%/Python/Python311/site-packages)
Config._Directories.namespace_dir.parent / Config._Filenames.root_config, Config._Directories.namespace_dir.parent / Config._Filenames.root_config,
# The AppDirs User Config Folder (e.g., %localappdata%/unshackle) # The AppDirs User Config Folder (e.g., ~/.config/unshackle on Linux, %LOCALAPPDATA%\unshackle on Windows)
Config._Directories.user_configs / Config._Filenames.root_config, Path(Config._Directories.app_dirs.user_config_dir) / Config._Filenames.root_config,
) )