fix: Server->Client Sync + File Locking repariert

Server->Client Sync:
- Server sendet Timestamps ohne Timezone (2026-04-11T12:49:24.735436)
- parse_from_rfc3339 braucht Timezone -> schlug still fehl
- Client dachte IMMER er sei neuer -> Upload statt Download
- Fix: parse_server_time() akzeptiert beides (mit/ohne Timezone)
- Probiert RFC3339, dann NaiveDateTime mit Microseconds, dann ohne

File Locking:
- open_cloud_file nutzte API-Clone vom SyncEngine (evtl. alter Token)
- Jetzt direkt state.api (immer aktueller Token nach Refresh)
- Lock wird zuverlaessig gesetzt beim Oeffnen von .cloud Dateien

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker
2026-04-12 02:05:10 +02:00
parent a445256d86
commit b3da50e6ce
2 changed files with 22 additions and 8 deletions
+20 -4
View File
@@ -109,8 +109,7 @@ impl SyncEngine {
let local_modified = std::fs::metadata(&local_path)
.and_then(|m| m.modified()).ok();
let server_modified = entry.updated_at.as_deref()
.and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok())
.map(|dt| std::time::SystemTime::from(dt));
.and_then(parse_server_time);
let server_is_newer = match (local_modified, server_modified) {
(Some(lt), Some(st)) => st > lt,
@@ -344,8 +343,7 @@ impl SyncEngine {
let local_modified = std::fs::metadata(&path)
.and_then(|m| m.modified()).ok();
let server_modified = se.updated_at.as_deref()
.and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok())
.map(|dt| std::time::SystemTime::from(dt));
.and_then(parse_server_time);
let server_is_newer = match (local_modified, server_modified) {
(Some(lt), Some(st)) => st > lt,
@@ -448,6 +446,24 @@ fn find_subtree(tree: &[FileEntry], folder_id: i64) -> Option<Vec<FileEntry>> {
None
}
/// Parse a server timestamp (may or may not have timezone)
fn parse_server_time(s: &str) -> Option<std::time::SystemTime> {
// Try with timezone first (RFC3339)
if let Ok(dt) = chrono::DateTime::parse_from_rfc3339(s) {
return Some(std::time::SystemTime::from(dt));
}
// Try without timezone (naive, assume UTC)
if let Ok(dt) = chrono::NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f") {
let utc = dt.and_utc();
return Some(std::time::SystemTime::from(utc));
}
if let Ok(dt) = chrono::NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S") {
let utc = dt.and_utc();
return Some(std::time::SystemTime::from(utc));
}
None
}
pub fn compute_file_hash(path: &Path) -> String {
let data = match std::fs::read(path) {
Ok(d) => d,