From 6fcfa438d979d7dae8d4e14f2364aa494f99b297 Mon Sep 17 00:00:00 2001 From: shenmo Date: Sun, 12 Apr 2026 16:44:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(update-center):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E4=B8=8B=E8=BD=BD=E5=8C=85=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=AE=89=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 buildLegacySparkUpgradeCommand,所有更新现在需要先下载 deb 包 - 为 APTSS 添加元数据查询功能 - 优化 aria2c 下载参数,使用 metalink URL - 版本号更新至 5.0.0beta4 --- .../main/backend/update-center/download.ts | 11 ++- electron/main/backend/update-center/index.ts | 76 +++++++++++++-- .../main/backend/update-center/install.ts | 97 ++++++------------- package-lock.json | 4 +- 4 files changed, 114 insertions(+), 74 deletions(-) diff --git a/electron/main/backend/update-center/download.ts b/electron/main/backend/update-center/download.ts index 42000bf7..f6e030c4 100644 --- a/electron/main/backend/update-center/download.ts +++ b/electron/main/backend/update-center/download.ts @@ -33,13 +33,22 @@ export const runAria2Download = async ({ const filePath = join(downloadDir, item.fileName); + // Use .metalink URL for download (same as Qt version) + const metalinkUrl = `${item.downloadUrl}.metalink`; + await new Promise((resolve, reject) => { const child = spawn("aria2c", [ "--dir", downloadDir, "--out", item.fileName, - item.downloadUrl, + "--enable-rpc=false", + "--console-log-level=warn", + "--summary-interval=1", + "--allow-overwrite=true", + "--connect-timeout=30", + "--max-tries=3", + metalinkUrl, ]); const abortDownload = () => { diff --git a/electron/main/backend/update-center/index.ts b/electron/main/backend/update-center/index.ts index f5de499f..76c100e6 100644 --- a/electron/main/backend/update-center/index.ts +++ b/electron/main/backend/update-center/index.ts @@ -66,6 +66,14 @@ const getApmPrintUrisCommand = (pkgname: string) => ({ ], }); +const getAptssPrintUrisCommand = (pkgname: string) => ({ + command: "bash", + args: [ + "-lc", + `/usr/bin/apt download ${pkgname} --print-uris -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf -o Dir::Etc::sourcelist=/opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/aptss.list -o Dir::Etc::sourceparts=/dev/null`, + ], +}); + const runCommandCapture: UpdateCenterCommandRunner = async ( command, args, @@ -140,6 +148,42 @@ const loadApmItemMetadata = async ( }; }; +const loadAptssItemMetadata = async ( + item: UpdateCenterItem, + runCommand: UpdateCenterCommandRunner, +): Promise< + | { item: UpdateCenterItem; warning?: undefined } + | { item: null; warning: string } +> => { + const printUrisCommand = getAptssPrintUrisCommand(item.pkgname); + const metadataResult = await runCommand( + printUrisCommand.command, + printUrisCommand.args, + ); + const commandError = getCommandError( + `aptss metadata query for ${item.pkgname}`, + metadataResult, + ); + if (commandError) { + return { item: null, warning: commandError }; + } + + const metadata = parsePrintUrisOutput(metadataResult.stdout); + if (!metadata) { + return { + item: null, + warning: `aptss metadata query for ${item.pkgname} returned no package metadata`, + }; + } + + return { + item: { + ...item, + ...metadata, + }, + }; +}; + const enrichApmItems = async ( items: UpdateCenterItem[], runCommand: UpdateCenterCommandRunner, @@ -156,6 +200,22 @@ const enrichApmItems = async ( }; }; +const enrichAptssItems = async ( + items: UpdateCenterItem[], + runCommand: UpdateCenterCommandRunner, +): Promise => { + const results = await Promise.all( + items.map((item) => loadAptssItemMetadata(item, runCommand)), + ); + + return { + items: results.flatMap((result) => (result.item ? [result.item] : [])), + warnings: results.flatMap((result) => + result.warning ? [result.warning] : [], + ), + }; +}; + const getStoreArch = ( item: Pick, ): string => { @@ -299,18 +359,22 @@ export const loadUpdateCenterItems = async ( enrichItemCategories(aptssItems), enrichItemCategories(apmItems), ]); - const enrichedApmItems = await enrichApmItems( - categorizedApmItems, - runCommand, - ); + const [enrichedAptssItems, enrichedApmItems] = await Promise.all([ + enrichAptssItems(categorizedAptssItems, runCommand), + enrichApmItems(categorizedApmItems, runCommand), + ]); return { items: mergeUpdateSources( - enrichItemIcons(categorizedAptssItems), + enrichItemIcons(enrichedAptssItems.items), enrichItemIcons(enrichedApmItems.items), installedSources, ), - warnings: [...warnings, ...enrichedApmItems.warnings], + warnings: [ + ...warnings, + ...enrichedAptssItems.warnings, + ...enrichedApmItems.warnings, + ], }; }; diff --git a/electron/main/backend/update-center/install.ts b/electron/main/backend/update-center/install.ts index 3cdd0c2c..937e5620 100644 --- a/electron/main/backend/update-center/install.ts +++ b/electron/main/backend/update-center/install.ts @@ -119,29 +119,8 @@ const buildPrivilegedCommand = ( }; }; -export const buildLegacySparkUpgradeCommand = ( - pkgname: string, - superUserCmd = "", -): UpdateCommand => { - if (superUserCmd) { - return { - execCommand: superUserCmd, - execParams: [ - SHELL_CALLER_PATH, - "aptss", - "install", - "-y", - pkgname, - "--only-upgrade", - ], - }; - } - - return { - execCommand: SHELL_CALLER_PATH, - execParams: ["aptss", "install", "-y", pkgname, "--only-upgrade"], - }; -}; +// Removed buildLegacySparkUpgradeCommand - all updates now require downloading the deb package first +// to avoid aptss install popup. Use ssinstall with downloaded deb file instead. export const installUpdateItem = async ({ item, @@ -150,11 +129,13 @@ export const installUpdateItem = async ({ onLog, signal, }: InstallUpdateItemOptions): Promise => { - if (item.source === "apm" && !filePath) { - throw new Error("APM update task requires downloaded package metadata"); + if (!filePath) { + throw new Error( + `Update task for ${item.pkgname} requires downloaded package file`, + ); } - if (item.source === "apm" && filePath) { + if (item.source === "apm") { const installCommand = buildPrivilegedCommand( SHELL_CALLER_PATH, ["apm", "ssinstall", filePath], @@ -169,26 +150,18 @@ export const installUpdateItem = async ({ return; } - if (filePath) { - const installCommand = buildPrivilegedCommand( - SSINSTALL_PATH, - [filePath, "--delete-after-install"], - superUserCmd, - ); - await runCommand( - installCommand.execCommand, - installCommand.execParams, - onLog, - signal, - ); - return; - } - - const command = buildLegacySparkUpgradeCommand( - item.pkgname, - superUserCmd ?? "", + // APTSS (Spark Store) packages use ssinstall + const installCommand = buildPrivilegedCommand( + SSINSTALL_PATH, + [filePath, "--delete-after-install", "--no-create-desktop-entry", "--native"], + superUserCmd, + ); + await runCommand( + installCommand.execCommand, + installCommand.execParams, + onLog, + signal, ); - await runCommand(command.execCommand, command.execParams, onLog, signal); }; export const createTaskRunner = ( @@ -246,30 +219,24 @@ export const createTaskRunner = ( }; try { - let filePath: string | undefined; - - if ( - task.item.source === "apm" && - (!task.item.downloadUrl || !task.item.fileName) - ) { + // All updates require download metadata + if (!task.item.downloadUrl || !task.item.fileName) { throw new Error( - "APM update task requires downloaded package metadata", + `Update task for ${task.item.pkgname} requires download metadata (URL and filename)`, ); } - if (task.item.downloadUrl && task.item.fileName) { - queue.markActiveTask(task.id, "downloading"); - const result = await runDownload({ - item: task.item, - task, - onLog, - signal: activeAbortController.signal, - onProgress: (progress) => { - queue.updateTaskProgress(task.id, progress); - }, - }); - filePath = result.filePath; - } + queue.markActiveTask(task.id, "downloading"); + const result = await runDownload({ + item: task.item, + task, + onLog, + signal: activeAbortController.signal, + onProgress: (progress) => { + queue.updateTaskProgress(task.id, progress); + }, + }); + const filePath = result.filePath; queue.markActiveTask(task.id, "installing"); await installItem({ diff --git a/package-lock.json b/package-lock.json index 28dcf426..8b890caf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "spark-store", - "version": "5.0.0beta3", + "version": "5.0.0beta4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "spark-store", - "version": "5.0.0beta3", + "version": "5.0.0beta4", "license": "GPL-3.0", "dependencies": { "@tailwindcss/vite": "^4.1.18",