From f6c7d8233b5c62f307cb911e6d74582bd796f030 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Sun, 20 Apr 2025 20:07:18 +0300 Subject: [PATCH 1/5] restore message about live stream not being live yet. --- app/library/DownloadQueue.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index 8ee069a6..0f06e3eb 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -313,12 +313,10 @@ class DownloadQueue(metaclass=Singleton): dlInfo: Download = Download(info=dl, info_dict=entry) if dlInfo.info.live_in or "is_upcoming" == entry.get("live_status"): - dlInfo.info.status = "not_live" - itemDownload = self.done.put(dlInfo) NotifyEvent = Events.COMPLETED - log_message = f"{dl.title or dl.id or dl._id}: stream is not live yet." - if dlInfo.info.live_in: - log_message += f" Will start in {dlInfo.info.live_in}." + dlInfo.info.status = "not_live" + dlInfo.info.msg = "Stream is not live yet." + itemDownload = self.done.put(dlInfo) elif len(entry.get("formats", [])) < 1: availability = entry.get("availability", "public") msg = "No formats found." From 5172742e968da924b83fdb8bbeca08d65cdd4487 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Mon, 21 Apr 2025 17:40:36 +0300 Subject: [PATCH 2/5] Only display availability when it's set --- app/library/DownloadQueue.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index 0f06e3eb..22abe93b 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -18,7 +18,7 @@ from .AsyncPool import AsyncPool from .config import Config from .DataStore import DataStore from .Download import Download -from .Events import EventBus, Events, info +from .Events import EventBus, Events from .ItemDTO import Item, ItemDTO from .Presets import Presets from .Scheduler import Scheduler @@ -320,7 +320,7 @@ class DownloadQueue(metaclass=Singleton): elif len(entry.get("formats", [])) < 1: availability = entry.get("availability", "public") msg = "No formats found." - if "public" != availability: + if availability and availability not in ("public",): msg += f" Availability is set for '{availability}'." dlInfo.info.status = "error" From 9ba7b3480303ff3501c8e6241caac9dc4be65a32 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Mon, 21 Apr 2025 18:21:29 +0300 Subject: [PATCH 3/5] Add more events --- app/library/DownloadQueue.py | 2 ++ app/library/Events.py | 19 +++++++++++++++++++ app/library/Notifications.py | 2 ++ ui/stores/SocketStore.js | 10 ++++++++++ 4 files changed, 33 insertions(+) diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index 22abe93b..a04e4f5a 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -19,6 +19,7 @@ from .config import Config from .DataStore import DataStore from .Download import Download from .Events import EventBus, Events +from .Events import warning as event_warning from .ItemDTO import Item, ItemDTO from .Presets import Presets from .Scheduler import Scheduler @@ -327,6 +328,7 @@ class DownloadQueue(metaclass=Singleton): dlInfo.info.error = msg itemDownload = self.done.put(dlInfo) NotifyEvent = Events.COMPLETED + await self._notify.emit(Events.LOG_WARNING, data=event_warning(msg)) elif self.config.allow_manifestless is False and is_manifestless is True: dlInfo.info.status = "error" dlInfo.info.error = "Video is in post-live manifestless mode." diff --git a/app/library/Events.py b/app/library/Events.py index f3885347..c73ad6e9 100644 --- a/app/library/Events.py +++ b/app/library/Events.py @@ -25,6 +25,21 @@ def error(msg: str, data: dict | None = None) -> dict: return message("error", msg, data) +def warning(msg: str, data: dict | None = None) -> dict: + """ + Create an error message. + + Args: + msg (str): The message. + data (dict|None): The data to include in the message. + + Returns: + dict : The message wrapped in a dictionary. + + """ + return message("warning", msg, data) + + def info(msg: str, data: dict | None = None) -> dict: """ Create an info message. @@ -87,6 +102,8 @@ class Events: CLEARED = "cleared" ERROR = "error" LOG_INFO = "log_info" + LOG_WARNING = "log_warning" + LOG_ERROR = "log_error" LOG_SUCCESS = "log_success" INITIAL_DATA = "initial_data" @@ -139,6 +156,8 @@ class Events: Events.ADDED, Events.ERROR, Events.LOG_INFO, + Events.LOG_WARNING, + Events.LOG_ERROR, Events.LOG_SUCCESS, Events.COMPLETED, Events.CANCELLED, diff --git a/app/library/Notifications.py b/app/library/Notifications.py index cdfb27d3..e25a82ff 100644 --- a/app/library/Notifications.py +++ b/app/library/Notifications.py @@ -96,6 +96,8 @@ class NotificationEvents: CLEARED = Events.CLEARED LOG_INFO = Events.LOG_INFO LOG_SUCCESS = Events.LOG_SUCCESS + LOG_WARNING = Events.LOG_WARNING + LOG_ERROR = Events.LOG_ERROR TEST = Events.TEST @staticmethod diff --git a/ui/stores/SocketStore.js b/ui/stores/SocketStore.js index dfba3d5e..4b83f2b2 100644 --- a/ui/stores/SocketStore.js +++ b/ui/stores/SocketStore.js @@ -52,6 +52,16 @@ export const useSocketStore = defineStore('socket', () => { toast.success(json?.message); }); + socket.value.on('log_warning', stream => { + const json = JSON.parse(stream); + toast.warning(json?.message); + }); + + socket.value.on('log_error', stream => { + const json = JSON.parse(stream); + toast.error(json?.message); + }); + socket.value.on('completed', stream => { const item = JSON.parse(stream); From 62703f3cb748cfcae0ba1297d793a491a7254b19 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Mon, 21 Apr 2025 18:40:00 +0300 Subject: [PATCH 4/5] add event warning about adding url saved to archive --- app/library/DownloadQueue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index a04e4f5a..b768e5b9 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -416,6 +416,7 @@ class DownloadQueue(metaclass=Singleton): if downloaded is True and id_dict: message = f"This url with ID '{id_dict.get('id')}' has been downloaded already and recorded in archive." LOG.info(message) + await self._notify.emit(Events.LOG_WARNING, data=event_warning(message)) return {"status": "error", "msg": message} started = time.perf_counter() From cdcb5d61be084824a01947426629af27fcc5f787 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Mon, 21 Apr 2025 20:53:45 +0300 Subject: [PATCH 5/5] update README --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 1ede081a..fc138d6f 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,17 @@ inside the `/config` directory named `yt-dlp` so, the path will be `/config/yt-d Once you have installed the plugins, restart the container and the plugins will be auto-loaded on demand. +# How to load random backgrounds from WatchState or any other source? + +YTPTube can be configured to pull random background images from different sources, including `WatchState` which is another +project of mine, simply change the `YTP_PICTURES_BACKENDS` environment variable to the following url + +```env +YTP_PICTURES_BACKENDS=https://watchstate.ip/v1/api/system/images/background?apikey=[api_key] +``` + +Where `[api_key]` is the api key you get from your WatchState instance. + # The origin of the project. The project first started as a fork [meTube](https://github.com/alexta69/metube), since then it has been completely