From 0158cfb2d44a602723e6c6636df8b541c75ca6cf Mon Sep 17 00:00:00 2001 From: daladim Date: Mon, 29 Mar 2021 23:46:21 +0200 Subject: [PATCH] Changed traits --- src/calendar/cached_calendar.rs | 8 ++--- src/calendar/remote_calendar.rs | 23 +++++++++---- src/provider.rs | 59 ++++++++++++++++++++------------- src/traits.rs | 10 +++--- 4 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/calendar/cached_calendar.rs b/src/calendar/cached_calendar.rs index 9ad62c0..36604c1 100644 --- a/src/calendar/cached_calendar.rs +++ b/src/calendar/cached_calendar.rs @@ -50,10 +50,6 @@ impl BaseCalendar for CachedCalendar { self.items.insert(item.id().clone(), item); Ok(()) } - - async fn get_item_by_id<'a>(&'a self, id: &ItemId) -> Option<&'a Item> { - self.items.get(id) - } } #[async_trait] @@ -72,6 +68,10 @@ impl CompleteCalendar for CachedCalendar { ) } + async fn get_item_by_id_ref<'a>(&'a self, id: &ItemId) -> Option<&'a Item> { + self.items.get(id) + } + async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item> { self.items.get_mut(id) } diff --git a/src/calendar/remote_calendar.rs b/src/calendar/remote_calendar.rs index b8d3ec0..1d9ab9c 100644 --- a/src/calendar/remote_calendar.rs +++ b/src/calendar/remote_calendar.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::error::Error; use async_trait::async_trait; +use reqwest::header::CONTENT_TYPE; use crate::traits::BaseCalendar; use crate::traits::DavCalendar; @@ -10,6 +11,7 @@ use crate::calendar::CalendarId; use crate::item::Item; use crate::item::ItemId; use crate::item::VersionTag; +use crate::item::SyncStatus; use crate::resource::Resource; static TASKS_BODY: &str = r#" @@ -33,7 +35,7 @@ static TASKS_BODY: &str = r#" pub struct RemoteCalendar { name: String, resource: Resource, - supported_components: SupportedComponents + supported_components: SupportedComponents, } impl RemoteCalendar { @@ -56,11 +58,6 @@ impl BaseCalendar for RemoteCalendar { async fn add_item(&mut self, _item: Item) -> Result<(), Box> { Err("Not implemented".into()) } - - async fn get_item_by_id<'a>(&'a self, id: &ItemId) -> Option<&'a Item> { - log::error!("Not implemented"); - None - } } #[async_trait] @@ -98,6 +95,20 @@ impl DavCalendar for RemoteCalendar { Ok(items) } + async fn get_item_by_id(&self, id: &ItemId) -> Result, Box> { + let res = reqwest::Client::new() + .get(id.as_url().clone()) + .header(CONTENT_TYPE, "text/calendar") + .basic_auth(self.resource.username(), Some(self.resource.password())) + .send() + .await?; + + let text = res.text().await?; + + let item = crate::ical::parse(&text, id.clone(), SyncStatus::Synced())?; + Ok(Some(item)) + } + async fn delete_item(&mut self, _item_id: &ItemId) -> Result<(), Box> { log::error!("Not implemented"); Ok(()) diff --git a/src/provider.rs b/src/provider.rs index 7a89e38..c25592b 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -80,7 +80,7 @@ where let mut local_items_to_handle = cal_local.get_item_ids().await?; for (id, remote_tag) in remote_items { log::trace!("* Considering remote item {}...", id); - match cal_local.get_item_by_id(&id).await { + match cal_local.get_item_by_id_ref(&id).await { None => { // This was created on the remote log::debug!("* {} is a remote addition", id); @@ -133,13 +133,14 @@ where // Also iterate on the local tasks that are not on the remote for id in local_items_to_handle { log::trace!("# Considering local item {}...", id); - let local_item = match cal_local.get_item_by_id(&id).await { + let local_item = match cal_local.get_item_by_id_ref(&id).await { None => { log::error!("Inconsistent state: missing task {} from the local tasks", id); continue; }, Some(item) => item, }; + match local_item.sync_status() { SyncStatus::Synced(_) => { // This item has been removed from the remote @@ -160,8 +161,8 @@ where log::info!("Conflict: item {} has been deleted from the server and locally modified. Deleting the local copy", id); remote_del.insert(id); }, - } } + } // Step 2 - commit changes @@ -169,7 +170,7 @@ where log::debug!("> Pushing local deletion {} to the server", id_del); match cal_remote.delete_item(&id_del).await { Err(err) => { - log::warn!("Unable to delete remote item {}: {}", id_del, err); + log::warn!("Unable to delete remote item {}: {}", id_del, err); }, Ok(()) => { // Change the local copy from "marked to deletion" to "actually deleted" @@ -190,14 +191,20 @@ where for id_add in remote_additions { log::debug!("> Applying remote addition {} locally", id_add); match cal_remote.get_item_by_id(&id_add).await { - None => { - log::error!("Inconsistency: new item {} has vanished from the remote end", id_add); + Err(err) => { + log::warn!("Unable to get remote item {}: {}. Skipping it.", id, err); continue; }, - Some(new_item) => { - if let Err(err) = cal_local.add_item(new_item.clone()).await { - log::error!("Not able to add item {} to local calendar: {}", id_add, err); - } + Ok(item) => match item { + None => { + log::error!("Inconsistency: new item {} has vanished from the remote end", id_add); + continue; + }, + Some(new_item) => { + if let Err(err) = cal_local.add_item(new_item.clone()).await { + log::error!("Not able to add item {} to local calendar: {}", id_add, err); + } + }, }, } } @@ -205,25 +212,31 @@ where for id_change in remote_changes { log::debug!("> Applying remote change {} locally", id_change); match cal_remote.get_item_by_id(&id_change).await { - None => { - log::error!("Inconsistency: modified item {} has vanished from the remote end", id_change); + Err(err) => { + log::warn!("Unable to get remote item {}: {}. Skippin it", id, err); continue; }, - Some(item) => { - if let Err(err) = cal_local.immediately_delete_item(&id_change).await { - log::error!("Unable to delete item {} from local calendar: {}", id_change, err); - } - if let Err(err) = cal_local.add_item(item.clone()).await { - log::error!("Unable to add item {} to local calendar: {}", id_change, err); - } - }, + Ok(item) => match item { + None => { + log::error!("Inconsistency: modified item {} has vanished from the remote end", id_change); + continue; + }, + Some(item) => { + if let Err(err) = cal_local.immediately_delete_item(&id_change).await { + log::error!("Unable to delete item {} from local calendar: {}", id_change, err); + } + if let Err(err) = cal_local.add_item(item.clone()).await { + log::error!("Unable to add item {} to local calendar: {}", id_change, err); + } + }, + } } } for id_add in local_additions { log::debug!("> Pushing local addition {} to the server", id_add); - match cal_local.get_item_by_id(&id_add).await { + match cal_local.get_item_by_id_ref(&id_add).await { None => { log::error!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add); continue; @@ -232,13 +245,13 @@ where if let Err(err) = cal_remote.add_item(item.clone()).await { log::error!("Unable to add item {} to remote calendar: {}", id_add, err); } - } + }, }; } for id_change in local_changes { log::debug!("> Pushing local change {} to the server", id_change); - match cal_local.get_item_by_id(&id_change).await { + match cal_local.get_item_by_id_ref(&id_change).await { None => { log::error!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change); continue; diff --git a/src/traits.rs b/src/traits.rs index 83e67f0..881a19a 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -33,10 +33,6 @@ pub trait BaseCalendar { /// Add an item into this calendar async fn add_item(&mut self, item: Item) -> Result<(), Box>; - /// Returns a particular item - async fn get_item_by_id<'a>(&'a self, id: &ItemId) -> Option<&'a Item>; - - /// Returns whether this calDAV calendar supports to-do items fn supports_todo(&self) -> bool { self.supported_components().contains(crate::calendar::SupportedComponents::TODO) @@ -65,6 +61,9 @@ pub trait DavCalendar : BaseCalendar { .map(|(id, _tag)| id.clone()) .collect()) } + + /// Returns a particular item + async fn get_item_by_id(&self, id: &ItemId) -> Result, Box>; } @@ -79,6 +78,9 @@ pub trait CompleteCalendar : BaseCalendar { /// Returns all items that this calendar contains async fn get_items(&self) -> Result, Box>; + /// Returns a particular item + async fn get_item_by_id_ref<'a>(&'a self, id: &ItemId) -> Option<&'a Item>; + /// Returns a particular item async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item>;