diff --git a/server/server.js b/server/server.js index 41b736b..58954c1 100644 --- a/server/server.js +++ b/server/server.js @@ -835,9 +835,14 @@ function updateMoveProgressFromStats(stats) { if (!stats) return false; const transfers = Array.isArray(stats.transferring) ? stats.transferring : []; let updated = false; - const applyProgress = (entry, prefix) => { + const applyProgress = (entry, prefixes, relRoot) => { if (!entry) return; - const matched = transfers.filter((t) => String(t.name || "").includes(prefix)); + const safePrefixes = Array.isArray(prefixes) + ? prefixes.filter(Boolean) + : [prefixes].filter(Boolean); + const matched = transfers.filter((t) => + safePrefixes.some((p) => String(t.name || "").includes(p)) + ); if (matched.length) { const bytes = matched.reduce((sum, t) => sum + (Number(t.bytes) || 0), 0); const pct = matched.reduce((sum, t) => sum + (Number(t.percentage) || 0), 0) / matched.length; @@ -859,8 +864,14 @@ function updateMoveProgressFromStats(stats) { updated = true; } } else { - // Transfer görünmüyorsa queued kalır; done kararı aşağıda verilecek. - if (entry.moveStatus === "uploading") { + const gdriveTarget = relRoot ? path.join(GDRIVE_ROOT, relRoot) : null; + const targetExists = gdriveTarget ? fs.existsSync(gdriveTarget) : false; + if (targetExists) { + entry.moveStatus = "done"; + entry.moveProgress = 1; + updated = true; + } else if (entry.moveStatus === "uploading") { + // Transfer görünmüyorsa queued kalır; done kararı yukarıda olabilir. entry.moveStatus = "queued"; updated = true; } @@ -868,15 +879,29 @@ function updateMoveProgressFromStats(stats) { }; for (const entry of torrents.values()) { - applyProgress(entry, `${RCLONE_REMOTE_PATH}/${entry.rootFolder || ""}`); + const relRoot = entry.rootFolder || ""; + const prefixes = [ + relRoot, + RCLONE_REMOTE_PATH ? `${RCLONE_REMOTE_PATH}/${relRoot}` : null + ]; + applyProgress(entry, prefixes, relRoot); } for (const job of youtubeJobs.values()) { - applyProgress(job, `${RCLONE_REMOTE_PATH}/${job.folderId || ""}`); + const relRoot = job.folderId || ""; + const prefixes = [ + relRoot, + RCLONE_REMOTE_PATH ? `${RCLONE_REMOTE_PATH}/${relRoot}` : null + ]; + applyProgress(job, prefixes, relRoot); } for (const job of mailruJobs.values()) { - const folderPrefix = job.folderId ? `${RCLONE_REMOTE_PATH}/${job.folderId}` : null; - if (folderPrefix) { - applyProgress(job, folderPrefix); + const relRoot = job.folderId || ""; + const prefixes = [ + relRoot, + RCLONE_REMOTE_PATH ? `${RCLONE_REMOTE_PATH}/${relRoot}` : null + ]; + if (relRoot) { + applyProgress(job, prefixes, relRoot); } } @@ -1004,17 +1029,17 @@ function startRcloneCacheCleanSchedule(minutes) { if (!interval || interval <= 0) return; rcloneCacheCleanTimer = setInterval(() => { if (!RCLONE_RC_ENABLED) return; - fetch(`http://${RCLONE_RC_ADDR}/vfs/forget`, { + fetch(`http://${RCLONE_RC_ADDR}/vfs/refresh`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path: "", recursive: true }) + body: JSON.stringify({ recursive: true }) }) .then((resp) => { if (resp.status === 404) { - return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, { + return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/refresh`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path: "", recursive: true }) + body: JSON.stringify({ recursive: true }) }); } return resp; @@ -1032,16 +1057,16 @@ async function runRcloneCacheClean() { const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed); try { if (wasRunning && RCLONE_RC_ENABLED) { - const resp = await fetch(`http://${RCLONE_RC_ADDR}/vfs/forget`, { + const resp = await fetch(`http://${RCLONE_RC_ADDR}/vfs/refresh`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path: "", recursive: true }) + body: JSON.stringify({ recursive: true }) }); if (resp.status === 404) { - const fallback = await fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, { + const fallback = await fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/refresh`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path: "", recursive: true }) + body: JSON.stringify({ recursive: true }) }); if (!fallback.ok) { const body = await fallback.text(); @@ -1194,8 +1219,16 @@ async function moveRootFolderToGdrive(rootFolder) { if (!fs.existsSync(sourceDir)) { return { ok: false, error: "Kaynak root bulunamadı" }; } + try { + ensureRcloneDirs({ mountDir: GDRIVE_ROOT }); + } catch (err) { + return { ok: false, error: err?.message || String(err) }; + } if (!fs.existsSync(GDRIVE_ROOT)) { - return { ok: false, error: "GDrive mount dizini bulunamadı" }; + return { ok: false, error: `GDrive mount dizini bulunamadı: ${GDRIVE_ROOT}` }; + } + if (!isRcloneMounted(GDRIVE_ROOT)) { + return { ok: false, error: "GDrive mount aktif değil" }; } const targetDir = path.join(GDRIVE_ROOT, safeRoot); if (fs.existsSync(targetDir)) { @@ -1228,6 +1261,17 @@ async function movePathToGdrive(relPath) { if (!safeRel) return { ok: false, error: "Geçersiz yol" }; const sourceFile = path.join(DOWNLOAD_DIR, safeRel); if (fs.existsSync(sourceFile) && fs.statSync(sourceFile).isFile()) { + try { + ensureRcloneDirs({ mountDir: GDRIVE_ROOT }); + } catch (err) { + return { ok: false, error: err?.message || String(err) }; + } + if (!fs.existsSync(GDRIVE_ROOT)) { + return { ok: false, error: `GDrive mount dizini bulunamadı: ${GDRIVE_ROOT}` }; + } + if (!isRcloneMounted(GDRIVE_ROOT)) { + return { ok: false, error: "GDrive mount aktif değil" }; + } const targetFile = path.join(GDRIVE_ROOT, safeRel); ensureDirForFile(targetFile); try {