fix: Virtual Mode laedt neue lokale Dateien jetzt hoch
Problem: Im Virtual Mode wurden nur .cloud Platzhalter fuer Server-Dateien erstellt, aber neue lokale Dateien wurden nie hochgeladen. Der Watcher hat die Aenderung erkannt aber der Sync hat sie ignoriert. Fix: sync_upload_new() wird jetzt auch im Virtual Mode aufgerufen. Scannt den lokalen Ordner nach Dateien die auf dem Server nicht existieren und laedt sie hoch. Auch geaenderte lokale Dateien (Checksum-Vergleich) werden aktualisiert. Gesperrte Dateien werden zurueckgehalten. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
607d18a7e2
commit
81574c8991
|
|
@ -67,6 +67,8 @@ impl SyncEngine {
|
|||
match sp.mode {
|
||||
SyncMode::Virtual => {
|
||||
self.sync_virtual(&entries, &local_dir, &sp.server_path, &mut log).await;
|
||||
// Also upload new local files (not on server yet)
|
||||
self.sync_upload_new(&entries, &local_dir, sp.server_folder_id, &mut log).await;
|
||||
}
|
||||
SyncMode::Full => {
|
||||
self.sync_full_download(&entries, &local_dir, &mut log).await;
|
||||
|
|
@ -147,6 +149,72 @@ impl SyncEngine {
|
|||
}
|
||||
}
|
||||
|
||||
/// Upload new local files that don't exist on server yet (for both Virtual + Full mode)
|
||||
async fn sync_upload_new(&self, server_entries: &[FileEntry], local_dir: &Path,
|
||||
parent_id: Option<i64>, log: &mut Vec<String>) {
|
||||
let server_names: std::collections::HashSet<String> = server_entries.iter()
|
||||
.map(|e| e.name.clone()).collect();
|
||||
|
||||
let entries = match std::fs::read_dir(local_dir) {
|
||||
Ok(e) => e,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
for entry in entries.flatten() {
|
||||
let name = entry.file_name().to_string_lossy().to_string();
|
||||
let path = entry.path();
|
||||
|
||||
// Skip hidden, temp, .cloud files
|
||||
if name.starts_with('.') || name.starts_with('~')
|
||||
|| name.ends_with(".tmp") || name.ends_with(".cloud") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if path.is_dir() {
|
||||
// New folder: create on server + recurse
|
||||
if !server_names.contains(&name) {
|
||||
match self.api.create_folder(&name, parent_id).await {
|
||||
Ok(folder) => {
|
||||
log.push(format!("Ordner erstellt: {}", name));
|
||||
Box::pin(self.sync_upload_new(&[], &path, Some(folder.id), log)).await;
|
||||
}
|
||||
Err(e) => log.push(format!("Ordner-Fehler {}: {}", name, e)),
|
||||
}
|
||||
} else {
|
||||
// Existing folder: recurse into it
|
||||
let sub = server_entries.iter().find(|e| e.name == name);
|
||||
let children = sub.and_then(|e| e.children.as_ref())
|
||||
.map(|c| c.as_slice()).unwrap_or(&[]);
|
||||
let sub_id = sub.map(|e| e.id);
|
||||
Box::pin(self.sync_upload_new(children, &path, sub_id, log)).await;
|
||||
}
|
||||
} else {
|
||||
// New file: upload
|
||||
if !server_names.contains(&name) {
|
||||
match self.api.upload_file(&path, parent_id).await {
|
||||
Ok(_) => log.push(format!("Hochgeladen: {}", name)),
|
||||
Err(e) => log.push(format!("Upload-Fehler {}: {}", name, e)),
|
||||
}
|
||||
} else {
|
||||
// Existing file: check if changed (checksum compare)
|
||||
if let Some(se) = server_entries.iter().find(|e| e.name == name) {
|
||||
if !se.locked.unwrap_or(false) {
|
||||
let local_hash = compute_file_hash(&path);
|
||||
if local_hash != se.checksum.as_deref().unwrap_or("") {
|
||||
match self.api.upload_file(&path, parent_id).await {
|
||||
Ok(_) => log.push(format!("Aktualisiert: {}", name)),
|
||||
Err(e) => log.push(format!("Upload-Fehler {}: {}", name, e)),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.push(format!("Zurueckgehalten (gesperrt): {}", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Full sync: download all files from server
|
||||
async fn sync_full_download(&self, entries: &[FileEntry], local_dir: &Path,
|
||||
log: &mut Vec<String>) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue