diff --git a/.vscode/settings.json b/.vscode/settings.json index 63b8efe4..2346790f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -82,6 +82,7 @@ "rejecttitle", "remux", "rtime", + "SIGUSR", "smhd", "socketio", "timespec", diff --git a/app/library/Download.py b/app/library/Download.py index e1640e28..fb3f044e 100644 --- a/app/library/Download.py +++ b/app/library/Download.py @@ -261,7 +261,7 @@ class Download: if isinstance(self.info_dict, dict) and len(self.info_dict.get("formats", [])) < 1: msg = f"Failed to extract any formats for '{self.info.url}'." if filtered_logs := extract_ytdlp_logs(self.logs): - msg += f" Logs: {', '.join(filtered_logs)}" + msg += " " + ", ".join(filtered_logs) raise ValueError(msg) # noqa: TRY301 @@ -280,9 +280,9 @@ class Download: def mark_cancelled(*_): cls._interrupted = True cls.to_screen("[info] Interrupt received, exiting cleanly...") - raise KeyboardInterrupt # noqa: TRY301 + raise SystemExit(130) # noqa: TRY301 - signal.signal(signal.SIGINT, mark_cancelled) + signal.signal(signal.SIGUSR1, mark_cancelled) if isinstance(self.info_dict, dict) and len(self.info_dict) > 1: self.logger.debug(f"Downloading '{self.info.url}' using pre-info.") @@ -313,7 +313,9 @@ class Download: except Exception as e: self.logger.error(f"Failed to delete cookie file: {cookie_file}. {e}") - self.logger.info(f'Task id="{self.info.id}" PID="{os.getpid()}" title="{self.info.title}" completed.') + self.logger.info( + f'Task id="{self.info.id}" PID="{os.getpid()}" title="{self.info.title}" preset="{self.preset}" cookies="{bool(params.get("cookiefile"))}" completed.' + ) async def start(self): self.status_queue = Config.get_manager().Queue() diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index f883d1b7..086dbcd1 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -317,8 +317,7 @@ class DownloadQueue(metaclass=Singleton): _status, _msg = ytdlp_reject(entry=etr, yt_params=yt_params) if not _status: - LOG.debug(_msg) - return {"status": "ok", "msg": _msg} + return {"status": "error", "msg": _msg} extras = { "playlist": entry.get("title") or entry.get("id"), @@ -366,7 +365,7 @@ class DownloadQueue(metaclass=Singleton): if any("error" == res["status"] for res in results): return { "status": "error", - "msg": ", ".join(res["msg"] for res in results if res["status"] == "error" and "msg" in res), + "msg": ", ".join(res["msg"] for res in results if "error" == res["status"] and "msg" in res), } return {"status": "ok"} @@ -470,7 +469,7 @@ class DownloadQueue(metaclass=Singleton): text_logs: str = "" if filtered_logs := extract_ytdlp_logs(logs): - text_logs = ", ".join(filtered_logs) + text_logs = " " + ", ".join(filtered_logs) if "is_upcoming" == entry.get("live_status"): nEvent = Events.ITEM_MOVED @@ -690,13 +689,13 @@ class DownloadQueue(metaclass=Singleton): if not item.requeued and (condition := Conditions.get_instance().match(info=entry)): already.pop() - LOG.info(f"Condition '{condition.name}' matched for '{item.url}'.") + LOG.info(f"Matched '{condition.name}' for '{item.url}' Adding '{condition.cli}' to request.") return await self.add(item=item.new_with(requeued=True, cli=condition.cli), already=already) _status, _msg = ytdlp_reject(entry=entry, yt_params=yt_conf) if not _status: LOG.debug(_msg) - return {"status": "ok", "msg": _msg} + return {"status": "error", "msg": _msg} end_time = time.perf_counter() - started LOG.debug(f"extract_info: for 'URL: {item.url}' is done in '{end_time:.3f}'. Length: '{len(entry)}/keys'.") @@ -1028,23 +1027,22 @@ class DownloadQueue(metaclass=Singleton): """ Monitor pool for stale downloads and cancel them if needed. """ - if self.is_paused(): + if self.is_paused() or self.queue.empty(): return - if not self.queue.empty(): - LOG.debug("Checking for stale items in the download queue.") - for _id, item in list(self.queue.items()): - item_ref = f"{_id=} {item.info.id=} {item.info.title=}" - if not item.is_stale(): - LOG.debug(f"Item '{item_ref}' is not stale.") - continue + LOG.debug("Checking for stale items in the download queue.") + for _id, item in list(self.queue.items()): + item_ref = f"{_id=} {item.info.id=} {item.info.title=}" + if not item.is_stale(): + LOG.debug(f"Item '{item_ref}' is not stale.") + continue + try: LOG.warning(f"Cancelling staled item '{item_ref}' from download queue.") - try: - await self.cancel([_id]) - except Exception as e: - LOG.error(f"Failed to cancel staled item '{item_ref}'. {e!s}") - LOG.exception(e) + await self.cancel([_id]) + except Exception as e: + LOG.error(f"Failed to cancel staled item '{item_ref}'. {e!s}") + LOG.exception(e) async def _check_live(self): """