Implemented pulling new calendars from server
This commit is contained in:
parent
0b65dff46d
commit
401099ed33
6 changed files with 55 additions and 34 deletions
|
@ -1,4 +1,3 @@
|
||||||
/*
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use my_tasks::{client::Client, traits::CalDavSource};
|
use my_tasks::{client::Client, traits::CalDavSource};
|
||||||
|
@ -8,31 +7,33 @@ use my_tasks::settings::URL;
|
||||||
use my_tasks::settings::USERNAME;
|
use my_tasks::settings::USERNAME;
|
||||||
use my_tasks::settings::PASSWORD;
|
use my_tasks::settings::PASSWORD;
|
||||||
|
|
||||||
const CACHE_FILE: &str = "caldav_cache.json";
|
const CACHE_FOLDER: &str = "example_cache";
|
||||||
*/
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
/*
|
env_logger::init();
|
||||||
let cache_path = Path::new(CACHE_FILE);
|
|
||||||
|
|
||||||
let mut client = Client::new(URL, USERNAME, PASSWORD).unwrap();
|
let cache_path = Path::new(CACHE_FOLDER);
|
||||||
let mut cache = match Cache::from_file(&cache_path) {
|
|
||||||
|
let client = Client::new(URL, USERNAME, PASSWORD).unwrap();
|
||||||
|
let cache = match Cache::from_folder(&cache_path) {
|
||||||
Ok(cache) => cache,
|
Ok(cache) => cache,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::warn!("Invalid cache file: {}. Using a default cache", err);
|
log::warn!("Invalid cache file: {}. Using a default cache", err);
|
||||||
Cache::new(&cache_path)
|
Cache::new(&cache_path)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let provider = Provider::new(client, cache);
|
let mut provider = Provider::new(client, cache);
|
||||||
|
|
||||||
let cals = provider.local().get_calendars().await.unwrap();
|
let cals = provider.local().get_calendars().await.unwrap();
|
||||||
println!("---- before sync -----");
|
println!("---- before sync -----");
|
||||||
my_tasks::utils::print_calendar_list(cals);
|
my_tasks::utils::print_calendar_list(&cals).await;
|
||||||
|
|
||||||
provider.sync();
|
if let Err(err) = provider.sync().await {
|
||||||
|
log::error!("Unable to sync: {}", err);
|
||||||
|
}
|
||||||
println!("---- after sync -----");
|
println!("---- after sync -----");
|
||||||
my_tasks::utils::print_calendar_list(cals);
|
let cals = provider.local().get_calendars().await.unwrap();
|
||||||
*/
|
my_tasks::utils::print_calendar_list(&cals).await;
|
||||||
|
|
||||||
}
|
}
|
17
src/cache.rs
17
src/cache.rs
|
@ -116,11 +116,6 @@ impl Cache {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn add_calendar(&mut self, calendar: Arc<Mutex<CachedCalendar>>) {
|
|
||||||
let id = calendar.lock().unwrap().id().clone();
|
|
||||||
self.data.calendars.insert(id, calendar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compares two Caches to check they have the same current content
|
/// Compares two Caches to check they have the same current content
|
||||||
///
|
///
|
||||||
/// This is not a complete equality test: some attributes (last sync date, deleted items...) may differ
|
/// This is not a complete equality test: some attributes (last sync date, deleted items...) may differ
|
||||||
|
@ -187,6 +182,15 @@ impl CalDavSource<CachedCalendar> for Cache {
|
||||||
async fn get_calendar(&self, id: &CalendarId) -> Option<Arc<Mutex<CachedCalendar>>> {
|
async fn get_calendar(&self, id: &CalendarId) -> Option<Arc<Mutex<CachedCalendar>>> {
|
||||||
self.data.calendars.get(id).map(|arc| arc.clone())
|
self.data.calendars.get(id).map(|arc| arc.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn insert_calendar(&mut self, new_calendar: CachedCalendar) -> Result<(), Box<dyn Error>> {
|
||||||
|
let id = new_calendar.id().clone();
|
||||||
|
log::debug!("Inserting local calendar {}", id);
|
||||||
|
match self.data.calendars.insert(id, Arc::new(Mutex::new(new_calendar))) {
|
||||||
|
Some(_) => Err("Attempt to insert calendar failed: there is alredy such a calendar.".into()),
|
||||||
|
None => Ok(()) ,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -207,7 +211,8 @@ mod tests {
|
||||||
let cal1 = CachedCalendar::new("shopping list".to_string(),
|
let cal1 = CachedCalendar::new("shopping list".to_string(),
|
||||||
Url::parse("https://caldav.com/shopping").unwrap(),
|
Url::parse("https://caldav.com/shopping").unwrap(),
|
||||||
SupportedComponents::TODO);
|
SupportedComponents::TODO);
|
||||||
cache.add_calendar(Arc::new(Mutex::new(cal1)));
|
cache.insert_calendar(cal1).await.unwrap();
|
||||||
|
|
||||||
|
|
||||||
cache.save_to_folder().unwrap();
|
cache.save_to_folder().unwrap();
|
||||||
|
|
||||||
|
|
|
@ -21,16 +21,6 @@ pub struct CachedCalendar {
|
||||||
items: HashMap<ItemId, Item>,
|
items: HashMap<ItemId, Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachedCalendar {
|
|
||||||
/// Create a new calendar
|
|
||||||
pub fn new(name: String, id: CalendarId, supported_components: SupportedComponents) -> Self {
|
|
||||||
Self {
|
|
||||||
name, id, supported_components,
|
|
||||||
items: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl BaseCalendar for CachedCalendar {
|
impl BaseCalendar for CachedCalendar {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -54,6 +44,13 @@ impl BaseCalendar for CachedCalendar {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CompleteCalendar for CachedCalendar {
|
impl CompleteCalendar for CachedCalendar {
|
||||||
|
fn new(name: String, id: CalendarId, supported_components: SupportedComponents) -> Self {
|
||||||
|
Self {
|
||||||
|
name, id, supported_components,
|
||||||
|
items: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||||
Ok(self.items.iter()
|
Ok(self.items.iter()
|
||||||
.map(|(id, _)| id.clone())
|
.map(|(id, _)| id.clone())
|
||||||
|
|
|
@ -230,5 +230,9 @@ impl CalDavSource<RemoteCalendar> for Client {
|
||||||
.and_then(|cals| cals.get(id))
|
.and_then(|cals| cals.get(id))
|
||||||
.map(|cal| cal.clone())
|
.map(|cal| cal.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn insert_calendar(&mut self, new_calendar: RemoteCalendar) -> Result<(), Box<dyn Error>> {
|
||||||
|
Err("Not implemented".into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::marker::PhantomData;
|
||||||
use crate::traits::{CalDavSource, DavCalendar};
|
use crate::traits::{CalDavSource, DavCalendar};
|
||||||
use crate::traits::CompleteCalendar;
|
use crate::traits::CompleteCalendar;
|
||||||
use crate::item::SyncStatus;
|
use crate::item::SyncStatus;
|
||||||
|
use crate::calendar::SupportedComponents;
|
||||||
|
|
||||||
/// A data source that combines two `CalDavSources` (usually a server and a local cache), which is able to sync both sources.
|
/// A data source that combines two `CalDavSources` (usually a server and a local cache), which is able to sync both sources.
|
||||||
pub struct Provider<L, T, R, U>
|
pub struct Provider<L, T, R, U>
|
||||||
|
@ -58,13 +59,21 @@ where
|
||||||
for (id, cal_remote) in cals_remote {
|
for (id, cal_remote) in cals_remote {
|
||||||
let mut cal_remote = cal_remote.lock().unwrap();
|
let mut cal_remote = cal_remote.lock().unwrap();
|
||||||
|
|
||||||
let cal_local = match self.local.get_calendar(&id).await {
|
let cal_local = loop {
|
||||||
None => {
|
if let Some(cal) = self.local.get_calendar(&id).await {
|
||||||
log::error!("TODO: implement here");
|
break cal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This calendar does not exist locally yet, let's add it
|
||||||
|
log::error!("TODO: what name/SP should we choose?");
|
||||||
|
let new_calendar = T::new(String::from("new calendar"), id.clone(), SupportedComponents::TODO);
|
||||||
|
|
||||||
|
if let Err(err) = self.local.insert_calendar(new_calendar).await {
|
||||||
|
log::warn!("Unable to create local calendar {}: {}. Skipping it.", id, err);
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
Some(cal) => cal,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cal_local = cal_local.lock().unwrap();
|
let mut cal_local = cal_local.lock().unwrap();
|
||||||
|
|
||||||
// Step 1 - find the differences
|
// Step 1 - find the differences
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::item::Item;
|
||||||
use crate::item::ItemId;
|
use crate::item::ItemId;
|
||||||
use crate::item::VersionTag;
|
use crate::item::VersionTag;
|
||||||
use crate::calendar::CalendarId;
|
use crate::calendar::CalendarId;
|
||||||
|
use crate::calendar::SupportedComponents;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait CalDavSource<T: BaseCalendar> {
|
pub trait CalDavSource<T: BaseCalendar> {
|
||||||
|
@ -16,6 +17,8 @@ pub trait CalDavSource<T: BaseCalendar> {
|
||||||
async fn get_calendars(&self) -> Result<HashMap<CalendarId, Arc<Mutex<T>>>, Box<dyn Error>>;
|
async fn get_calendars(&self) -> Result<HashMap<CalendarId, Arc<Mutex<T>>>, Box<dyn Error>>;
|
||||||
/// Returns the calendar matching the ID
|
/// Returns the calendar matching the ID
|
||||||
async fn get_calendar(&self, id: &CalendarId) -> Option<Arc<Mutex<T>>>;
|
async fn get_calendar(&self, id: &CalendarId) -> Option<Arc<Mutex<T>>>;
|
||||||
|
/// Insert a calendar if it did not exist
|
||||||
|
async fn insert_calendar(&mut self, new_calendar: T) -> Result<(), Box<dyn Error>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This trait contains functions that are common to all calendars
|
/// This trait contains functions that are common to all calendars
|
||||||
|
@ -72,6 +75,8 @@ pub trait DavCalendar : BaseCalendar {
|
||||||
/// Usually, these are local calendars fully backed by a local folder
|
/// Usually, these are local calendars fully backed by a local folder
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait CompleteCalendar : BaseCalendar {
|
pub trait CompleteCalendar : BaseCalendar {
|
||||||
|
fn new(name: String, id: CalendarId, supported_components: SupportedComponents) -> Self;
|
||||||
|
|
||||||
/// Get the IDs of all current items in this calendar
|
/// Get the IDs of all current items in this calendar
|
||||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>>;
|
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>>;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue