Implement DAV Push

This commit is contained in:
Lennart
2025-06-14 20:24:50 +02:00
parent 0c48507f0c
commit 03ae492483
23 changed files with 882 additions and 308 deletions

View File

@@ -3,8 +3,8 @@ use async_trait::async_trait;
use derive_more::derive::Constructor;
use rustical_ical::AddressObject;
use rustical_store::{
Addressbook, AddressbookStore, CollectionOperation, CollectionOperationDomain,
CollectionOperationType, Error, synctoken::format_synctoken,
Addressbook, AddressbookStore, CollectionOperation, CollectionOperationInfo, Error,
synctoken::format_synctoken,
};
use sqlx::{Acquire, Executor, Sqlite, SqlitePool, Transaction};
use tokio::sync::mpsc::Sender;
@@ -413,10 +413,8 @@ impl AddressbookStore for SqliteAddressbookStore {
if let Some(addressbook) = addressbook {
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Delete,
domain: CollectionOperationDomain::Addressbook,
data: CollectionOperationInfo::Delete,
topic: addressbook.push_topic,
sync_token: None,
}) {
error!("Push notification about deleted addressbook failed: {err}");
};
@@ -485,7 +483,7 @@ impl AddressbookStore for SqliteAddressbookStore {
)
.await?;
let synctoken = log_object_operation(
let sync_token = log_object_operation(
&mut tx,
&principal,
&addressbook_id,
@@ -498,13 +496,11 @@ impl AddressbookStore for SqliteAddressbookStore {
tx.commit().await.map_err(crate::Error::from)?;
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: CollectionOperationDomain::Addressbook,
data: CollectionOperationInfo::Content { sync_token },
topic: self
.get_addressbook(&principal, &addressbook_id, false)
.await?
.push_topic,
sync_token: Some(synctoken),
}) {
error!("Push notification about deleted addressbook failed: {err}");
};
@@ -524,7 +520,7 @@ impl AddressbookStore for SqliteAddressbookStore {
Self::_delete_object(&mut *tx, principal, addressbook_id, object_id, use_trashbin).await?;
let synctoken = log_object_operation(
let sync_token = log_object_operation(
&mut tx,
principal,
addressbook_id,
@@ -536,16 +532,15 @@ impl AddressbookStore for SqliteAddressbookStore {
tx.commit().await.map_err(crate::Error::from)?;
// TODO: Watch for errors here?
let _ = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: CollectionOperationDomain::Addressbook,
if let Err(err) = self.sender.try_send(CollectionOperation {
data: CollectionOperationInfo::Content { sync_token },
topic: self
.get_addressbook(principal, addressbook_id, false)
.await?
.push_topic,
sync_token: Some(synctoken),
});
}) {
error!("Push notification about deleted addressbook failed: {err}");
};
Ok(())
}
@@ -560,7 +555,7 @@ impl AddressbookStore for SqliteAddressbookStore {
Self::_restore_object(&mut *tx, principal, addressbook_id, object_id).await?;
let synctoken = log_object_operation(
let sync_token = log_object_operation(
&mut tx,
principal,
addressbook_id,
@@ -571,16 +566,15 @@ impl AddressbookStore for SqliteAddressbookStore {
.map_err(crate::Error::from)?;
tx.commit().await.map_err(crate::Error::from)?;
// TODO: Watch for errors here?
let _ = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: CollectionOperationDomain::Addressbook,
if let Err(err) = self.sender.try_send(CollectionOperation {
data: CollectionOperationInfo::Content { sync_token },
topic: self
.get_addressbook(principal, addressbook_id, false)
.await?
.push_topic,
sync_token: Some(synctoken),
});
}) {
error!("Push notification about deleted addressbook failed: {err}");
};
Ok(())
}

View File

@@ -6,7 +6,7 @@ use rustical_ical::{CalDateTime, CalendarObject, CalendarObjectType};
use rustical_store::calendar_store::CalendarQuery;
use rustical_store::synctoken::format_synctoken;
use rustical_store::{Calendar, CalendarStore, Error};
use rustical_store::{CollectionOperation, CollectionOperationType};
use rustical_store::{CollectionOperation, CollectionOperationInfo};
use sqlx::types::chrono::NaiveDateTime;
use sqlx::{Acquire, Executor, Sqlite, SqlitePool, Transaction};
use tokio::sync::mpsc::Sender;
@@ -518,10 +518,8 @@ impl CalendarStore for SqliteCalendarStore {
if let Some(cal) = cal {
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Delete,
domain: rustical_store::CollectionOperationDomain::Calendar,
data: CollectionOperationInfo::Delete,
topic: cal.push_topic,
sync_token: None,
}) {
error!("Push notification about deleted calendar failed: {err}");
};
@@ -585,7 +583,7 @@ impl CalendarStore for SqliteCalendarStore {
)
.await?;
let synctoken = log_object_operation(
let sync_token = log_object_operation(
&mut tx,
&principal,
&cal_id,
@@ -597,10 +595,8 @@ impl CalendarStore for SqliteCalendarStore {
tx.commit().await.map_err(crate::Error::from)?;
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: rustical_store::CollectionOperationDomain::Calendar,
data: CollectionOperationInfo::Content { sync_token },
topic: self.get_calendar(&principal, &cal_id).await?.push_topic,
sync_token: Some(synctoken),
}) {
error!("Push notification about deleted calendar failed: {err}");
};
@@ -619,15 +615,13 @@ impl CalendarStore for SqliteCalendarStore {
Self::_delete_object(&mut *tx, principal, cal_id, id, use_trashbin).await?;
let synctoken =
let sync_token =
log_object_operation(&mut tx, principal, cal_id, id, ChangeOperation::Delete).await?;
tx.commit().await.map_err(crate::Error::from)?;
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: rustical_store::CollectionOperationDomain::Calendar,
data: CollectionOperationInfo::Content { sync_token },
topic: self.get_calendar(principal, cal_id).await?.push_topic,
sync_token: Some(synctoken),
}) {
error!("Push notification about deleted calendar failed: {err}");
};
@@ -645,16 +639,14 @@ impl CalendarStore for SqliteCalendarStore {
Self::_restore_object(&mut *tx, principal, cal_id, object_id).await?;
let synctoken =
let sync_token =
log_object_operation(&mut tx, principal, cal_id, object_id, ChangeOperation::Add)
.await?;
tx.commit().await.map_err(crate::Error::from)?;
if let Err(err) = self.sender.try_send(CollectionOperation {
r#type: CollectionOperationType::Object,
domain: rustical_store::CollectionOperationDomain::Calendar,
data: CollectionOperationInfo::Content { sync_token },
topic: self.get_calendar(principal, cal_id).await?.push_topic,
sync_token: Some(synctoken),
}) {
error!("Push notification about deleted calendar failed: {err}");
};