From a0fef50248e9bab12b1955626cc594d9bddd5884 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Sat, 14 Feb 2026 18:49:52 +0300 Subject: [PATCH 1/2] fix: some times adding a link fails with UnboundLocalError --- app/library/downloads/item_adder.py | 1 + ui/app/utils/embedable.ts | 27 ++++++++++++++++++--------- ui/app/utils/index.ts | 8 ++------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/app/library/downloads/item_adder.py b/app/library/downloads/item_adder.py index 8cccd30e..7ebdb967 100644 --- a/app/library/downloads/item_adder.py +++ b/app/library/downloads/item_adder.py @@ -85,6 +85,7 @@ async def add( """ _preset: Preset | None = Presets.get_instance().get(item.preset) + logs = [] if item.has_cli(): try: diff --git a/ui/app/utils/embedable.ts b/ui/app/utils/embedable.ts index d406349c..f97f31f2 100644 --- a/ui/app/utils/embedable.ts +++ b/ui/app/utils/embedable.ts @@ -75,22 +75,31 @@ const sources: EmbedSource[] = [ url: "https://drive.google.com/file/d/{id}/preview", regex: /https?:\/\/(?:www\.)?drive\.google\.com\/file\/d\/(?[^/?#&]+)/, }, + { + name: "fbc_sites", + url: "{domain}/e/{id}", + regex: /(?(.+?))\/(?:api\/tokens|f)\/(?fbc_[A-Za-z0-9_-]{22})\/?/, + }, ] const isEmbedable = (url: string): boolean => sources.some(source => source.regex.test(url)) const getEmbedable = (url: string): string | null => { - const source = sources.find(source => source.regex.test(url)) - if (!source) { - return null + for (const source of sources) { + const match = source.regex.exec(url) + if (!match?.groups) { + continue + } + + const replacements: Record = { + ...match.groups, + origin: window.location.origin, + } + + return source.url.replace(/\{(\w+)\}/g, (_, key) => replacements[key] ?? `{${key}}`) } - const match = source.regex.exec(url) - if (!match || !match.groups?.id) { - return null - } - - return source.url.replace(/\{origin\}/g, window.location.origin).replace(/\{id\}/g, match.groups.id) + return null } export { isEmbedable, getEmbedable } diff --git a/ui/app/utils/index.ts b/ui/app/utils/index.ts index dc08e6fa..59d93393 100644 --- a/ui/app/utils/index.ts +++ b/ui/app/utils/index.ts @@ -213,11 +213,7 @@ const encodePath = (item: string): string => { processed = encodeURIComponent(processed) const placeholderRegex = new RegExp(`${_PREFIX.replace(/_/g, '_')}(\\d+)${_SUFFIX.replace(/_/g, '_')}`, 'g') - processed = processed.replace(placeholderRegex, (_match, index: string) => { - return placeholders[parseInt(index)] || '' - }) - - return processed + return processed.replace(placeholderRegex, (_match, index: string) => placeholders[parseInt(index)] || '') }).join('/') } @@ -255,7 +251,7 @@ const request = (url: string, options: RequestInit & { timeout?: number } = {}): if (typeof timeout === 'number' && timeout > 0) { controller = new AbortController() fetchOptions.signal = controller.signal - timer = setTimeout(() => controller!.abort(`Request timed out.`), timeout*1000) + timer = setTimeout(() => controller!.abort(`Request timed out.`), timeout * 1000) } return fetch(url.startsWith('/') ? uri(url) : url, fetchOptions).finally(() => { From 84077349c74e0476fb60b0e44bd52ee30252c1cb Mon Sep 17 00:00:00 2001 From: arabcoders Date: Sat, 14 Feb 2026 20:05:08 +0300 Subject: [PATCH 2/2] feat: improve status tracking in downloads --- app/features/ytdlp/ytdlp.py | 12 +++++++++++- app/library/downloads/status_tracker.py | 10 +++++++++- app/yt_dlp_plugins/postprocessor/nfo_maker.py | 4 ++++ ui/app/components/Queue.vue | 6 +++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/features/ytdlp/ytdlp.py b/app/features/ytdlp/ytdlp.py index 720c0054..1a1f0a84 100644 --- a/app/features/ytdlp/ytdlp.py +++ b/app/features/ytdlp/ytdlp.py @@ -1,4 +1,4 @@ -# flake8: noqa: F401 +# flake8: noqa: F401, RUF100, W291, I001 import sys from typing import Any @@ -49,6 +49,7 @@ class _ArchiveProxy: class YTDLP(yt_dlp.YoutubeDL): _interrupted = False + _registered = False def __init__(self, params=None, auto_init=True): # Avoid yt-dlp preloading the archive file by stripping the param first @@ -73,6 +74,15 @@ class YTDLP(yt_dlp.YoutubeDL): pass self.archive = _ArchiveProxy(orig_file) + if not YTDLP._registered: + try: + from app.yt_dlp_plugins.postprocessor.nfo_maker import NFOMakerPP + from yt_dlp.postprocessor import postprocessors + + postprocessors.value.update({"NFOMakerPP": NFOMakerPP}) + YTDLP._registered = True + except Exception: + pass def _delete_downloaded_files(self, *args, **kwargs) -> None: if self._interrupted: diff --git a/app/library/downloads/status_tracker.py b/app/library/downloads/status_tracker.py index 3a9c406e..edd248d8 100644 --- a/app/library/downloads/status_tracker.py +++ b/app/library/downloads/status_tracker.py @@ -66,9 +66,17 @@ class StatusTracker: """ self.info.datetime = str(formatdate(time.time())) - self.info.filename = safe_relative_path(filepath, Path(self.download_dir), self.temp_path) + self.info.filename = safe_relative_path(filepath, Path(self.download_dir)) self.final_update = True self.logger.debug(f"Final file name: '{filepath}'.") + try: + filepath.relative_to(self.download_dir) + except ValueError: + self.logger.warning( + f"Final file '{filepath}' is outside of the intended download directory '{self.download_dir}'." + ) + self.info.filename = None + return if filepath.is_file() and filepath.exists(): try: diff --git a/app/yt_dlp_plugins/postprocessor/nfo_maker.py b/app/yt_dlp_plugins/postprocessor/nfo_maker.py index 9a341294..9097e101 100644 --- a/app/yt_dlp_plugins/postprocessor/nfo_maker.py +++ b/app/yt_dlp_plugins/postprocessor/nfo_maker.py @@ -120,6 +120,10 @@ class NFOMakerPP(PostProcessor): return "NFOMaker" def run(self, info: dict | None = None) -> tuple[list, dict]: + if "fail" == self.mode: + msg = "Intentionally failing due to mode=fail." + raise Exception(msg) + if not info: self.report_warning("No info provided to NFO Maker.") return [], {} diff --git a/ui/app/components/Queue.vue b/ui/app/components/Queue.vue index 57db52c9..4166a08c 100644 --- a/ui/app/components/Queue.vue +++ b/ui/app/components/Queue.vue @@ -121,7 +121,7 @@
-
{{ updateProgress(item) }}
+
@@ -247,7 +247,7 @@
-
{{ updateProgress(item) }}
+
@@ -600,7 +600,7 @@ const updateProgress = (item: StoreItem): string => { if ('postprocessing' === item.status) { if (item.postprocessor) { - return `PP Running: ${item.postprocessor}` + return ` PP: ${item.postprocessor}` } return 'Post-processors are running.' }