diff --git a/app/library/Download.py b/app/library/Download.py index c2b041a5..6747ead6 100644 --- a/app/library/Download.py +++ b/app/library/Download.py @@ -1,6 +1,5 @@ import asyncio import hashlib -import json import logging import multiprocessing import os @@ -15,7 +14,7 @@ from .config import Config from .Emitter import Emitter from .ffprobe import ffprobe from .ItemDTO import ItemDTO -from .Utils import get_opts, json_cookie, merge_config +from .Utils import get_opts, merge_config LOG = logging.getLogger("download") @@ -138,17 +137,11 @@ class Download: if self.info.cookies: try: - data = json_cookie(json.loads(self.info.cookies)) - if not data: - LOG.warning( - f"The cookie string that was provided for {self.info.title} is empty or not in expected spec." - ) with open(os.path.join(self.temp_path, f"cookie_{self.info._id}.txt"), "w") as f: - f.write(data) - - params["cookiefile"] = f.name + f.write(self.info.cookies) + params["cookiefile"] = f.name except ValueError as e: - LOG.error(f"Invalid cookies: was provided for '{self.info.title}'. '{e!s}'.") + LOG.error(f"Failed to create cookie file for '{self.info.id}: {self.info.title}'. '{e!s}'.") if self.is_live or self.is_manifestless: hasDeletedOptions = False diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index a14fd8f9..10079d4e 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -3,10 +3,12 @@ import json import logging import os import time +import uuid from datetime import UTC, datetime from email.utils import formatdate from sqlite3 import Connection +import anyio import yt_dlp from aiohttp import web @@ -354,9 +356,11 @@ class DownloadQueue(metaclass=Singleton): folder = str(folder) if folder else "" filePath = calc_download_path(base_path=self.config.download_path, folder=folder) + yt_conf = {} + cookie_file = os.path.join(self.config.temp_path, f"c_{uuid.uuid4().hex}.txt") LOG.info( - f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {cookies}' 'YTConfig: {config}'." + f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {len(cookies)}/chars' 'YTConfig: {config}'." ) if isinstance(config, str): @@ -384,19 +388,33 @@ class DownloadQueue(metaclass=Singleton): started = time.perf_counter() LOG.debug(f"extract_info: checking {url=}") + logs = [] + + yt_conf = { + "callback": { + "func": lambda _, msg: logs.append(msg), + "level": logging.WARNING, + }, + **merge_config(self.config.ytdl_options, config), + } + + if cookies: + try: + async with await anyio.open_file(cookie_file, "w") as f: + await f.write(cookies) + yt_conf["cookiefile"] = f.name + except ValueError as e: + LOG.error(f"Failed to create cookie file for '{self.info.id}: {self.info.title}'. '{e!s}'.") + entry = await asyncio.wait_for( fut=asyncio.get_running_loop().run_in_executor( - None, - extract_info, - get_opts(preset, merge_config(self.config.ytdl_options, config)), - url, - bool(self.config.ytdl_debug), + None, extract_info, get_opts(preset, yt_conf), url, bool(self.config.ytdl_debug) ), timeout=self.config.extract_info_timeout, ) if not entry: - return {"status": "error", "msg": "Unable to extract info check logs."} + return {"status": "error", "msg": "Unable to extract info." + "\n".join(logs)} LOG.debug( f"extract_info: for 'URL: {url}' is done in '{time.perf_counter() - started}'. Length: '{len(entry)}'." @@ -413,6 +431,13 @@ class DownloadQueue(metaclass=Singleton): "status": "error", "msg": f"TimeoutError: {self.config.extract_info_timeout}s reached Unable to extract info.", } + finally: + if cookie_file and os.path.exists(cookie_file): + try: + os.remove(yt_conf["cookiefile"]) + del yt_conf["cookiefile"] + except Exception as e: + LOG.error(f"Failed to remove cookie file '{yt_conf['cookiefile']}'. {e!s}") return await self.__add_entry( entry=entry, diff --git a/app/library/Tasks.py b/app/library/Tasks.py index 35b52ddc..e8c56555 100644 --- a/app/library/Tasks.py +++ b/app/library/Tasks.py @@ -17,7 +17,7 @@ from .encoder import Encoder from .EventsSubscriber import Event, Events, EventsSubscriber from .Singleton import Singleton -LOG = logging.getLogger("notifications") +LOG = logging.getLogger("tasks") @dataclass(kw_only=True) diff --git a/ui/components/NewDownload.vue b/ui/components/NewDownload.vue index eb99257b..885989c5 100644 --- a/ui/components/NewDownload.vue +++ b/ui/components/NewDownload.vue @@ -100,7 +100,7 @@