From 438254c594e48c460274cac0f04a73d9d0743ff1 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Fri, 25 Jul 2025 17:37:52 +0300 Subject: [PATCH 01/13] Added task to kill debugpy, sometimes vscode leave it behind causing problems during development --- .vscode/launch.json | 19 +++++++++---------- .vscode/tasks.json | 22 ++++++++++++++++++++++ app/main.py | 1 - 3 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json index a0cd2cce..14415dad 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,4 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { @@ -18,17 +15,17 @@ "cwd": "${workspaceFolder}/ui", "env": { "NUXT_API_URL": "http://localhost:8081/api/", - "NUXT_PUBLIC_WSS": ":8081/", + "NUXT_PUBLIC_WSS": ":8081/" }, "console": "internalConsole", - "outputCapture": "std", + "outputCapture": "std" }, { - "name": "Python: main.py", + "name": "Python: main.py ", "type": "debugpy", "request": "launch", "program": "app/main.py", - "console": "internalConsole", + "console": "integratedTerminal", "justMyCode": true, "env": { "YTP_CONFIG_PATH": "${workspaceFolder}/var/config", @@ -36,7 +33,9 @@ "YTP_TEMP_PATH": "${workspaceFolder}/var/tmp", "PYDEVD_DISABLE_FILE_VALIDATION": "1", "YTP_IGNORE_UI": "true" - } + }, + "subProcess": true, + "postDebugTask": "kill-debugpy" }, { "name": "Node: Generate UI", @@ -65,14 +64,14 @@ "YTP_CONFIG_PATH": "${workspaceFolder}/var/config", "YTP_DOWNLOAD_PATH": "${workspaceFolder}/var/downloads", "YTP_TEMP_PATH": "${workspaceFolder}/var/tmp", - "YTP_LOG_LEVEL": "DEBUG", + "YTP_LOG_LEVEL": "DEBUG" } }, { "name": "Python: Attach To Process", "type": "debugpy", "request": "attach", - "processId": "${command:pickProcess}", + "processId": "${command:pickProcess}" }, { "name": "Python: Attach To Container", diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..ee6cc98f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,22 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "kill-debugpy", + "type": "shell", + "command": "pkill -f debugpy || true", + "problemMatcher": [], + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "dedicated", + "showReuseMessage": false, + "clear": false + }, + "runOptions": { + "runOn": "folderOpen" + } + } + ] +} diff --git a/app/main.py b/app/main.py index bcda05d8..549ace11 100644 --- a/app/main.py +++ b/app/main.py @@ -171,7 +171,6 @@ class Main: self._app, host=host, port=port, - reuse_port="win32" != sys.platform, loop=asyncio.get_event_loop(), access_log=HTTP_LOGGER, print=started, From 4e1a1e65ed88fd6898495c135d516c5592971af2 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Fri, 25 Jul 2025 18:38:04 +0300 Subject: [PATCH 02/13] Add loading screen --- ui/app/spa-loading-template.html | 126 +++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 ui/app/spa-loading-template.html diff --git a/ui/app/spa-loading-template.html b/ui/app/spa-loading-template.html new file mode 100644 index 00000000..9dc389a7 --- /dev/null +++ b/ui/app/spa-loading-template.html @@ -0,0 +1,126 @@ + + + + + + YTPTube Loading... + + + + + + From dcaeb7acc8ae8b68a15e07cc5825e80c9a960c1e Mon Sep 17 00:00:00 2001 From: arabcoders Date: Fri, 25 Jul 2025 19:41:17 +0300 Subject: [PATCH 03/13] migrated more code to ts --- ui/app/components/NotificationForm.vue | 90 +++++++++-------- ui/app/components/NotifyDropdown.vue | 102 +++++++++---------- ui/app/components/PresetForm.vue | 129 +++++++++---------------- ui/app/components/TaskForm.vue | 129 +++++++++---------------- ui/app/components/VideoPlayer.vue | 7 +- ui/app/types/notification.d.ts | 26 +++++ ui/app/types/presets.d.ts | 17 ++++ ui/app/types/store.d.ts | 5 + ui/app/utils/index.ts | 7 +- 9 files changed, 249 insertions(+), 263 deletions(-) create mode 100644 ui/app/types/notification.d.ts create mode 100644 ui/app/types/presets.d.ts diff --git a/ui/app/components/NotificationForm.vue b/ui/app/components/NotificationForm.vue index efb46dcb..985cb5fc 100644 --- a/ui/app/components/NotificationForm.vue +++ b/ui/app/components/NotificationForm.vue @@ -198,7 +198,7 @@
- - - diff --git a/ui/app/components/PresetForm.vue b/ui/app/components/PresetForm.vue index c38a2a61..6c79e07c 100644 --- a/ui/app/components/PresetForm.vue +++ b/ui/app/components/PresetForm.vue @@ -230,102 +230,74 @@ - diff --git a/ui/app/pages/tasks.vue b/ui/app/pages/tasks.vue index b43d1598..74b9e910 100644 --- a/ui/app/pages/tasks.vue +++ b/ui/app/pages/tasks.vue @@ -1,13 +1,3 @@ - - - diff --git a/ui/app/pages/logs.vue b/ui/app/pages/logs.vue index c983aac1..3950f042 100644 --- a/ui/app/pages/logs.vue +++ b/ui/app/pages/logs.vue @@ -172,7 +172,7 @@ watch(() => config.app.file_logging, async v => { const filteredItems = computed(() => { const raw = query.value.trim().toLowerCase() const contextMatch = raw.match(/context:(\d+)/) - const context = contextMatch ? parseInt(contextMatch[1], 10) : 0 + const context = contextMatch ? parseInt(String(contextMatch[1]), 10) : 0 const searchTerm = raw.replace(/context:\d+/, '').trim() if (!searchTerm) { @@ -191,7 +191,7 @@ const filteredItems = computed(() => { }) Array.from(matchedIndexes).sort((a: any, b: any) => a - b).forEach((index: any) => { - result.push(logs.value[index]) + result.push(logs.value[index] as log_line) }) return result @@ -276,21 +276,20 @@ const scrollToBottom = (fast = false) => { }) } +const log_handler = (data: log_line) => { + logs.value.push(data) + + nextTick(() => { + if (autoScroll.value && bottomMarker.value) { + bottomMarker.value.scrollIntoView({ behavior: 'smooth' }) + } + }) +} + onMounted(async () => { await fetchLogs() + socket.on('log_lines', log_handler) socket.emit('subscribe', 'log_lines') - - socket.on('log_lines', (data: any) => { - logs.value.push(data) - - nextTick(() => { - if (autoScroll.value && bottomMarker.value) { - bottomMarker.value.scrollIntoView({ behavior: 'smooth' }) - } - }) - - }) - if (bg_enable.value) { document.querySelector('body')?.setAttribute("style", `opacity: 1.0`) } @@ -298,7 +297,7 @@ onMounted(async () => { onBeforeUnmount(() => { socket.emit('unsubscribe', 'log_lines') - socket.off('log_lines') + socket.off('log_lines', log_handler) if (bg_enable.value) { document.querySelector('body')?.setAttribute("style", `opacity: ${bg_opacity.value}`) } @@ -306,7 +305,7 @@ onBeforeUnmount(() => { onBeforeUnmount(() => { socket.emit('unsubscribe', 'log_lines') - socket.off('log_lines') + socket.off('log_lines', log_handler) if (scrollTimeout) clearTimeout(scrollTimeout) }) diff --git a/ui/app/stores/SocketStore.ts b/ui/app/stores/SocketStore.ts index 779a52f1..da7a668f 100644 --- a/ui/app/stores/SocketStore.ts +++ b/ui/app/stores/SocketStore.ts @@ -20,7 +20,7 @@ export const useSocketStore = defineStore('socket', () => { event.forEach(e => socket.value?.on(e, (...args) => true === withEvent ? callback(e, ...args) : callback(...args))) } - const off = (event: string | string[], callback: (...args: any[]) => void): any => { + const off = (event: string | string[], callback?: (...args: any[]) => void): any => { if (!Array.isArray(event)) { event = [event] } diff --git a/ui/app/types/filebrowser.d.ts b/ui/app/types/filebrowser.d.ts new file mode 100644 index 00000000..3bd6db03 --- /dev/null +++ b/ui/app/types/filebrowser.d.ts @@ -0,0 +1,20 @@ +type FileItem = { + type: 'file' | 'dir' | 'link' + content_type: 'image' | 'video' | 'text' | 'subtitle' | 'metadata' | 'dir' | string + name: string + path: string + size: number + mime: string + mtime: string + ctime: string + is_dir: boolean + is_file: boolean + is_symlink: boolean +} + +type FileBrowserResponse = { + path: string + contents: FileItem[] +} + +export type { FileItem, FileBrowserResponse } From 964a24cdd594f1d57b78792cc63e40ed630fa1b0 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Sat, 26 Jul 2025 21:14:53 +0300 Subject: [PATCH 11/13] completed the ts migration --- app/library/Utils.py | 16 +- app/routes/api/browser.py | 1 + ui/app/components/History.vue | 272 +++++++++++++++------------------- ui/app/components/Queue.vue | 196 ++++++++++-------------- ui/app/types/store.d.ts | 10 +- 5 files changed, 217 insertions(+), 278 deletions(-) diff --git a/app/library/Utils.py b/app/library/Utils.py index dd70aff9..e1e949ba 100644 --- a/app/library/Utils.py +++ b/app/library/Utils.py @@ -373,14 +373,18 @@ def check_id(file: Path) -> bool | str: id = match.groupdict().get("id") - for f in file.parent.iterdir(): - if id not in f.stem: - continue + try: + for f in file.parent.iterdir(): + if id not in f.stem: + continue - if f.suffix != file.suffix: - continue + if f.suffix != file.suffix: + continue - return f.absolute() + return f.absolute() + except OSError as e: + LOG.error(f"Error checking file '{file}': {e!s}") + return False return False diff --git a/app/routes/api/browser.py b/app/routes/api/browser.py index e6c78fa8..1d09876a 100644 --- a/app/routes/api/browser.py +++ b/app/routes/api/browser.py @@ -324,6 +324,7 @@ async def prepare_zip_file(request: Request, config: Config, cache: Cache): for f in json: if not isinstance(f, str): continue + ref, status = get_file(download_path=config.download_path, file=f) if status == web.HTTPNotFound.status_code: continue diff --git a/ui/app/components/History.vue b/ui/app/components/History.vue index 5a394551..aa833526 100644 --- a/ui/app/components/History.vue +++ b/ui/app/components/History.vue @@ -161,7 +161,7 @@
@@ -188,7 +188,8 @@ - - diff --git a/ui/app/components/Queue.vue b/ui/app/components/Queue.vue index 26b44fbb..53ad7830 100644 --- a/ui/app/components/Queue.vue +++ b/ui/app/components/Queue.vue @@ -108,7 +108,7 @@
{{ updateProgress(item) }}
-
+
@@ -119,7 +119,8 @@