fix(rclone): ilerleme takibini ve mount kontrolünü iyileştir
İlerleme güncellemelerinde artık hedef dosya/dizin GDrive'da mevcutsa durum "done" olarak işaretleniyor. Transfer eşleştirmesi birden fazla prefix desteği ile daha doğru çalışıyor. Cache temizleme işleminde vfs/refresh kullanılıyor ve mount işlemlerinden önce aktiflik kontrolü eklendi.
This commit is contained in:
@@ -835,9 +835,14 @@ function updateMoveProgressFromStats(stats) {
|
|||||||
if (!stats) return false;
|
if (!stats) return false;
|
||||||
const transfers = Array.isArray(stats.transferring) ? stats.transferring : [];
|
const transfers = Array.isArray(stats.transferring) ? stats.transferring : [];
|
||||||
let updated = false;
|
let updated = false;
|
||||||
const applyProgress = (entry, prefix) => {
|
const applyProgress = (entry, prefixes, relRoot) => {
|
||||||
if (!entry) return;
|
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) {
|
if (matched.length) {
|
||||||
const bytes = matched.reduce((sum, t) => sum + (Number(t.bytes) || 0), 0);
|
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;
|
const pct = matched.reduce((sum, t) => sum + (Number(t.percentage) || 0), 0) / matched.length;
|
||||||
@@ -859,8 +864,14 @@ function updateMoveProgressFromStats(stats) {
|
|||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Transfer görünmüyorsa queued kalır; done kararı aşağıda verilecek.
|
const gdriveTarget = relRoot ? path.join(GDRIVE_ROOT, relRoot) : null;
|
||||||
if (entry.moveStatus === "uploading") {
|
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";
|
entry.moveStatus = "queued";
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
@@ -868,15 +879,29 @@ function updateMoveProgressFromStats(stats) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const entry of torrents.values()) {
|
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()) {
|
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()) {
|
for (const job of mailruJobs.values()) {
|
||||||
const folderPrefix = job.folderId ? `${RCLONE_REMOTE_PATH}/${job.folderId}` : null;
|
const relRoot = job.folderId || "";
|
||||||
if (folderPrefix) {
|
const prefixes = [
|
||||||
applyProgress(job, folderPrefix);
|
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;
|
if (!interval || interval <= 0) return;
|
||||||
rcloneCacheCleanTimer = setInterval(() => {
|
rcloneCacheCleanTimer = setInterval(() => {
|
||||||
if (!RCLONE_RC_ENABLED) return;
|
if (!RCLONE_RC_ENABLED) return;
|
||||||
fetch(`http://${RCLONE_RC_ADDR}/vfs/forget`, {
|
fetch(`http://${RCLONE_RC_ADDR}/vfs/refresh`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ path: "", recursive: true })
|
body: JSON.stringify({ recursive: true })
|
||||||
})
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (resp.status === 404) {
|
if (resp.status === 404) {
|
||||||
return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, {
|
return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/refresh`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ path: "", recursive: true })
|
body: JSON.stringify({ recursive: true })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
@@ -1032,16 +1057,16 @@ async function runRcloneCacheClean() {
|
|||||||
const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed);
|
const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed);
|
||||||
try {
|
try {
|
||||||
if (wasRunning && RCLONE_RC_ENABLED) {
|
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",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ path: "", recursive: true })
|
body: JSON.stringify({ recursive: true })
|
||||||
});
|
});
|
||||||
if (resp.status === 404) {
|
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",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ path: "", recursive: true })
|
body: JSON.stringify({ recursive: true })
|
||||||
});
|
});
|
||||||
if (!fallback.ok) {
|
if (!fallback.ok) {
|
||||||
const body = await fallback.text();
|
const body = await fallback.text();
|
||||||
@@ -1194,8 +1219,16 @@ async function moveRootFolderToGdrive(rootFolder) {
|
|||||||
if (!fs.existsSync(sourceDir)) {
|
if (!fs.existsSync(sourceDir)) {
|
||||||
return { ok: false, error: "Kaynak root bulunamadı" };
|
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)) {
|
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);
|
const targetDir = path.join(GDRIVE_ROOT, safeRoot);
|
||||||
if (fs.existsSync(targetDir)) {
|
if (fs.existsSync(targetDir)) {
|
||||||
@@ -1228,6 +1261,17 @@ async function movePathToGdrive(relPath) {
|
|||||||
if (!safeRel) return { ok: false, error: "Geçersiz yol" };
|
if (!safeRel) return { ok: false, error: "Geçersiz yol" };
|
||||||
const sourceFile = path.join(DOWNLOAD_DIR, safeRel);
|
const sourceFile = path.join(DOWNLOAD_DIR, safeRel);
|
||||||
if (fs.existsSync(sourceFile) && fs.statSync(sourceFile).isFile()) {
|
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);
|
const targetFile = path.join(GDRIVE_ROOT, safeRel);
|
||||||
ensureDirForFile(targetFile);
|
ensureDirForFile(targetFile);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user