Changed traits

This commit is contained in:
daladim 2021-03-29 23:46:21 +02:00
parent b54fe5e228
commit 0158cfb2d4
4 changed files with 63 additions and 37 deletions

View file

@ -50,10 +50,6 @@ impl BaseCalendar for CachedCalendar {
self.items.insert(item.id().clone(), item); self.items.insert(item.id().clone(), item);
Ok(()) Ok(())
} }
async fn get_item_by_id<'a>(&'a self, id: &ItemId) -> Option<&'a Item> {
self.items.get(id)
}
} }
#[async_trait] #[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> { async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item> {
self.items.get_mut(id) self.items.get_mut(id)
} }

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use async_trait::async_trait; use async_trait::async_trait;
use reqwest::header::CONTENT_TYPE;
use crate::traits::BaseCalendar; use crate::traits::BaseCalendar;
use crate::traits::DavCalendar; use crate::traits::DavCalendar;
@ -10,6 +11,7 @@ use crate::calendar::CalendarId;
use crate::item::Item; use crate::item::Item;
use crate::item::ItemId; use crate::item::ItemId;
use crate::item::VersionTag; use crate::item::VersionTag;
use crate::item::SyncStatus;
use crate::resource::Resource; use crate::resource::Resource;
static TASKS_BODY: &str = r#" static TASKS_BODY: &str = r#"
@ -33,7 +35,7 @@ static TASKS_BODY: &str = r#"
pub struct RemoteCalendar { pub struct RemoteCalendar {
name: String, name: String,
resource: Resource, resource: Resource,
supported_components: SupportedComponents supported_components: SupportedComponents,
} }
impl RemoteCalendar { impl RemoteCalendar {
@ -56,11 +58,6 @@ impl BaseCalendar for RemoteCalendar {
async fn add_item(&mut self, _item: Item) -> Result<(), Box<dyn Error>> { async fn add_item(&mut self, _item: Item) -> Result<(), Box<dyn Error>> {
Err("Not implemented".into()) 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] #[async_trait]
@ -98,6 +95,20 @@ impl DavCalendar for RemoteCalendar {
Ok(items) Ok(items)
} }
async fn get_item_by_id(&self, id: &ItemId) -> Result<Option<Item>, Box<dyn Error>> {
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<dyn Error>> { async fn delete_item(&mut self, _item_id: &ItemId) -> Result<(), Box<dyn Error>> {
log::error!("Not implemented"); log::error!("Not implemented");
Ok(()) Ok(())

View file

@ -80,7 +80,7 @@ where
let mut local_items_to_handle = cal_local.get_item_ids().await?; let mut local_items_to_handle = cal_local.get_item_ids().await?;
for (id, remote_tag) in remote_items { for (id, remote_tag) in remote_items {
log::trace!("* Considering remote item {}...", id); 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 => { None => {
// This was created on the remote // This was created on the remote
log::debug!("* {} is a remote addition", id); log::debug!("* {} is a remote addition", id);
@ -133,13 +133,14 @@ where
// Also iterate on the local tasks that are not on the remote // Also iterate on the local tasks that are not on the remote
for id in local_items_to_handle { for id in local_items_to_handle {
log::trace!("# Considering local item {}...", id); 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 => { None => {
log::error!("Inconsistent state: missing task {} from the local tasks", id); log::error!("Inconsistent state: missing task {} from the local tasks", id);
continue; continue;
}, },
Some(item) => item, Some(item) => item,
}; };
match local_item.sync_status() { match local_item.sync_status() {
SyncStatus::Synced(_) => { SyncStatus::Synced(_) => {
// This item has been removed from the remote // 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); log::info!("Conflict: item {} has been deleted from the server and locally modified. Deleting the local copy", id);
remote_del.insert(id); remote_del.insert(id);
}, },
}
} }
}
// Step 2 - commit changes // Step 2 - commit changes
@ -169,7 +170,7 @@ where
log::debug!("> Pushing local deletion {} to the server", id_del); log::debug!("> Pushing local deletion {} to the server", id_del);
match cal_remote.delete_item(&id_del).await { match cal_remote.delete_item(&id_del).await {
Err(err) => { Err(err) => {
log::warn!("Unable to delete remote item {}: {}", id_del, err); log::warn!("Unable to delete remote item {}: {}", id_del, err);
}, },
Ok(()) => { Ok(()) => {
// Change the local copy from "marked to deletion" to "actually deleted" // Change the local copy from "marked to deletion" to "actually deleted"
@ -190,14 +191,20 @@ where
for id_add in remote_additions { for id_add in remote_additions {
log::debug!("> Applying remote addition {} locally", id_add); log::debug!("> Applying remote addition {} locally", id_add);
match cal_remote.get_item_by_id(&id_add).await { match cal_remote.get_item_by_id(&id_add).await {
None => { Err(err) => {
log::error!("Inconsistency: new item {} has vanished from the remote end", id_add); log::warn!("Unable to get remote item {}: {}. Skipping it.", id, err);
continue; continue;
}, },
Some(new_item) => { Ok(item) => match item {
if let Err(err) = cal_local.add_item(new_item.clone()).await { None => {
log::error!("Not able to add item {} to local calendar: {}", id_add, err); 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 { for id_change in remote_changes {
log::debug!("> Applying remote change {} locally", id_change); log::debug!("> Applying remote change {} locally", id_change);
match cal_remote.get_item_by_id(&id_change).await { match cal_remote.get_item_by_id(&id_change).await {
None => { Err(err) => {
log::error!("Inconsistency: modified item {} has vanished from the remote end", id_change); log::warn!("Unable to get remote item {}: {}. Skippin it", id, err);
continue; continue;
}, },
Some(item) => { Ok(item) => match item {
if let Err(err) = cal_local.immediately_delete_item(&id_change).await { None => {
log::error!("Unable to delete item {} from local calendar: {}", id_change, err); log::error!("Inconsistency: modified item {} has vanished from the remote end", id_change);
} continue;
if let Err(err) = cal_local.add_item(item.clone()).await { },
log::error!("Unable to add item {} to local calendar: {}", id_change, err); 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 { for id_add in local_additions {
log::debug!("> Pushing local addition {} to the server", id_add); 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 => { None => {
log::error!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add); log::error!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add);
continue; continue;
@ -232,13 +245,13 @@ where
if let Err(err) = cal_remote.add_item(item.clone()).await { if let Err(err) = cal_remote.add_item(item.clone()).await {
log::error!("Unable to add item {} to remote calendar: {}", id_add, err); log::error!("Unable to add item {} to remote calendar: {}", id_add, err);
} }
} },
}; };
} }
for id_change in local_changes { for id_change in local_changes {
log::debug!("> Pushing local change {} to the server", id_change); 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 => { None => {
log::error!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change); log::error!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change);
continue; continue;

View file

@ -33,10 +33,6 @@ pub trait BaseCalendar {
/// Add an item into this calendar /// Add an item into this calendar
async fn add_item(&mut self, item: Item) -> Result<(), Box<dyn Error>>; async fn add_item(&mut self, item: Item) -> Result<(), Box<dyn Error>>;
/// 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 /// Returns whether this calDAV calendar supports to-do items
fn supports_todo(&self) -> bool { fn supports_todo(&self) -> bool {
self.supported_components().contains(crate::calendar::SupportedComponents::TODO) self.supported_components().contains(crate::calendar::SupportedComponents::TODO)
@ -65,6 +61,9 @@ pub trait DavCalendar : BaseCalendar {
.map(|(id, _tag)| id.clone()) .map(|(id, _tag)| id.clone())
.collect()) .collect())
} }
/// Returns a particular item
async fn get_item_by_id(&self, id: &ItemId) -> Result<Option<Item>, Box<dyn Error>>;
} }
@ -79,6 +78,9 @@ pub trait CompleteCalendar : BaseCalendar {
/// Returns all items that this calendar contains /// Returns all items that this calendar contains
async fn get_items(&self) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>>; async fn get_items(&self) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>>;
/// Returns a particular item
async fn get_item_by_id_ref<'a>(&'a self, id: &ItemId) -> Option<&'a Item>;
/// Returns a particular item /// Returns a particular item
async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item>; async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item>;