Added support for calendar colors
This commit is contained in:
parent
2b339a7aff
commit
17716575d8
11 changed files with 198 additions and 27 deletions
153
Cargo.lock
generated
153
Cargo.lock
generated
|
@ -103,6 +103,16 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csscolorparser"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2fb3bd93ef32553e3d5b9f8020028f41ac64ff8a230033d5d548b8222d21fbe"
|
||||||
|
dependencies = [
|
||||||
|
"phf",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.28"
|
version = "0.8.28"
|
||||||
|
@ -196,6 +206,17 @@ dependencies = [
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -204,7 +225,7 @@ checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -382,6 +403,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"csscolorparser",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"ical",
|
"ical",
|
||||||
"ics",
|
"ics",
|
||||||
|
@ -568,6 +590,50 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro-hack",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"rand 0.7.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro-hack",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -612,6 +678,12 @@ version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-hack"
|
||||||
|
version = "0.5.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
|
@ -639,6 +711,20 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.1.16",
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.2.2",
|
||||||
|
"rand_core 0.5.1",
|
||||||
|
"rand_hc 0.2.0",
|
||||||
|
"rand_pcg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
|
@ -646,9 +732,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.3.0",
|
||||||
"rand_core",
|
"rand_core 0.6.2",
|
||||||
"rand_hc",
|
"rand_hc 0.3.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -658,7 +754,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.1.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -667,7 +772,16 @@ version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
|
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -676,7 +790,16 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_pcg"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -841,6 +964,12 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -877,7 +1006,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"rand",
|
"rand 0.8.3",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -1082,7 +1211,7 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1101,6 +1230,12 @@ dependencies = [
|
||||||
"try-lock",
|
"try-lock",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.2+wasi-snapshot-preview1"
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -26,3 +26,4 @@ sanitize-filename = "0.3"
|
||||||
ical = "0.7"
|
ical = "0.7"
|
||||||
ics = "0.5"
|
ics = "0.5"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
csscolorparser = { version = "0.5", features = ["serde"] }
|
||||||
|
|
|
@ -69,7 +69,7 @@ async fn add_items_and_sync_again(provider: &mut CalDavProvider)
|
||||||
let new_calendar_id: CalendarId = EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
|
let new_calendar_id: CalendarId = EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
|
||||||
let new_calendar_name = "A brave new calendar".to_string();
|
let new_calendar_name = "A brave new calendar".to_string();
|
||||||
if let Err(_err) = provider.local_mut()
|
if let Err(_err) = provider.local_mut()
|
||||||
.create_calendar(new_calendar_id.clone(), new_calendar_name.clone(), SupportedComponents::TODO)
|
.create_calendar(new_calendar_id.clone(), new_calendar_name.clone(), SupportedComponents::TODO, None)
|
||||||
.await {
|
.await {
|
||||||
println!("Unable to add calendar, maybe it exists already. We're not adding it after all.");
|
println!("Unable to add calendar, maybe it exists already. We're not adding it after all.");
|
||||||
}
|
}
|
||||||
|
|
10
src/cache.rs
10
src/cache.rs
|
@ -9,6 +9,7 @@ use std::ffi::OsStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
use crate::traits::CalDavSource;
|
use crate::traits::CalDavSource;
|
||||||
use crate::traits::BaseCalendar;
|
use crate::traits::BaseCalendar;
|
||||||
|
@ -208,12 +209,12 @@ impl CalDavSource<CachedCalendar> for Cache {
|
||||||
self.get_calendar_sync(id)
|
self.get_calendar_sync(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents) -> Result<Arc<Mutex<CachedCalendar>>, Box<dyn Error>> {
|
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents, color: Option<Color>) -> Result<Arc<Mutex<CachedCalendar>>, Box<dyn Error>> {
|
||||||
log::debug!("Inserting local calendar {}", id);
|
log::debug!("Inserting local calendar {}", id);
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
self.mock_behaviour.as_ref().map_or(Ok(()), |b| b.lock().unwrap().can_create_calendar())?;
|
self.mock_behaviour.as_ref().map_or(Ok(()), |b| b.lock().unwrap().can_create_calendar())?;
|
||||||
|
|
||||||
let new_calendar = CachedCalendar::new(name, id.clone(), supported_components);
|
let new_calendar = CachedCalendar::new(name, id.clone(), supported_components, color);
|
||||||
let arc = Arc::new(Mutex::new(new_calendar));
|
let arc = Arc::new(Mutex::new(new_calendar));
|
||||||
|
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
|
@ -244,12 +245,14 @@ mod tests {
|
||||||
Url::parse("https://caldav.com/shopping").unwrap(),
|
Url::parse("https://caldav.com/shopping").unwrap(),
|
||||||
"My shopping list".to_string(),
|
"My shopping list".to_string(),
|
||||||
SupportedComponents::TODO,
|
SupportedComponents::TODO,
|
||||||
|
Some(csscolorparser::parse("lime").unwrap()),
|
||||||
).await.unwrap();
|
).await.unwrap();
|
||||||
|
|
||||||
let bucket_list = cache.create_calendar(
|
let bucket_list = cache.create_calendar(
|
||||||
Url::parse("https://caldav.com/bucket-list").unwrap(),
|
Url::parse("https://caldav.com/bucket-list").unwrap(),
|
||||||
"My bucket list".to_string(),
|
"My bucket list".to_string(),
|
||||||
SupportedComponents::TODO,
|
SupportedComponents::TODO,
|
||||||
|
Some(csscolorparser::parse("#ff8000").unwrap()),
|
||||||
).await.unwrap();
|
).await.unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -288,11 +291,12 @@ mod tests {
|
||||||
let cache_path = PathBuf::from(String::from("test_cache/sanity_tests"));
|
let cache_path = PathBuf::from(String::from("test_cache/sanity_tests"));
|
||||||
let mut cache = populate_cache(&cache_path).await;
|
let mut cache = populate_cache(&cache_path).await;
|
||||||
|
|
||||||
// We should not be able to add twice the same calendar
|
// We should not be able to add a second calendar with the same id
|
||||||
let second_addition_same_calendar = cache.create_calendar(
|
let second_addition_same_calendar = cache.create_calendar(
|
||||||
Url::parse("https://caldav.com/shopping").unwrap(),
|
Url::parse("https://caldav.com/shopping").unwrap(),
|
||||||
"My shopping list".to_string(),
|
"My shopping list".to_string(),
|
||||||
SupportedComponents::TODO,
|
SupportedComponents::TODO,
|
||||||
|
None,
|
||||||
).await;
|
).await;
|
||||||
assert!(second_addition_same_calendar.is_err());
|
assert!(second_addition_same_calendar.is_err());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::error::Error;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
use crate::item::SyncStatus;
|
use crate::item::SyncStatus;
|
||||||
use crate::traits::{BaseCalendar, CompleteCalendar};
|
use crate::traits::{BaseCalendar, CompleteCalendar};
|
||||||
|
@ -24,6 +25,7 @@ pub struct CachedCalendar {
|
||||||
name: String,
|
name: String,
|
||||||
id: CalendarId,
|
id: CalendarId,
|
||||||
supported_components: SupportedComponents,
|
supported_components: SupportedComponents,
|
||||||
|
color: Option<Color>,
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
mock_behaviour: Option<Arc<Mutex<MockBehaviour>>>,
|
mock_behaviour: Option<Arc<Mutex<MockBehaviour>>>,
|
||||||
|
@ -85,7 +87,9 @@ impl CachedCalendar {
|
||||||
pub async fn has_same_observable_content_as(&self, other: &CachedCalendar) -> Result<bool, Box<dyn Error>> {
|
pub async fn has_same_observable_content_as(&self, other: &CachedCalendar) -> Result<bool, Box<dyn Error>> {
|
||||||
if self.name != other.name
|
if self.name != other.name
|
||||||
|| self.id != other.id
|
|| self.id != other.id
|
||||||
|| self.supported_components != other.supported_components {
|
|| self.supported_components != other.supported_components
|
||||||
|
|| self.color != other.color
|
||||||
|
{
|
||||||
log::debug!("Calendar properties mismatch");
|
log::debug!("Calendar properties mismatch");
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
@ -156,6 +160,10 @@ impl BaseCalendar for CachedCalendar {
|
||||||
self.supported_components
|
self.supported_components
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color(&self) -> Option<&Color> {
|
||||||
|
self.color.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
|
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
|
||||||
if self.items.contains_key(item.id()) {
|
if self.items.contains_key(item.id()) {
|
||||||
return Err(format!("Item {:?} cannot be added, it exists already", item.id()).into());
|
return Err(format!("Item {:?} cannot be added, it exists already", item.id()).into());
|
||||||
|
@ -181,9 +189,9 @@ 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 {
|
fn new(name: String, id: CalendarId, supported_components: SupportedComponents, color: Option<Color>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name, id, supported_components,
|
name, id, supported_components, color,
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
mock_behaviour: None,
|
mock_behaviour: None,
|
||||||
items: HashMap::new(),
|
items: HashMap::new(),
|
||||||
|
@ -253,8 +261,8 @@ use crate::{item::VersionTag,
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl DavCalendar for CachedCalendar {
|
impl DavCalendar for CachedCalendar {
|
||||||
fn new(name: String, resource: Resource, supported_components: SupportedComponents) -> Self {
|
fn new(name: String, resource: Resource, supported_components: SupportedComponents, color: Option<Color>) -> Self {
|
||||||
crate::traits::CompleteCalendar::new(name, resource.url().clone(), supported_components)
|
crate::traits::CompleteCalendar::new(name, resource.url().clone(), supported_components, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::sync::Mutex;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::{header::CONTENT_TYPE, header::CONTENT_LENGTH};
|
use reqwest::{header::CONTENT_TYPE, header::CONTENT_LENGTH};
|
||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
use crate::traits::BaseCalendar;
|
use crate::traits::BaseCalendar;
|
||||||
use crate::traits::DavCalendar;
|
use crate::traits::DavCalendar;
|
||||||
|
@ -37,6 +38,7 @@ pub struct RemoteCalendar {
|
||||||
name: String,
|
name: String,
|
||||||
resource: Resource,
|
resource: Resource,
|
||||||
supported_components: SupportedComponents,
|
supported_components: SupportedComponents,
|
||||||
|
color: Option<Color>,
|
||||||
|
|
||||||
cached_version_tags: Mutex<Option<HashMap<ItemId, VersionTag>>>,
|
cached_version_tags: Mutex<Option<HashMap<ItemId, VersionTag>>>,
|
||||||
}
|
}
|
||||||
|
@ -48,6 +50,9 @@ impl BaseCalendar for RemoteCalendar {
|
||||||
fn supported_components(&self) -> crate::calendar::SupportedComponents {
|
fn supported_components(&self) -> crate::calendar::SupportedComponents {
|
||||||
self.supported_components
|
self.supported_components
|
||||||
}
|
}
|
||||||
|
fn color(&self) -> Option<&Color> {
|
||||||
|
self.color.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
|
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
|
||||||
let ical_text = crate::ical::build_from(&item)?;
|
let ical_text = crate::ical::build_from(&item)?;
|
||||||
|
@ -114,9 +119,9 @@ impl BaseCalendar for RemoteCalendar {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl DavCalendar for RemoteCalendar {
|
impl DavCalendar for RemoteCalendar {
|
||||||
fn new(name: String, resource: Resource, supported_components: SupportedComponents) -> Self {
|
fn new(name: String, resource: Resource, supported_components: SupportedComponents, color: Option<Color>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name, resource, supported_components,
|
name, resource, supported_components, color,
|
||||||
cached_version_tags: Mutex::new(None),
|
cached_version_tags: Mutex::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use reqwest::{Method, StatusCode};
|
||||||
use reqwest::header::CONTENT_TYPE;
|
use reqwest::header::CONTENT_TYPE;
|
||||||
use minidom::Element;
|
use minidom::Element;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::utils::{find_elem, find_elems};
|
use crate::utils::{find_elem, find_elems};
|
||||||
|
@ -42,6 +43,7 @@ static CAL_BODY: &str = r#"
|
||||||
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" >
|
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" >
|
||||||
<d:prop>
|
<d:prop>
|
||||||
<d:displayname />
|
<d:displayname />
|
||||||
|
<E:calendar-color xmlns:E="http://apple.com/ns/ical/"/>
|
||||||
<d:resourcetype />
|
<d:resourcetype />
|
||||||
<c:supported-calendar-component-set />
|
<c:supported-calendar-component-set />
|
||||||
</d:prop>
|
</d:prop>
|
||||||
|
@ -205,7 +207,14 @@ impl Client {
|
||||||
},
|
},
|
||||||
Ok(sc) => sc,
|
Ok(sc) => sc,
|
||||||
};
|
};
|
||||||
let this_calendar = RemoteCalendar::new(display_name, this_calendar_url, supported_components);
|
|
||||||
|
let this_calendar_color = find_elem(&rep, "calendar-color")
|
||||||
|
.and_then(|col| {
|
||||||
|
col.texts().next()
|
||||||
|
.and_then(|t| csscolorparser::parse(t).ok())
|
||||||
|
});
|
||||||
|
|
||||||
|
let this_calendar = RemoteCalendar::new(display_name, this_calendar_url, supported_components, this_calendar_color);
|
||||||
log::info!("Found calendar {}", this_calendar.name());
|
log::info!("Found calendar {}", this_calendar.name());
|
||||||
calendars.insert(this_calendar.id().clone(), Arc::new(Mutex::new(this_calendar)));
|
calendars.insert(this_calendar.id().clone(), Arc::new(Mutex::new(this_calendar)));
|
||||||
}
|
}
|
||||||
|
@ -243,7 +252,7 @@ impl CalDavSource<RemoteCalendar> for Client {
|
||||||
.map(|cal| cal.clone())
|
.map(|cal| cal.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents) -> Result<Arc<Mutex<RemoteCalendar>>, Box<dyn Error>> {
|
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents, color: Option<Color>) -> Result<Arc<Mutex<RemoteCalendar>>, Box<dyn Error>> {
|
||||||
self.populate_calendars().await?;
|
self.populate_calendars().await?;
|
||||||
|
|
||||||
match self.cached_replies.lock().unwrap().calendars.as_ref() {
|
match self.cached_replies.lock().unwrap().calendars.as_ref() {
|
||||||
|
|
|
@ -390,10 +390,12 @@ where
|
||||||
let src = needle.lock().unwrap();
|
let src = needle.lock().unwrap();
|
||||||
let name = src.name().to_string();
|
let name = src.name().to_string();
|
||||||
let supported_comps = src.supported_components();
|
let supported_comps = src.supported_components();
|
||||||
|
let color = src.color();
|
||||||
if let Err(err) = haystack.create_calendar(
|
if let Err(err) = haystack.create_calendar(
|
||||||
cal_id.clone(),
|
cal_id.clone(),
|
||||||
name,
|
name,
|
||||||
supported_comps,
|
supported_comps,
|
||||||
|
color.cloned(),
|
||||||
).await{
|
).await{
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
use crate::item::SyncStatus;
|
use crate::item::SyncStatus;
|
||||||
use crate::item::Item;
|
use crate::item::Item;
|
||||||
|
@ -21,7 +22,7 @@ pub trait CalDavSource<T: BaseCalendar> {
|
||||||
/// 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>>>;
|
||||||
/// Create a calendar if it did not exist, and return it
|
/// Create a calendar if it did not exist, and return it
|
||||||
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents)
|
async fn create_calendar(&mut self, id: CalendarId, name: String, supported_components: SupportedComponents, color: Option<Color>)
|
||||||
-> Result<Arc<Mutex<T>>, Box<dyn Error>>;
|
-> Result<Arc<Mutex<T>>, Box<dyn Error>>;
|
||||||
|
|
||||||
// Removing a calendar is not supported yet
|
// Removing a calendar is not supported yet
|
||||||
|
@ -39,6 +40,9 @@ pub trait BaseCalendar {
|
||||||
/// Returns the supported kinds of components for this calendar
|
/// Returns the supported kinds of components for this calendar
|
||||||
fn supported_components(&self) -> crate::calendar::SupportedComponents;
|
fn supported_components(&self) -> crate::calendar::SupportedComponents;
|
||||||
|
|
||||||
|
/// Returns the user-defined color of this calendar
|
||||||
|
fn color(&self) -> Option<&Color>;
|
||||||
|
|
||||||
/// Add an item into this calendar, and return its new sync status.
|
/// Add an item into this calendar, and return its new sync status.
|
||||||
/// For local calendars, the sync status is not modified.
|
/// For local calendars, the sync status is not modified.
|
||||||
/// For remote calendars, the sync status is updated by the server
|
/// For remote calendars, the sync status is updated by the server
|
||||||
|
@ -64,7 +68,7 @@ pub trait BaseCalendar {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait DavCalendar : BaseCalendar {
|
pub trait DavCalendar : BaseCalendar {
|
||||||
/// Create a new calendar
|
/// Create a new calendar
|
||||||
fn new(name: String, resource: Resource, supported_components: SupportedComponents) -> Self;
|
fn new(name: String, resource: Resource, supported_components: SupportedComponents, color: Option<Color>) -> Self;
|
||||||
|
|
||||||
/// Get the IDs and the version tags of every item in this calendar
|
/// Get the IDs and the version tags of every item in this calendar
|
||||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>>;
|
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>>;
|
||||||
|
@ -94,7 +98,7 @@ pub trait DavCalendar : BaseCalendar {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait CompleteCalendar : BaseCalendar {
|
pub trait CompleteCalendar : BaseCalendar {
|
||||||
/// Create a new calendar
|
/// Create a new calendar
|
||||||
fn new(name: String, id: CalendarId, supported_components: SupportedComponents) -> Self;
|
fn new(name: String, id: CalendarId, supported_components: SupportedComponents, color: Option<Color>) -> 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>>;
|
||||||
|
|
|
@ -50,14 +50,15 @@ async fn show_calendars() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
#[ignore]
|
||||||
async fn create_cal() {
|
async fn create_cal() {
|
||||||
let _ = env_logger::builder().is_test(true).try_init();
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
let mut client = Client::new(URL, USERNAME, PASSWORD).unwrap();
|
let mut client = Client::new(URL, USERNAME, PASSWORD).unwrap();
|
||||||
let id: Url = kitchen_fridge::settings::EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
|
let id: Url = kitchen_fridge::settings::EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
|
||||||
let name = "prout".into();
|
let name = "a created calendar".into();
|
||||||
let supported_components = SupportedComponents::TODO;
|
let supported_components = SupportedComponents::TODO;
|
||||||
client.create_calendar(id, name, supported_components).await.unwrap();
|
client.create_calendar(id, name, supported_components, Some(csscolorparser::parse("gold").unwrap())).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
|
@ -692,11 +692,13 @@ async fn get_or_insert_calendar(source: &mut Cache, id: &CalendarId)
|
||||||
None => {
|
None => {
|
||||||
let new_name = format!("Test calendar for ID {}", id);
|
let new_name = format!("Test calendar for ID {}", id);
|
||||||
let supported_components = SupportedComponents::TODO;
|
let supported_components = SupportedComponents::TODO;
|
||||||
|
let color = csscolorparser::parse("#ff8000"); // TODO: we should rather have specific colors, depending on the calendars
|
||||||
|
|
||||||
source.create_calendar(
|
source.create_calendar(
|
||||||
id.clone(),
|
id.clone(),
|
||||||
new_name.to_string(),
|
new_name.to_string(),
|
||||||
supported_components,
|
supported_components,
|
||||||
|
None,
|
||||||
).await
|
).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue