refactor: support more yt-dlp options for metadata save_path. ref #539

This commit is contained in:
arabcoders 2026-01-09 18:57:25 +03:00
parent c8e2fc5dc9
commit 345337a1a2
3 changed files with 32 additions and 20 deletions

View file

@ -160,6 +160,7 @@
"rejecttitle", "rejecttitle",
"remux", "remux",
"reqs", "reqs",
"restrictfilenames",
"RPAREN", "RPAREN",
"rtime", "rtime",
"rvfc", "rvfc",

View file

@ -96,29 +96,34 @@ class FileLogFormatter(logging.Formatter):
return datetime.fromtimestamp(record.created).astimezone().isoformat(timespec="milliseconds") return datetime.fromtimestamp(record.created).astimezone().isoformat(timespec="milliseconds")
def get_static_ytdlp(reload: bool = False) -> YTDLP: def get_ytdlp(params: dict | None = None) -> YTDLP:
""" """
Get a static YTDLP instance for info extraction. Get a static YTDLP instance for info extraction.
Args: Args:
reload (bool): If True, forces re-creation of the instance. params (dict|None): YTDLP parameters.
Returns: Returns:
YTDLP: A static YTDLP instance. YTDLP: A static YTDLP instance.
""" """
global YTDLP_INFO_CLS # noqa: PLW0603 global YTDLP_INFO_CLS # noqa: PLW0603
if YTDLP_INFO_CLS is None or reload:
YTDLP_INFO_CLS = YTDLP( default_params: dict[str, Any] = {
params={ "color": "no_color",
"color": "no_color", "extract_flat": True,
"extract_flat": True, "skip_download": True,
"skip_download": True, "ignoreerrors": True,
"ignoreerrors": True, "ignore_no_formats_error": True,
"ignore_no_formats_error": True, "quiet": True,
"quiet": True, }
}
) if params:
return YTDLP(params=merge_dict(params, default_params))
if YTDLP_INFO_CLS is None:
YTDLP_INFO_CLS = YTDLP(params=default_params)
return YTDLP_INFO_CLS return YTDLP_INFO_CLS
@ -1438,7 +1443,7 @@ def get_archive_id(url: str) -> dict[str, str | None]:
"archive_id": None, "archive_id": None,
} }
for key, _ie in get_static_ytdlp()._ies.items(): for key, _ie in get_ytdlp()._ies.items():
try: try:
if not _ie.suitable(url): if not _ie.suitable(url):
continue continue
@ -1937,16 +1942,17 @@ def get_extras(entry: dict, kind: str = "video") -> dict:
return extras return extras
def parse_outtmpl(output_template: str, info_dict: dict) -> str: def parse_outtmpl(output_template: str, info_dict: dict, params: dict | None = None) -> str:
""" """
Parse yt-dlp output template with given info_dict. Parse yt-dlp output template with given info_dict.
Args: Args:
output_template (str): The output template string. output_template (str): The output template string.
info_dict (dict): The info dictionary from yt-dlp. info_dict (dict): The info dictionary from yt-dlp.
params (dict|None): Additional parameters for yt-dlp.
Returns: Returns:
str: The parsed output string. str: The parsed output string.
""" """
return get_static_ytdlp().prepare_filename(info_dict=info_dict, outtmpl=output_template) return get_ytdlp(params=params).prepare_filename(info_dict=info_dict, outtmpl=output_template)

View file

@ -2,6 +2,7 @@ import asyncio
import functools import functools
import logging import logging
import uuid import uuid
from pathlib import Path
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
from aiohttp import web from aiohttp import web
@ -266,14 +267,16 @@ async def task_metadata(request: Request, config: Config, encoder: Encoder) -> R
if not task.folder: if not task.folder:
try: try:
outtmpl = parse_outtmpl( ytdlp_opts: dict = task.get_ytdlp_opts().get_all()
output_template=task.get_ytdlp_opts().get_all().get("outtmpl", {}).get("default", "{title} [{id}]"), outtmpl: str = parse_outtmpl(
output_template=ytdlp_opts.get("outtmpl", {}).get("default", "{title} [{id}]"),
info_dict=metadata, info_dict=metadata,
params=ytdlp_opts,
) )
if outtmpl: if outtmpl:
_path = save_path / outtmpl _path: Path = save_path / outtmpl
if not _path.is_dir(): if not _path.is_dir():
_path = _path.parent _path: Path = _path.parent
(save_path, _) = get_file(config.download_path, _path.relative_to(config.download_path)) (save_path, _) = get_file(config.download_path, _path.relative_to(config.download_path))
if not str(save_path or "").startswith(str(config.download_path)): if not str(save_path or "").startswith(str(config.download_path)):
@ -302,6 +305,8 @@ async def task_metadata(request: Request, config: Config, encoder: Encoder) -> R
data={"error": "Failed to get title from metadata."}, status=web.HTTPBadRequest.status_code data={"error": "Failed to get title from metadata."}, status=web.HTTPBadRequest.status_code
) )
LOG.info(f"Generating metadata for task '{task.name}' in '{save_path!s}'")
from yt_dlp.utils import sanitize_filename from yt_dlp.utils import sanitize_filename
from app.yt_dlp_plugins.postprocessor.nfo_maker import NFOMakerPP from app.yt_dlp_plugins.postprocessor.nfo_maker import NFOMakerPP