diff options
author | Quentin Dufour <quentin@deuxfleurs.fr> | 2024-05-28 17:21:30 +0200 |
---|---|---|
committer | Quentin Dufour <quentin@deuxfleurs.fr> | 2024-05-28 17:21:30 +0200 |
commit | a2f5b451bd32780d60be69c6412cb351a54b765b (patch) | |
tree | dc8dc26889d9f447dffd1b2f0968c348386cfcd7 /aero-proto/src/dav/resource.rs | |
parent | 18f2154151b2cf81e03bdda28fa2ea5d685e33d1 (diff) | |
download | aerogramme-caldav.tar.gz aerogramme-caldav.zip |
initial implementation of sync-collectioncaldav
Diffstat (limited to 'aero-proto/src/dav/resource.rs')
-rw-r--r-- | aero-proto/src/dav/resource.rs | 96 |
1 files changed, 93 insertions, 3 deletions
diff --git a/aero-proto/src/dav/resource.rs b/aero-proto/src/dav/resource.rs index 1ae766c..297a1c1 100644 --- a/aero-proto/src/dav/resource.rs +++ b/aero-proto/src/dav/resource.rs @@ -8,7 +8,7 @@ use futures::{future::BoxFuture, future::FutureExt}; use aero_collections::{ calendar::Calendar, - davdag::{BlobId, Etag}, + davdag::{BlobId, Etag, SyncChange, Token}, user::User, }; use aero_dav::acltypes as acl; @@ -21,6 +21,8 @@ use aero_dav::versioningtypes as vers; use super::node::PropertyStream; use crate::dav::node::{Content, DavNode, PutPolicy}; +pub const BASE_TOKEN_URI: &str = "https://aerogramme.0/sync/"; + #[derive(Clone)] pub(crate) struct RootNode {} impl DavNode for RootNode { @@ -117,6 +119,16 @@ impl DavNode for RootNode { fn delete(&self) -> BoxFuture<std::result::Result<(), std::io::Error>> { async { Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied)) }.boxed() } + + fn diff<'a>( + &self, + _sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + async { Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) }.boxed() + } } #[derive(Clone)] @@ -229,6 +241,15 @@ impl DavNode for HomeNode { fn delete(&self) -> BoxFuture<std::result::Result<(), std::io::Error>> { async { Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied)) }.boxed() } + fn diff<'a>( + &self, + _sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + async { Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) }.boxed() + } } #[derive(Clone)] @@ -353,6 +374,15 @@ impl DavNode for CalendarListNode { fn delete(&self) -> BoxFuture<std::result::Result<(), std::io::Error>> { async { Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied)) }.boxed() } + fn diff<'a>( + &self, + _sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + async { Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) }.boxed() + } } #[derive(Clone)] @@ -480,8 +510,8 @@ impl DavNode for CalendarNode { )) => match col.token().await { Ok(token) => dav::Property::Extension(all::Property::Sync( sync::Property::SyncToken(sync::SyncToken(format!( - "https://aerogramme.0/sync/{}", - token + "{}{}", + BASE_TOKEN_URI, token ))), )), _ => return Err(n.clone()), @@ -535,6 +565,48 @@ impl DavNode for CalendarNode { fn delete(&self) -> BoxFuture<std::result::Result<(), std::io::Error>> { async { Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied)) }.boxed() } + fn diff<'a>( + &self, + sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + let col = self.col.clone(); + let calname = self.calname.clone(); + async move { + let sync_token = sync_token.unwrap(); + let (new_token, listed_changes) = match col.diff(sync_token).await { + Ok(v) => v, + Err(e) => { + tracing::info!(err=?e, "token resolution failed, maybe a forgotten token"); + return Err(std::io::Error::from(std::io::ErrorKind::NotFound)); + } + }; + + let mut ok_nodes: Vec<Box<dyn DavNode>> = vec![]; + let mut rm_nodes: Vec<dav::Href> = vec![]; + for change in listed_changes.into_iter() { + match change { + SyncChange::Ok((filename, blob_id)) => { + let child = Box::new(EventNode { + col: col.clone(), + calname: calname.clone(), + filename, + blob_id, + }); + ok_nodes.push(child); + } + SyncChange::NotFound(filename) => { + rm_nodes.push(dav::Href(filename)); + } + } + } + + Ok((new_token, ok_nodes, rm_nodes)) + } + .boxed() + } } #[derive(Clone)] @@ -757,6 +829,15 @@ impl DavNode for EventNode { } .boxed() } + fn diff<'a>( + &self, + _sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + async { Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) }.boxed() + } } #[derive(Clone)] @@ -849,4 +930,13 @@ impl DavNode for CreateEventNode { // Nothing to delete async { Ok(()) }.boxed() } + fn diff<'a>( + &self, + _sync_token: Option<Token>, + ) -> BoxFuture< + 'a, + std::result::Result<(Token, Vec<Box<dyn DavNode>>, Vec<dav::Href>), std::io::Error>, + > { + async { Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) }.boxed() + } } |