// @ts-nocheck import * as quark_api from "./quark-api"; import * as quark_share from "./quark-share"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); /** * 转存 & 存储管理模块。 * 处理分享链接解析 → 转存 → 查/创建目标文件夹 → 文件重命名 → 递归统计。 */ // ==================== saveFromShare — 核心转存流水线 ==================== /** * Save files from a share link → magic rename → create shared link. * * Flow: token → detail → save → wait_task → rename → share */ export async function saveFromShare(cookie, nickname, shareUrl, sourceTitle, retrySave = false) { try { // Parse share token from URL const urlObj = new URL(shareUrl); const pwdId = urlObj.pathname.split('/').filter(Boolean).pop(); if (!pwdId) { return { success: false, message: 'Invalid share URL: could not extract share token' }; } // Step 1: Acquire stoken const stoken = await quark_share.acquireStoken(cookie, pwdId); if (!stoken) { return { success: false, message: '😅 Oops!资源好像偷偷溜走了,换个链接试试吧~' }; } // Step 2: Get share detail const shareInfo = await quark_share.getShareFiles(cookie, pwdId, stoken); if (!shareInfo || !shareInfo.files || shareInfo.files.length === 0) { return { success: false, message: '🌚 空的!这个分享里啥都没有…' }; } const { files: topFiles, topDir, childFiles } = shareInfo; const originalFolderName = topFiles[0]?.file_name || ''; const fids = topFiles.map(f => f.fid); const fidTokens = topFiles.map(f => f.share_fid_token); // 按日期创建/查找文件夹,每天的转存存入当天文件夹 await quark_api.humanDelay(); const saveDirName = quark_api.dailyFolderName(); console.log(`[Quark] saveFromShare: looking for/create dir "${saveDirName}"`); const saveDirFid = await findOrCreateDir(cookie, saveDirName); let targetPdirFid = saveDirFid || '0'; let retrySubFolderFid = ''; if (saveDirFid) { console.log(`[Quark] Using save directory: ${saveDirName} (fid: ${saveDirFid})`); if (retrySave) { const subName = 'retry_' + Math.random().toString(36).slice(2, 6); console.log(`[Quark] Retry: creating subfolder "${subName}" inside "${saveDirName}"`); retrySubFolderFid = await findOrCreateDir(cookie, subName, saveDirFid); if (retrySubFolderFid) { targetPdirFid = retrySubFolderFid; console.log(`[Quark] Retry: saving to subfolder ${subName} (fid: ${retrySubFolderFid})`); } } } else { console.log(`[Quark] WARNING: failed to create/find dir "${saveDirName}", saving to root`); } // Step 3: Save top-level item(s) to the target directory const saveResult = await quark_share.saveFiles(cookie, pwdId, stoken, fids, fidTokens.filter(Boolean), targetPdirFid); if (!saveResult.success) { return saveResult; } const taskId = saveResult.taskId; // Step 4: Wait for save task to complete (poll up to 30s) const savedFids = await quark_share.waitForTask(cookie, taskId, 30000); if (!savedFids || savedFids.length === 0) { return { success: true, message: '文件已保存,但获取保存结果超时' }; } // Step 5: Magic rename files — with random delay to avoid detection await quark_api.humanDelay(); const renamed = []; let shareFid = ''; let savedFolderName = ''; let newInnerDirName = ''; if (topDir && childFiles && childFiles.length > 0) { // ── Single folder share ── const savedDirFid = savedFids[0]; shareFid = savedDirFid; savedFolderName = topFiles[0]?.file_name || ''; } else { // ── Multiple files at top level ── shareFid = savedFids[0]; savedFolderName = topFiles[0]?.file_name || ''; } if (retrySave && retrySubFolderFid) { shareFid = retrySubFolderFid; console.log(`[Quark] Retry: sharing subfolder (fid: ${retrySubFolderFid}) instead of saved content`); } // Step 6: Create share link FIRST (before rename), so all files are guaranteed to be shared await quark_api.humanDelay(); let shareUrlResult = ''; let sharePwdResult = ''; let shareMsg = ''; let successCount = 0; // total items (files + folders) actually saved const { createShareLink } = await import('./quark-share'); if (shareFid) { const shareResult = await createShareLink(cookie, shareFid); if (shareResult.success && shareResult.shareUrl) { shareUrlResult = shareResult.shareUrl; if (shareResult.sharePwd) sharePwdResult = shareResult.sharePwd; } else { shareMsg = `(分享失败:${shareResult.message})`; } } const { magicRenameDir, magicRename } = await import('./quark-rename'); const { renameFile } = await import('./quark-share'); // Step 7: Rename files AFTER creating the share link (anti-harmony, won't affect the share) if (topDir && childFiles && childFiles.length > 0) { // ── Single folder share ── const savedDirFid = savedFids[0]; // List files inside the saved directory const dirFiles = await quark_api.listDir(cookie, savedDirFid); if (dirFiles && dirFiles.length > 0) { for (const file of dirFiles) { if (file.dir) continue; const newName = magicRename(file.file_name); const renameOk = await renameFile(cookie, file.fid, newName); if (renameOk) { renamed.push({ original: file.file_name, renamed: newName }); } } } // Also rename the inner folder itself (the actual shared folder) const innerDirOriginalName = sourceTitle || topFiles[0]?.file_name || ''; if (innerDirOriginalName) { newInnerDirName = magicRenameDir(innerDirOriginalName); const innerDirRenameOk = await renameFile(cookie, savedDirFid, newInnerDirName); if (innerDirRenameOk) { console.log(`[Quark] Renamed inner folder: ${innerDirOriginalName} → ${newInnerDirName}`); } } } else { // ── Multiple files at top level ── for (let i = 0; i < savedFids.length && i < topFiles.length; i++) { const originalName = topFiles[i].file_name; if (topFiles[i].dir) continue; const newName = magicRename(originalName); const renameOk = await renameFile(cookie, savedFids[i], newName); if (renameOk) { renamed.push({ original: originalName, renamed: newName }); } } } // Step 7.5: 广告关键词清理 + 创建警示文件夹 if (shareFid) { try { const { runAdCleanup } = await import('./quark-ad-cleanup'); const adResult = await runAdCleanup(cookie, shareFid); if (adResult.adDeleted > 0) { console.log(`[Quark] 广告清理完成: 删除了 ${adResult.adDeleted} 个广告文件/文件夹`); } if (adResult.warningDirs > 0) { console.log(`[Quark] 已创建 ${adResult.warningDirs} 个警示文件夹`); } } catch (err) { console.log(`[Quark] 广告清理/警示文件夹创建失败(非致命): ${err.message}`); } } // Step 8: DAY FOLDER STAYS AS-IS (e.g. "2026-05-03") // DO NOT rename the date folder — it serves as the organizational container. savedFolderName = newInnerDirName ? `${saveDirName}/${newInnerDirName}` : saveDirName; // Recursively count files and folders from saved cloud directory let fileCount = 0; let folderCount = 0; if (shareFid) { try { const counts = await countRecursive(cookie, shareFid); fileCount = counts.fileCount; folderCount = counts.folderCount; } catch { console.log('[Quark] Recursive count failed, using fallback'); } } // If recursive count returned nothing, try fallback if (fileCount === 0 && folderCount === 0) { if (topDir && childFiles) { folderCount = 1 + childFiles.filter(f => f.dir).length; fileCount = childFiles.filter(f => !f.dir).length; } else { folderCount = topFiles.filter(f => f.dir).length; fileCount = topFiles.filter(f => !f.dir).length; } } // Calculate total file size const allFiles = topDir && childFiles ? childFiles : topFiles; const fileSize = allFiles.reduce((sum, f) => sum + (Number(f.size) || 0), 0); const renameMsg = renamed.length > 0 ? `,已重命名 ${renamed.length} 个文件` : ''; const folderMsg = savedFolderName ? `到文件夹「${savedFolderName}」` : ''; return { success: true, message: `已保存${folderMsg}${renameMsg}${shareMsg}`, shareUrl: shareUrlResult || undefined, sharePwd: sharePwdResult || undefined, folderName: savedFolderName, taskId, renamed: renamed.map(r => `${r.original} → ${r.renamed}`), fileCount, folderCount, fileSize, originalFolderName, }; } catch (err) { return { success: false, message: err.message || 'Network error' }; } } // ==================== Dir Management ==================== /** * Create a new directory at root. */ export async function createDir(cookie, dirName, parentFid = '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: parentFid, 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] Created dir "${dirName}" (fid: ${data.data.fid})`); return data.data.fid; } console.log(`[Quark] createDir API returned non-200: status=${data.status} msg=${data.message}`); return null; } catch (err) { console.log(`[Quark] createDir error: ${err.message}`); return null; } } /** * Find an existing directory by name, or create it if not found. */ export async function findOrCreateDir(cookie, dirName, parentFid = '0') { try { const rootFiles = await quark_api.listDirAllPages(cookie, parentFid); const existing = rootFiles.find(f => f.dir && f.file_name === dirName); if (existing?.fid) { console.log(`[Quark] Found existing daily folder: ${dirName} (fid: ${existing.fid})`); return existing.fid; } console.log(`[Quark] Daily folder "${dirName}" not found, creating...`); } catch (err) { console.log(`[Quark] findOrCreateDir list error: ${err.message}`); } const fid = await createDir(cookie, dirName, parentFid); console.log(`[Quark] createDir result for "${dirName}": ${fid || 'null'}`); return fid; } // ==================== Recursive Count ==================== /** * Recursively count files and folders for a saved cloud directory. */ export async function countRecursive(cookie, pdirFid) { let fileCount = 0; let folderCount = 0; const stack = [pdirFid]; const visited = new Set(); while (stack.length > 0) { const fid = stack.pop(); if (visited.has(fid)) continue; visited.add(fid); const files = await quark_api.listDir(cookie, fid); if (!files) continue; for (const f of files) { if (f.dir) { folderCount++; stack.push(f.fid); } else { fileCount++; } } } return { fileCount, folderCount }; }