// @ts-nocheck import * as quark_api from "./quark-api"; import * as system_config_service from "../../admin/system-config.service"; /** * 广告关键词清理模块。 * 在转存完成后执行: * 1. 遍历转存的目录,删除文件名/文件夹名含广告关键词的内容 * 2. 在转存根目录下创建警示文件夹(置顶提醒) */ // ==================== 配置读取 ==================== /** 从 DB 读取广告关键词列表 */ export function getAdKeywords() { const raw = system_config_service.getSystemConfig("quark_ad_keywords") || ""; return raw .split("\n") .flatMap((line) => line.split(",")) .map((s) => s.trim()) .filter(Boolean); } /** 从 DB 读取警示文件夹名称列表 */ export function getWarningFolderNames() { const raw = system_config_service.getSystemConfig("quark_warning_folder_names") || ""; return raw .split("\n") .flatMap((line) => line.split(",")) .map((s) => s.trim()) .filter(Boolean); } /** 从 DB 读取可疑文件后缀列表 */ export function getSusExtensions() { const raw = system_config_service.getSystemConfig("quark_sus_extensions") || ""; if (raw.trim()) { return raw .split("\n") .map((s) => s.trim().toLowerCase().replace(/^\./, "")) .filter(Boolean); } // 默认可疑后缀 return ["bat", "exe", "vbs", "scr", "cmd", "com", "pif", "js", "jar", "msi", "reg", "inf", "ps1"]; } // ==================== 关键词检测 ==================== /** 检查文件名是否包含任意广告关键词 */ export function containsAdKeyword(fileName, keywords) { if (!keywords.length) return false; const lower = fileName.toLowerCase(); return keywords.some((kw) => kw && lower.includes(kw.toLowerCase())); } // ==================== 删除操作 ==================== /** * 遍历指定目录(含子目录),删除匹配广告关键词的文件和文件夹。 * 返回删除的文件数。 */ export async function deleteAdFiles(cookie, dirFid, keywords) { const extensions = getSusExtensions(); if (!keywords.length && !extensions.length) return 0; let deletedCount = 0; const stack = [dirFid]; const visited = new Set(); while (stack.length > 0) { const fid = stack.pop(); if (visited.has(fid)) continue; visited.add(fid); await quark_api.humanDelay(); const files = await quark_api.listDir(cookie, fid); if (!files || files.length === 0) continue; // 先收集所有需要删除的 fid const toDelete = []; const toKeep = []; const extensions = getSusExtensions(); for (const file of files) { const ext = file.file.split(".").pop()?.toLowerCase() || ""; const isSusExt = extensions.includes(ext); if (containsAdKeyword(file.file_name, keywords) || isSusExt) { toDelete.push(file.fid); console.log(`[Quark-AdCleanup] 标记删除: "${file.file_name}" (fid: ${file.fid})${isSusExt ? " [可疑后缀]" : " [广告关键词]"}`); } else { toKeep.push(file.fid); // 如果是目录且不删除,继续遍历子目录 if (file.dir) { stack.push(file.fid); } } } // 批量删除 if (toDelete.length > 0) { const deleteOk = await batchDeleteFiles(cookie, toDelete); if (deleteOk) { deletedCount += toDelete.length; console.log(`[Quark-AdCleanup] 已删除 ${toDelete.length} 个广告文件`); } } } return deletedCount; } /** * 批量删除文件/文件夹(移入回收站)。 */ async function batchDeleteFiles(cookie, fids) { if (!fids.length) return true; try { const resp = await fetch(`https://drive-pc.quark.cn/1/clouddrive/file/trash?${quark_api.makeQuery()}`, { method: "POST", headers: { ...quark_api.getHeaders(cookie), "Content-Type": "application/json", }, body: JSON.stringify({ action_type: 1, filelist: fids, exclude_filelist: [], }), signal: AbortSignal.timeout(30000), }); if (!resp.ok) { console.log(`[Quark-AdCleanup] batchDelete HTTP ${resp.status}`); return false; } const data = (await resp.json()); if (data.status === 200) { return true; } console.log(`[Quark-AdCleanup] batchDelete 返回非200: status=${data.status} msg=${data.message}`); return false; } catch (err) { console.log(`[Quark-AdCleanup] batchDelete 错误: ${err.message}`); return false; } } // ==================== 警示文件夹创建 ==================== /** * 在转存根目录下创建警示文件夹。 * 文件夹名前加 ⚠️ 和空格,让其按字母排序置顶。 * 已存在的则跳过。 */ export async function createWarningDirectories(cookie, dirNames, parentDirFid = "0") { if (!dirNames.length) return; // 先获取根目录下所有文件夹,避免重复创建 await quark_api.humanDelay(); const rootFiles = await quark_api.listDirAllPages(cookie, parentDirFid); const existingDirs = new Set(rootFiles.filter((f) => f.dir).map((f) => f.file_name)); for (const name of dirNames) { // 格式化名称:确保以 ⚠️ 开头 let formattedName = name; if (!formattedName.startsWith("⚠️") && !formattedName.startsWith("⚠")) { formattedName = `⚠️ ${formattedName}`; } // 去掉多余空格 formattedName = formattedName.replace(/\s+/g, " ").trim(); if (existingDirs.has(formattedName)) { console.log(`[Quark-AdCleanup] 警示文件夹已存在,跳过: "${formattedName}"`); continue; } await createSingleDir(cookie, formattedName, parentDirFid); // 加入已存在集合,防止同名重试 existingDirs.add(formattedName); } } /** * 创建单个文件夹。 */ async function createSingleDir(cookie, dirName, pdirFid = "0") { try { const resp = await fetch(`https://drive-pc.quark.cn/1/clouddrive/file?${quark_api.makeQuery()}`, { method: "POST", headers: { ...quark_api.getHeaders(cookie), "Content-Type": "application/json", }, body: JSON.stringify({ pdir_fid: pdirFid, file_name: dirName, dir: true, dir_path: "", }), signal: AbortSignal.timeout(10000), }); const data = (await resp.json()); if (data.status === 200 && data.data?.fid) { console.log(`[Quark-AdCleanup] 已创建警示文件夹: "${dirName}" (fid: ${data.data.fid})`); return true; } console.log(`[Quark-AdCleanup] 创建文件夹失败: status=${data.status} msg=${data.message}`); return false; } catch (err) { console.log(`[Quark-AdCleanup] 创建文件夹错误: "${dirName}" — ${err.message}`); return false; } } // ==================== 主入口 ==================== /** * 执行广告清理 + 创建警示文件夹。 * 在转存重命名后调用。 */ export async function runAdCleanup(cookie, savedDirFid) { const keywords = getAdKeywords(); const susExtensions = getSusExtensions(); const warningNames = getWarningFolderNames(); let adDeleted = 0; let warningDirs = 0; // 1. 广告关键词 + 可疑后缀清理 if (keywords.length > 0 || susExtensions.length > 0) { console.log(`[Quark-AdCleanup] 开始文件清理: ${keywords.length} 个关键词, ${susExtensions.length} 个可疑后缀`); adDeleted = await deleteAdFiles(cookie, savedDirFid, keywords); console.log(`[Quark-AdCleanup] 清理完成,共删除 ${adDeleted} 个文件/文件夹`); } else { console.log("[Quark-AdCleanup] 无关键词/可疑后缀配置,跳过清理"); } // 2. 创建警示文件夹 if (warningNames.length > 0) { console.log(`[Quark-AdCleanup] 开始创建警示文件夹: ${warningNames.length} 个`); await createWarningDirectories(cookie, warningNames, savedDirFid); warningDirs = warningNames.length; console.log(`[Quark-AdCleanup] 警示文件夹创建完成(共 ${warningDirs} 个)`); } else { console.log("[Quark-AdCleanup] 无警示文件夹配置,跳过创建"); } return { adDeleted, warningDirs }; }