style: fix ruff E721, E701, and E722 lint errors

This commit is contained in:
Andy
2026-02-16 13:37:23 -07:00
parent df92f9e4b6
commit 0217086abf
2 changed files with 135 additions and 104 deletions

View File

@@ -195,12 +195,7 @@ class dl:
sdh_suffix = ".sdh" if (subtitle.sdh or subtitle.cc) else ""
extension = (target_codec or subtitle.codec or Subtitle.Codec.SubRip).extension
if (
not target_codec
and not subtitle.codec
and source_path
and source_path.suffix
):
if not target_codec and not subtitle.codec and source_path and source_path.suffix:
extension = source_path.suffix.lstrip(".")
filename = f"{base_filename}.{lang_suffix}{forced_suffix}{sdh_suffix}.{extension}"
@@ -1056,8 +1051,8 @@ class dl:
return
# Enables manual selection for Series when --select-titles is set
if select_titles and type(titles) == Series:
console.print(Padding(Rule(f"[rule.text]Select Titles"), (1, 2)))
if select_titles and isinstance(titles, Series):
console.print(Padding(Rule("[rule.text]Select Titles"), (1, 2)))
selection_titles = []
dependencies = {}
@@ -1085,9 +1080,7 @@ class dl:
# Apply indentation only for multiple seasons
prefix = " " if multiple_seasons else ""
option_text = (
f"{prefix}{t.number}" + (f". {display_name}" if t.name else "")
)
option_text = f"{prefix}{t.number}" + (f". {display_name}" if t.name else "")
selection_titles.append(option_text)
current_ui_idx = len(selection_titles) - 1
@@ -1103,15 +1096,11 @@ class dl:
# Execute selector with dependencies (headers select all children)
selected_ui_idx = select_multiple(
selection_titles,
minimal_count=1,
page_size=8,
return_indices=True,
dependencies=dependencies
selection_titles, minimal_count=1, page_size=8, return_indices=True, dependencies=dependencies
)
selection_end = time.time()
start_time += (selection_end - selection_start)
start_time += selection_end - selection_start
# Map UI indices back to title indices (excluding headers)
selected_idx = []
@@ -1604,7 +1593,10 @@ class dl:
if audio_description:
standard_audio = [a for a in title.tracks.audio if not a.descriptive]
selected_standards = title.tracks.by_language(
standard_audio, processed_lang, per_language=per_language, exact_match=exact_lang
standard_audio,
processed_lang,
per_language=per_language,
exact_match=exact_lang,
)
desc_audio = [a for a in title.tracks.audio if a.descriptive]
# Include all descriptive tracks for the requested languages.
@@ -1728,9 +1720,7 @@ class dl:
),
licence=partial(
service.get_playready_license
if (
is_playready_cdm(self.cdm)
)
if (is_playready_cdm(self.cdm))
and hasattr(service, "get_playready_license")
else service.get_widevine_license,
title=title,
@@ -1848,9 +1838,7 @@ class dl:
# Subtitle output mode configuration (for sidecar originals)
subtitle_output_mode = config.subtitle.get("output_mode", "mux")
sidecar_format = config.subtitle.get("sidecar_format", "srt")
skip_subtitle_mux = (
subtitle_output_mode == "sidecar" and (title.tracks.videos or title.tracks.audio)
)
skip_subtitle_mux = subtitle_output_mode == "sidecar" and (title.tracks.videos or title.tracks.audio)
sidecar_subtitles: list[Subtitle] = []
sidecar_original_paths: dict[str, Path] = {}
if subtitle_output_mode in ("sidecar", "both") and not no_mux:
@@ -2101,7 +2089,9 @@ class dl:
sidecar_dir = config.directories.downloads
if not no_folder and isinstance(title, (Episode, Song)) and media_info:
sidecar_dir /= title.get_filename(media_info, show_service=not no_source, folder=True)
sidecar_dir /= title.get_filename(
media_info, show_service=not no_source, folder=True
)
sidecar_dir.mkdir(parents=True, exist_ok=True)
with console.status("Saving subtitle sidecar files..."):

View File

@@ -1,21 +1,25 @@
import click
import sys
import click
from rich.console import Group
from rich.live import Live
from rich.padding import Padding
from rich.table import Table
from rich.text import Text
from unshackle.core.console import console
IS_WINDOWS = sys.platform == "win32"
if IS_WINDOWS:
import msvcrt
class Selector:
"""
A custom interactive selector class using the Rich library.
Allows for multi-selection of items with pagination.
"""
def __init__(
self,
options: list[str],
@@ -24,7 +28,7 @@ class Selector:
page_size: int = 8,
minimal_count: int = 0,
dependencies: dict[int, list[int]] = None,
prefixes: list[str] = None
prefixes: list[str] = None,
):
"""
Initialize the Selector.
@@ -61,8 +65,8 @@ class Selector:
if idx < len(self.options):
option = self.options[idx]
is_cursor = (idx == self.cursor_index)
is_selected = (idx in self.selected_indices)
is_cursor = idx == self.cursor_index
is_selected = idx in self.selected_indices
symbol = "[X]" if is_selected else "[ ]"
style = self.cursor_style if is_cursor else self.text_style
@@ -80,7 +84,7 @@ class Selector:
info_text = Text(
f"\n[Space]: Toggle [a]: All [←/→]: Page [Enter]: Confirm (Page {current_page}/{total_pages})",
style="gray"
style="gray",
)
return Padding(Group(table, info_text), (0, 5))
@@ -144,28 +148,43 @@ class Selector:
Returns command strings like 'UP', 'DOWN', 'ENTER', etc.
"""
key = msvcrt.getch()
if key == b'\x03' or key == b'\x1b':
return 'CANCEL'
if key == b'\xe0' or key == b'\x00':
if key == b"\x03" or key == b"\x1b":
return "CANCEL"
if key == b"\xe0" or key == b"\x00":
try:
key = msvcrt.getch()
if key == b'H': return 'UP'
if key == b'P': return 'DOWN'
if key == b'K': return 'LEFT'
if key == b'M': return 'RIGHT'
except: pass
if key == b"H":
return "UP"
if key == b"P":
return "DOWN"
if key == b"K":
return "LEFT"
if key == b"M":
return "RIGHT"
except Exception:
pass
try: char = key.decode('utf-8', errors='ignore')
except: return None
try:
char = key.decode("utf-8", errors="ignore")
except Exception:
return None
if char in ('\r', '\n'): return 'ENTER'
if char == ' ': return 'SPACE'
if char in ('q', 'Q'): return 'QUIT'
if char in ('a', 'A'): return 'ALL'
if char in ('w', 'W', 'k', 'K'): return 'UP'
if char in ('s', 'S', 'j', 'J'): return 'DOWN'
if char in ('h', 'H'): return 'LEFT'
if char in ('d', 'D', 'l', 'L'): return 'RIGHT'
if char in ("\r", "\n"):
return "ENTER"
if char == " ":
return "SPACE"
if char in ("q", "Q"):
return "QUIT"
if char in ("a", "A"):
return "ALL"
if char in ("w", "W", "k", "K"):
return "UP"
if char in ("s", "S", "j", "J"):
return "DOWN"
if char in ("h", "H"):
return "LEFT"
if char in ("d", "D", "l", "L"):
return "RIGHT"
return None
def get_input_unix(self):
@@ -174,37 +193,49 @@ class Selector:
Returns command strings like 'UP', 'DOWN', 'ENTER', etc.
"""
char = click.getchar()
if char == '\x03':
return 'CANCEL'
if char == "\x03":
return "CANCEL"
mapping = {
'\x1b[A': 'UP',
'\x1b[B': 'DOWN',
'\x1b[C': 'RIGHT',
'\x1b[D': 'LEFT',
"\x1b[A": "UP",
"\x1b[B": "DOWN",
"\x1b[C": "RIGHT",
"\x1b[D": "LEFT",
}
if char in mapping:
return mapping[char]
if char == '\x1b':
if char == "\x1b":
try:
next1 = click.getchar()
if next1 in ('[', 'O'):
if next1 in ("[", "O"):
next2 = click.getchar()
if next2 == 'A': return 'UP'
if next2 == 'B': return 'DOWN'
if next2 == 'C': return 'RIGHT'
if next2 == 'D': return 'LEFT'
return 'CANCEL'
except:
return 'CANCEL'
if next2 == "A":
return "UP"
if next2 == "B":
return "DOWN"
if next2 == "C":
return "RIGHT"
if next2 == "D":
return "LEFT"
return "CANCEL"
except Exception:
return "CANCEL"
if char in ('\r', '\n'): return 'ENTER'
if char == ' ': return 'SPACE'
if char in ('q', 'Q'): return 'QUIT'
if char in ('a', 'A'): return 'ALL'
if char in ('w', 'W', 'k', 'K'): return 'UP'
if char in ('s', 'S', 'j', 'J'): return 'DOWN'
if char in ('h', 'H'): return 'LEFT'
if char in ('d', 'D', 'l', 'L'): return 'RIGHT'
if char in ("\r", "\n"):
return "ENTER"
if char == " ":
return "SPACE"
if char in ("q", "Q"):
return "QUIT"
if char in ("a", "A"):
return "ALL"
if char in ("w", "W", "k", "K"):
return "UP"
if char in ("s", "S", "j", "J"):
return "DOWN"
if char in ("h", "H"):
return "LEFT"
if char in ("d", "D", "l", "L"):
return "RIGHT"
return None
def run(self) -> list[int]:
@@ -219,29 +250,39 @@ class Selector:
with Live(self.get_renderable(), console=console, auto_refresh=False, transient=True) as live:
while True:
live.update(self.get_renderable(), refresh=True)
if IS_WINDOWS: action = self.get_input_windows()
else: action = self.get_input_unix()
if IS_WINDOWS:
action = self.get_input_windows()
else:
action = self.get_input_unix()
if action == 'UP': self.move_cursor(-1)
elif action == 'DOWN': self.move_cursor(1)
elif action == 'LEFT': self.change_page(-1)
elif action == 'RIGHT': self.change_page(1)
elif action == 'SPACE': self.toggle_selection()
elif action == 'ALL': self.toggle_all()
elif action in ('ENTER', 'QUIT'):
if action == "UP":
self.move_cursor(-1)
elif action == "DOWN":
self.move_cursor(1)
elif action == "LEFT":
self.change_page(-1)
elif action == "RIGHT":
self.change_page(1)
elif action == "SPACE":
self.toggle_selection()
elif action == "ALL":
self.toggle_all()
elif action in ("ENTER", "QUIT"):
if len(self.selected_indices) >= self.minimal_count:
return sorted(list(self.selected_indices))
elif action == 'CANCEL': raise KeyboardInterrupt
elif action == "CANCEL":
raise KeyboardInterrupt
except KeyboardInterrupt:
return []
def select_multiple(
options: list[str],
minimal_count: int = 1,
page_size: int = 8,
return_indices: bool = True,
cursor_style: str = "pink",
**kwargs
**kwargs,
) -> list[int]:
"""
Drop-in replacement using custom Selector with global console.
@@ -259,7 +300,7 @@ def select_multiple(
text_style="text",
page_size=page_size,
minimal_count=minimal_count,
**kwargs
**kwargs,
)
selected_indices = selector.run()