From 4a8777faf7d5e170afaf68cdcbd9b94728d85bc4 Mon Sep 17 00:00:00 2001 From: hayzamjs Date: Mon, 21 Jul 2025 18:27:06 +0400 Subject: [PATCH] vm: network: error out if no more switches to attach to --- internal/services/utilities/utilities.go | 2 +- web/package-lock.json | 102 +++++++++++++++--- web/package.json | 2 + web/src/lib/locales/ar.po | 6 +- web/src/lib/locales/cn-simplified.po | 6 +- web/src/lib/locales/en.po | 6 +- web/src/lib/locales/mal.po | 6 +- web/src/lib/locales/ru.po | 6 +- web/src/lib/locales/tu.po | 6 +- web/src/lib/utils/string.ts | 25 +++++ .../[node]/utilities/downloader/+page.svelte | 6 +- .../[node]/vm/[node]/network/+page.svelte | 18 +++- 12 files changed, 170 insertions(+), 21 deletions(-) diff --git a/internal/services/utilities/utilities.go b/internal/services/utilities/utilities.go index d9e475b0..9631efa3 100644 --- a/internal/services/utilities/utilities.go +++ b/internal/services/utilities/utilities.go @@ -32,7 +32,7 @@ type Service struct { } func NewUtilitiesService(db *gorm.DB) utilitiesServiceInterfaces.UtilitiesServiceInterface { - torrent.DisableLogging() + // torrent.DisableLogging() cfg := torrent.DefaultConfig cfg.Database = config.GetDownloadsPath("torrent.db") cfg.DataDir = config.GetDownloadsPath("torrents") diff --git a/web/package-lock.json b/web/package-lock.json index bd6466c2..a6e82200 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -28,6 +28,7 @@ "is-ip": "^5.0.1", "jsonwebtoken": "^9.0.2", "lucide-svelte": "^0.516.0", + "magnet-uri": "^7.0.7", "tabulator-tables": "^6.3.1", "validator": "^13.15.15", "wuchale": "^0.8.3", @@ -48,6 +49,7 @@ "@types/d3-scale": "^4.0.9", "@types/d3-shape": "^3.1.7", "@types/jsonwebtoken": "^9.0.10", + "@types/magnet-uri": "^5.1.5", "@types/tabulator-tables": "^6.2.6", "@types/validator": "^13.15.2", "bits-ui": "^2.8.11", @@ -322,13 +324,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz", - "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz", + "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.0", + "@eslint/core": "^0.15.1", "levn": "^0.4.1" }, "engines": { @@ -336,9 +338,9 @@ } }, "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz", - "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1354,9 +1356,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.22.2.tgz", - "integrity": "sha512-2MvEpSYabUrsJAoq5qCOBGAlkICjfjunrnLcx3YAk2XV7TvAIhomlKsAgR4H/4uns5rAfYmj7Wet5KRtc8dPIg==", + "version": "2.25.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.25.1.tgz", + "integrity": "sha512-8H+fxDEp7Xq6tLFdrGdS5fLu6ONDQQ9DgyjboXpChubuFdfH9QoFX09ypssBpyNkJNZFt9eW3yLmXIc9CesPCA==", "dev": true, "license": "MIT", "dependencies": { @@ -1371,8 +1373,7 @@ "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0", - "vitefu": "^1.0.6" + "sirv": "^3.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -1756,6 +1757,18 @@ "vite": "^5.2.0 || ^6" } }, + "node_modules/@thaunknown/thirty-two": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@thaunknown/thirty-two/-/thirty-two-1.0.5.tgz", + "integrity": "sha512-Q53KyCXweV1CS62EfqtPDqfpksn5keQ59PGqzzkK+g8Vif1jB4inoBCcs/BUSdsqddhE3G+2Fn+4RX3S6RqT0A==", + "license": "MIT", + "dependencies": { + "uint8-util": "^2.2.5" + }, + "engines": { + "node": ">=0.2.6" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -1827,6 +1840,16 @@ "@types/node": "*" } }, + "node_modules/@types/magnet-uri": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/magnet-uri/-/magnet-uri-5.1.5.tgz", + "integrity": "sha512-SbBjlb1KGe38VfjRR+mwqztJd/4skhdKkRbIzPDhTy7IAeEAPZWIVSEkZw00Qr4ZZOGR3/ATJ20WWPBfrKHGdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -2347,6 +2370,24 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/bep53-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-2.0.0.tgz", + "integrity": "sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/bits-ui": { "version": "2.8.11", "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.8.11.tgz", @@ -4474,6 +4515,34 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/magnet-uri": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-7.0.7.tgz", + "integrity": "sha512-z/+dB2NQsXaDuxVBjoPLpZT8ePaacUmoontoFheRBl++nALHYs4qV9MmhTur9e4SaMbkCR/uPX43UMzEOoeyaw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "@thaunknown/thirty-two": "^1.0.5", + "bep53-range": "^2.0.0", + "uint8-util": "^2.2.5" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -5936,6 +6005,15 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/uint8-util": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/uint8-util/-/uint8-util-2.2.5.tgz", + "integrity": "sha512-/QxVQD7CttWpVUKVPz9znO+3Dd4BdTSnFQ7pv/4drVhC9m4BaL2LFHTkJn6EsYoxT79VDq/2Gg8L0H22PrzyMw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/undici-types": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", diff --git a/web/package.json b/web/package.json index 04ee44cb..2314919c 100644 --- a/web/package.json +++ b/web/package.json @@ -28,6 +28,7 @@ "@types/d3-scale": "^4.0.9", "@types/d3-shape": "^3.1.7", "@types/jsonwebtoken": "^9.0.10", + "@types/magnet-uri": "^5.1.5", "@types/tabulator-tables": "^6.2.6", "@types/validator": "^13.15.2", "bits-ui": "^2.8.11", @@ -74,6 +75,7 @@ "is-ip": "^5.0.1", "jsonwebtoken": "^9.0.2", "lucide-svelte": "^0.516.0", + "magnet-uri": "^7.0.7", "tabulator-tables": "^6.3.1", "validator": "^13.15.15", "wuchale": "^0.8.3", diff --git a/web/src/lib/locales/ar.po b/web/src/lib/locales/ar.po index 2aaf82d7..211e38f7 100644 --- a/web/src/lib/locales/ar.po +++ b/web/src/lib/locales/ar.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T15:13:04.883Z\n" -"PO-Revision-Date: 2025-07-21T11:34:37.736Z\n" +"PO-Revision-Date: 2025-07-21T14:26:16.045Z\n" "Last-Translator: \n" "Language: Arabic\n" "Language-Team: \n" @@ -2665,3 +2665,7 @@ msgstr "" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "" diff --git a/web/src/lib/locales/cn-simplified.po b/web/src/lib/locales/cn-simplified.po index 1e724bc0..988e9de8 100644 --- a/web/src/lib/locales/cn-simplified.po +++ b/web/src/lib/locales/cn-simplified.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T15:13:43.695Z\n" -"PO-Revision-Date: 2025-07-21T11:34:37.734Z\n" +"PO-Revision-Date: 2025-07-21T14:26:16.019Z\n" "Last-Translator: \n" "Language: 简体中文\n" "Language-Team: \n" @@ -2665,3 +2665,7 @@ msgstr "" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "" diff --git a/web/src/lib/locales/en.po b/web/src/lib/locales/en.po index f668fb06..82cca814 100644 --- a/web/src/lib/locales/en.po +++ b/web/src/lib/locales/en.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T15:12:48.250Z\n" -"PO-Revision-Date: 2025-07-21T11:20:57.538Z\n" +"PO-Revision-Date: 2025-07-21T14:24:51.127Z\n" "Last-Translator: \n" "Language: English\n" "Language-Team: \n" @@ -2665,3 +2665,7 @@ msgstr "Failed to {0} Samba share" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "Samba share {0}" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "No available/unused switches to attach to" diff --git a/web/src/lib/locales/mal.po b/web/src/lib/locales/mal.po index 817ef8d8..d1323b49 100644 --- a/web/src/lib/locales/mal.po +++ b/web/src/lib/locales/mal.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T15:13:23.412Z\n" -"PO-Revision-Date: 2025-07-21T11:34:37.731Z\n" +"PO-Revision-Date: 2025-07-21T14:26:16.016Z\n" "Last-Translator: \n" "Language: Malayalam\n" "Language-Team: \n" @@ -2665,3 +2665,7 @@ msgstr "" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "" diff --git a/web/src/lib/locales/ru.po b/web/src/lib/locales/ru.po index dd8a95d8..0219d4f8 100644 --- a/web/src/lib/locales/ru.po +++ b/web/src/lib/locales/ru.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T15:13:09.713Z\n" -"PO-Revision-Date: 2025-07-21T11:34:37.741Z\n" +"PO-Revision-Date: 2025-07-21T14:26:16.047Z\n" "Last-Translator: \n" "Language: Russian\n" "Language-Team: \n" @@ -2665,3 +2665,7 @@ msgstr "" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "" diff --git a/web/src/lib/locales/tu.po b/web/src/lib/locales/tu.po index e37e1315..f7c999fc 100644 --- a/web/src/lib/locales/tu.po +++ b/web/src/lib/locales/tu.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-19T13:45:12.198Z\n" -"PO-Revision-Date: 2025-07-21T11:20:57.590Z\n" +"PO-Revision-Date: 2025-07-21T14:26:16.053Z\n" "Last-Translator: \n" "Language: Türkçe\n" "Language-Team: \n" @@ -2675,3 +2675,7 @@ msgstr "" #: src/lib/components/custom/Samba/Share.svelte msgid "Samba share {0}" msgstr "" + +#: src/routes/[node]/vm/[node]/network/+page.svelte +msgid "No available/unused switches to attach to" +msgstr "" diff --git a/web/src/lib/utils/string.ts b/web/src/lib/utils/string.ts index 0d22d62b..0c1076be 100644 --- a/web/src/lib/utils/string.ts +++ b/web/src/lib/utils/string.ts @@ -11,6 +11,7 @@ import { getIcon, loadIcon } from '@iconify/svelte'; import isCidr from 'is-cidr'; import { isIP, isIPv4 } from 'is-ip'; +import { decode as magnetDecode, encode as magnetEncode } from 'magnet-uri'; import { customRandom, nanoid } from 'nanoid'; import isEmail from 'validator/lib/isEmail'; import isMACAddress from 'validator/lib/isMACAddress'; @@ -194,3 +195,27 @@ export function isValidEmail(email: string): boolean { allow_display_name: false }); } + +export function addTrackersToMagnet(uri: string): string { + try { + const parsed = magnetDecode(uri); + if (!parsed.tr || parsed.tr.length === 0) { + const trackers = [ + 'udp://tracker.opentrackr.org:1337/announce', + 'udp://tracker.coppersurfer.tk:6969/announce', + 'udp://tracker.internetwarriors.net:1337/announce', + 'udp://tracker.openbittorrent.com:80/announce', + 'udp://tracker.publicbt.com:80/announce' + ]; + + parsed.tr = trackers; + parsed.announce = trackers; + } + + return magnetEncode(parsed); + } catch (e) { + console.error('Invalid magnet URI:', e); + } + + return uri; +} diff --git a/web/src/routes/[node]/utilities/downloader/+page.svelte b/web/src/routes/[node]/utilities/downloader/+page.svelte index 008f053c..3d050ac9 100644 --- a/web/src/routes/[node]/utilities/downloader/+page.svelte +++ b/web/src/routes/[node]/utilities/downloader/+page.svelte @@ -16,7 +16,7 @@ import type { Row } from '$lib/types/components/tree-table'; import type { Download } from '$lib/types/utilities/downloader'; import { handleAPIError, isAPIResponse, updateCache } from '$lib/utils/http'; - import { isDownloadURL } from '$lib/utils/string'; + import { addTrackersToMagnet, isDownloadURL } from '$lib/utils/string'; import { generateTableData } from '$lib/utils/utilities/downloader'; import Icon from '@iconify/svelte'; import { useQueries } from '@sveltestack/svelte-query'; @@ -112,6 +112,10 @@ return; } + if (isMagnet(modalState.url)) { + modalState.url = addTrackersToMagnet(modalState.url); + } + const result = await startDownload(modalState.url); if (result) { modalState.isOpen = false; diff --git a/web/src/routes/[node]/vm/[node]/network/+page.svelte b/web/src/routes/[node]/vm/[node]/network/+page.svelte index 6c94fafd..62617d8e 100644 --- a/web/src/routes/[node]/vm/[node]/network/+page.svelte +++ b/web/src/routes/[node]/vm/[node]/network/+page.svelte @@ -14,6 +14,7 @@ import { handleAPIError, updateCache } from '$lib/utils/http'; import Icon from '@iconify/svelte'; import { useQueries } from '@sveltestack/svelte-query'; + import { untrack } from 'svelte'; import { toast } from 'svelte-sonner'; import type { CellComponent } from 'tabulator-tables'; @@ -127,6 +128,11 @@ let activeRows: Row[] | null = $state(null); let activeRow: Row | null = $derived(activeRows ? (activeRows[0] as Row) : ({} as Row)); let query = $state(''); + let usable = $derived.by(() => { + return switches.standard?.filter((s) => { + return !vm?.networks.some((n) => n.switchId === s.id); + }); + }); let options = { attach: { @@ -170,7 +176,17 @@