From fef60f03954066ff825f4c5c2889a7a61a782f8f Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Fri, 17 Jan 2025 23:44:27 +0300 Subject: [PATCH 1/4] wrap file access into exception handler. --- app/library/Download.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/app/library/Download.py b/app/library/Download.py index 2877f219..8d3ae989 100644 --- a/app/library/Download.py +++ b/app/library/Download.py @@ -340,7 +340,11 @@ class Download: self.info.filename = os.path.relpath(status.get("filename"), self.download_dir) if os.path.exists(status.get("filename")): - self.info.file_size = os.path.getsize(status.get("filename")) + try: + self.info.file_size = os.path.getsize(status.get("filename")) + except FileNotFoundError: + self.info.file_size = 0 + pass self.info.status = status.get("status", self.info.status) self.info.msg = status.get("msg") @@ -360,22 +364,16 @@ class Download: self.info.speed = status.get("speed") self.info.eta = status.get("eta") - if self.info.status == "finished" and "filename" in status: + if self.info.status == "finished" and "filename" in status and os.path.exists(status.get("filename")): try: self.info.file_size = os.path.getsize(status.get("filename")) - except FileNotFoundError: - LOG.warning(f'File not found: {status.get("filename")}') - self.info.file_size = None - pass - - try: ff = await ffprobe(status.get("filename")) - self.info.extras['is_video'] = ff.has_video() - self.info.extras['is_audio'] = ff.has_audio() + self.info.extras["is_video"] = ff.has_video() + self.info.extras["is_audio"] = ff.has_audio() self.info.datetime = str(formatdate(time.time())) - except Exception as e: - self.info.extras['is_video'] = True - self.info.extras['is_audio'] = True + except (FileNotFoundError, Exception) as e: + self.info.extras["is_video"] = True + self.info.extras["is_audio"] = True LOG.exception(f"Failed to ffprobe: {status.get('filename')}. {e}") asyncio.create_task(self.emitter.updated(dl=self.info), name=f"emitter-u-{self.id}") From 1319c3e1abe65fec2883e10da51acd48e2a95b59 Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Sat, 18 Jan 2025 17:47:03 +0300 Subject: [PATCH 2/4] ignore /api/ping access log --- app/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index 5325f3f7..c9403686 100644 --- a/app/main.py +++ b/app/main.py @@ -150,7 +150,7 @@ class Main: LOG.info("=" * 40) if self.config.access_log: - http_logger.addFilter(lambda record: "GET /ping" not in record.getMessage()) + http_logger.addFilter(lambda record: "GET /api/ping" not in record.getMessage()) web.run_app( self.app, From 44440aa546d60822c504ee5ba466f80964335f9a Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Sat, 18 Jan 2025 17:47:33 +0300 Subject: [PATCH 3/4] prevent loading keys which sometimes breaks ytptube --- app/library/Utils.py | 15 +++++---------- app/library/config.py | 13 ++++++++++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/library/Utils.py b/app/library/Utils.py index 68c6e27a..84ccbde8 100644 --- a/app/library/Utils.py +++ b/app/library/Utils.py @@ -22,6 +22,8 @@ IGNORED_KEYS: tuple[str] = ( "outtmpl", "progress_hooks", "postprocessor_hooks", + "format", + "download_archive", ) YTDLP_INFO_CLS: yt_dlp.YoutubeDL = None OS_ALT_SEP: list[str] = list(sep for sep in [os.sep, os.path.altsep] if sep is not None and sep != "/") @@ -77,6 +79,7 @@ def get_opts(preset: str, ytdl_opts: dict) -> dict: LOG.debug(f"Using preset '{preset}', altered options: {opts}") return opts + def getVideoInfo(url: str, ytdlp_opts: dict = None, no_archive: bool = True) -> Any | dict[str, Any] | None: """ Extracts video information from the given URL. @@ -187,17 +190,9 @@ def mergeConfig(config: dict, new_config: dict) -> dict: Returns: dict: Merged config """ - - ignored_keys: tuple = ( - "cookiefile", - "download_archive" "paths", - "outtmpl", - "progress_hooks", - "postprocessor_hooks", - ) - - for key in ignored_keys: + for key in IGNORED_KEYS: if key in new_config: + LOG.error(f"Key '{key}' is not allowed to be manually set.") del new_config[key] conf = mergeDict(new_config, config) diff --git a/app/library/config.py b/app/library/config.py index 070394ed..d2d3709b 100644 --- a/app/library/config.py +++ b/app/library/config.py @@ -10,7 +10,7 @@ import coloredlogs from dotenv import load_dotenv from yt_dlp.version import __version__ as YTDLP_VERSION -from .Utils import load_file +from .Utils import load_file, mergeDict, IGNORED_KEYS from .version import APP_VERSION @@ -218,15 +218,22 @@ class Config: LOG.error(f"Error starting debugpy server at '0.0.0.0:{self.debugpy_port}'. {e}") optsFile: str = os.path.join(self.config_path, "ytdlp.json") - if os.path.exists(optsFile) and os.path.getsize(optsFile) > 4: + if os.path.exists(optsFile) and os.path.getsize(optsFile) > 5: LOG.info(f"Loading yt-dlp custom options from '{optsFile}'.") (opts, status, error) = load_file(optsFile, dict) if not status: LOG.error(f"Could not load yt-dlp custom options from '{optsFile}'. {error}") sys.exit(1) + if isinstance(opts, dict): + for key in IGNORED_KEYS: + if key in opts: + LOG.error(f"Key '{key}' is not allowed to be loaded via 'ytdlp.json' file.") + del opts[key] - self.ytdl_options.update(opts) + self.ytdl_options = mergeDict(self.ytdl_options, opts) + else: + LOG.error(f"Invalid yt-dlp custom options file '{optsFile}'.") else: LOG.info(f"No yt-dlp custom options found at '{optsFile}'.") From 2fddadf363312404303fb06c837cf2633ecae99c Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Sat, 18 Jan 2025 17:47:55 +0300 Subject: [PATCH 4/4] Potential fix for #173 --- app/library/Download.py | 7 +++++-- app/library/DownloadQueue.py | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/library/Download.py b/app/library/Download.py index 8d3ae989..8786e95d 100644 --- a/app/library/Download.py +++ b/app/library/Download.py @@ -317,8 +317,11 @@ class Download: except asyncio.CancelledError: LOG.debug(f"Closing progress update for: {self.info._id=}.") return - - status = await self.update_task + try: + status = await self.update_task + except Exception as e: + LOG.error(f"Failed to get status update for: {self.info._id=}. {e}") + pass if status is None or status.__class__ is Terminator: LOG.debug(f"Closing progress update for: {self.info._id=}.") diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index d34d50fe..323aec9e 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -230,6 +230,7 @@ class DownloadQueue: already=None, ): ytdlp_config = ytdlp_config if ytdlp_config else {} + folder = str(folder) LOG.info( f"Adding url '{url}' to folder '{folder}' with the following options 'Preset: {preset}' 'Naming: {output_template}', 'Cookies: {ytdlp_cookies}' 'YTConfig: {ytdlp_config}'."