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",
"remux",
"reqs",
"restrictfilenames",
"RPAREN",
"rtime",
"rvfc",

View file

@ -96,29 +96,34 @@ class FileLogFormatter(logging.Formatter):
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.
Args:
reload (bool): If True, forces re-creation of the instance.
params (dict|None): YTDLP parameters.
Returns:
YTDLP: A static YTDLP instance.
"""
global YTDLP_INFO_CLS # noqa: PLW0603
if YTDLP_INFO_CLS is None or reload:
YTDLP_INFO_CLS = YTDLP(
params={
"color": "no_color",
"extract_flat": True,
"skip_download": True,
"ignoreerrors": True,
"ignore_no_formats_error": True,
"quiet": True,
}
)
default_params: dict[str, Any] = {
"color": "no_color",
"extract_flat": True,
"skip_download": True,
"ignoreerrors": True,
"ignore_no_formats_error": 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
@ -1438,7 +1443,7 @@ def get_archive_id(url: str) -> dict[str, str | None]:
"archive_id": None,
}
for key, _ie in get_static_ytdlp()._ies.items():
for key, _ie in get_ytdlp()._ies.items():
try:
if not _ie.suitable(url):
continue
@ -1937,16 +1942,17 @@ def get_extras(entry: dict, kind: str = "video") -> dict:
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.
Args:
output_template (str): The output template string.
info_dict (dict): The info dictionary from yt-dlp.
params (dict|None): Additional parameters for yt-dlp.
Returns:
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 logging
import uuid
from pathlib import Path
from typing import TYPE_CHECKING, Any
from aiohttp import web
@ -266,14 +267,16 @@ async def task_metadata(request: Request, config: Config, encoder: Encoder) -> R
if not task.folder:
try:
outtmpl = parse_outtmpl(
output_template=task.get_ytdlp_opts().get_all().get("outtmpl", {}).get("default", "{title} [{id}]"),
ytdlp_opts: dict = task.get_ytdlp_opts().get_all()
outtmpl: str = parse_outtmpl(
output_template=ytdlp_opts.get("outtmpl", {}).get("default", "{title} [{id}]"),
info_dict=metadata,
params=ytdlp_opts,
)
if outtmpl:
_path = save_path / outtmpl
_path: Path = save_path / outtmpl
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))
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
)
LOG.info(f"Generating metadata for task '{task.name}' in '{save_path!s}'")
from yt_dlp.utils import sanitize_filename
from app.yt_dlp_plugins.postprocessor.nfo_maker import NFOMakerPP