This commit is contained in:
Timothy Jaeryang Baek
2026-05-20 01:39:22 +04:00
parent 97252fa609
commit 8f2d346e10
2 changed files with 24 additions and 17 deletions
+7
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import asyncio
import io
import logging
import zipfile
@@ -1007,6 +1008,7 @@ class SyncDiffResponse(BaseModel):
mkdir: list[str] # directory paths to create
rmdir: list[str] # directory IDs to remove
unmodified_count: int
directory_map: dict[str, str] # existing path → directory ID
@router.post('/{id}/sync/diff', response_model=SyncDiffResponse)
@@ -1101,6 +1103,7 @@ async def sync_knowledge_diff(
mkdir=mkdir,
rmdir=rmdir,
unmodified_count=unmodified_count,
directory_map=directory_id_by_path,
)
@@ -1154,6 +1157,10 @@ async def sync_knowledge_cleanup(
if file.user_id == user.id or user.role == 'admin':
await Files.delete_file_by_id(file_id, db=db)
try:
await asyncio.to_thread(Storage.delete_file, file.path)
except Exception:
pass
# ── Remove orphaned directories (children before parents) ──
for dir_id in reversed(form_data.dir_ids):
@@ -651,13 +651,24 @@
return;
}
// ── 4. mkdir — create missing directories (parents first) ──
const createdDirectoryIds: Record<string, string> = {};
// ── 4. Cleanup — remove deleted + stale modified files first ──
const staleFileIds = [
...diff.deleted.map((d: any) => d.file_id),
...diff.modified.map((m: any) => m.stale_file_id)
];
if (staleFileIds.length > 0 || diff.rmdir.length > 0) {
syncing = $i18n.t('Removing {{count}} stale files...', { count: staleFileIds.length });
await syncKnowledgeCleanup(localStorage.token, id, staleFileIds, diff.rmdir);
}
// ── 5. mkdir — create missing directories (parents first) ──
const directoryIdByPath: Record<string, string> = { ...(diff.directory_map || {}) };
for (const dirPath of diff.mkdir) {
const segments = dirPath.split('/');
const name = segments.at(-1)!;
const parentPath = segments.slice(0, -1).join('/');
const parentId = parentPath ? createdDirectoryIds[parentPath] : null;
const parentId = parentPath ? directoryIdByPath[parentPath] : null;
const directory = await createKnowledgeDirectory(
localStorage.token,
@@ -666,11 +677,11 @@
parentId
);
if (directory) {
createdDirectoryIds[dirPath] = directory.id;
directoryIdByPath[dirPath] = directory.id;
}
}
// ── 5. Upload added + modified files ──
// ── 6. Upload added + modified files ──
const filesToUpload = manifest.filter(
(entry) =>
diff.added.some((a: any) => a.filename === entry.filename && a.path === entry.path) ||
@@ -691,21 +702,10 @@
await uploadFile(localStorage.token, fileObject, {
knowledge_id: knowledge.id,
file_hash: entry.checksum,
directory_id: entry.path ? createdDirectoryIds[entry.path] : null
directory_id: entry.path ? directoryIdByPath[entry.path] : null
}).catch(() => null);
}
// ── 6. Cleanup — remove deleted files + rmdir orphaned directories ──
const staleFileIds = [
...diff.deleted.map((d: any) => d.file_id),
...diff.modified.map((m: any) => m.stale_file_id)
];
if (staleFileIds.length > 0 || diff.rmdir.length > 0) {
syncing = $i18n.t('Removing {{count}} stale files...', { count: staleFileIds.length });
await syncKnowledgeCleanup(localStorage.token, id, staleFileIds, diff.rmdir);
}
// ── 7. Report ──
toast.success(
$i18n.t(