fix: recent change made fetch_info unpicklable

This commit is contained in:
arabcoders 2026-05-18 22:12:13 +03:00
parent 88db357b7f
commit 3b3c8120b8
3 changed files with 55 additions and 14 deletions

View file

@ -19,19 +19,32 @@ LOG: logging.Logger = logging.getLogger("downloads.extractor")
def _ytdlp_logger(target: logging.Logger):
def _log(level: int, msg: str, *args: Any, **kwargs: Any) -> None:
return _YTDLPLogger(target)
class _YTDLPLogger:
def __init__(self, target: logging.Logger) -> None:
self.target = target
def __call__(self, level: int, msg: str, *args: Any, **kwargs: Any) -> None:
kwargs.setdefault("stacklevel", 4)
if level <= logging.DEBUG and isinstance(msg, str) and msg.startswith("[debug] "):
target.debug(msg.removeprefix("[debug] "), *args, **kwargs)
self.target.debug(msg.removeprefix("[debug] "), *args, **kwargs)
return
if level <= logging.DEBUG:
target.info(msg, *args, **kwargs)
self.target.info(msg, *args, **kwargs)
return
target.log(level, msg, *args, **kwargs)
self.target.log(level, msg, *args, **kwargs)
return _log
class _LogCapture:
def __init__(self, logs: list[str]) -> None:
self.logs = logs
def __call__(self, _: int, msg: str, *args: Any, **__: Any) -> None:
self.logs.append(msg % args if args else msg)
def _get_process_pool_kwargs() -> dict[str, Any]:
@ -243,7 +256,7 @@ def extract_info_sync(
sanitize_info: bool = False,
capture_logs: int | None = None,
**kwargs,
) -> tuple[dict[str, Any] | None, list[dict[str, Any]]]:
) -> tuple[dict[str, Any] | None, list[str]]:
"""
Extract video information from a URL.
@ -258,7 +271,7 @@ def extract_info_sync(
**kwargs: Additional arguments
Returns:
tuple[dict | None, list[dict]]: Extracted information and captured logs.
tuple[dict | None, list[str]]: Extracted information and captured logs.
"""
params: dict[str, Any] = {**config, **_DATA.YTDLP_PARAMS, "simulate": True}
@ -287,7 +300,7 @@ def extract_info_sync(
captured_logs: list[str] = kwargs.get("captured_logs", [])
if capture_logs is not None:
log_wrapper.add_target(
target=lambda _, msg: captured_logs.append(msg),
target=_LogCapture(captured_logs),
level=capture_logs,
name="log-capture",
)
@ -351,7 +364,7 @@ async def fetch_info(
extractor_config: ExtractorConfig | None = None,
budget_sleep: bool = False,
**kwargs,
) -> tuple[dict[str, Any] | None, list[dict[str, Any]]]:
) -> tuple[dict[str, Any] | None, list[str]]:
"""
Extract video information from a URL.
@ -371,7 +384,7 @@ async def fetch_info(
**kwargs: Additional arguments
Returns:
tuple[dict | None, list[dict]]: Extracted information and captured logs.
tuple[dict | None, list[str]]: Extracted information and captured logs.
"""
if extractor_config is None:

View file

@ -1,13 +1,16 @@
import logging
import pickle
from unittest.mock import MagicMock, patch
from app.features.ytdlp.extractor import (
ExtractorConfig,
ExtractorPool,
_LogCapture,
_get_process_pool_kwargs,
_ytdlp_logger,
extract_info_sync,
)
from app.features.ytdlp.utils import LogWrapper
class TestProcessPoolConfiguration:
@ -170,3 +173,18 @@ class TestYtdlpLogger:
_ytdlp_logger(logger)(logging.DEBUG, "screen line")
logger.info.assert_called_once_with("screen line", stacklevel=4)
def test_targets_are_picklable(self) -> None:
logs: list[str] = []
wrapper = LogWrapper()
wrapper.add_target(_ytdlp_logger(logging.getLogger("yt-dlp.test")), level=logging.DEBUG, name="yt-dlp.test")
wrapper.add_target(_LogCapture(logs), level=logging.WARNING, name="log-capture")
pickle.dumps(wrapper)
def test_capture_formats_args(self) -> None:
logs: list[str] = []
_LogCapture(logs)(logging.WARNING, "hello %s", "world")
assert logs == ["hello world"]

View file

@ -142,7 +142,9 @@
]"
>
<p :class="logLineClass()">
<span class="inline-flex items-center gap-2 align-middle">
<span
class="inline-flex max-w-full flex-wrap items-center gap-x-2 gap-y-1 align-middle"
>
<UTooltip :text="logTimeTitle(entry.log.datetime)">
<span class="inline text-[11px] font-semibold text-toned cursor-pointer">
{{ logTimeLabel(entry.log.datetime) }}
@ -169,7 +171,8 @@
</span>
<span
v-if="entry.log.logger"
class="inline text-[11px] font-semibold text-toned"
:title="entry.log.logger"
class="inline-block max-w-[46vw] truncate align-middle text-[11px] font-semibold text-toned sm:max-w-104"
>[{{ entry.log.logger }}]</span
>
</span>
@ -223,8 +226,15 @@
/>
{{ getLogLevel(selectedLog.level) }}
</UBadge>
<UBadge v-if="selectedLog.logger" color="neutral" variant="soft" size="sm">
{{ selectedLog.logger }}
<UBadge
v-if="selectedLog.logger"
color="neutral"
variant="soft"
size="sm"
class="max-w-full min-w-0"
:title="selectedLog.logger"
>
<span class="min-w-0 max-w-full truncate">{{ selectedLog.logger }}</span>
</UBadge>
<span class="text-xs text-toned">{{ logTimeTitle(selectedLog.datetime) }}</span>
</div>