mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 03:32:15 +00:00
caldav: Add calendar-timezone-id
This commit is contained in:
@@ -27,6 +27,7 @@ pub struct SupportedCalendarComponentSetElement {
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug)]
|
||||
pub struct MkcolCalendarProp {
|
||||
// TODO: Add namespaces
|
||||
resourcetype: Option<Resourcetype>,
|
||||
displayname: Option<String>,
|
||||
calendar_description: Option<String>,
|
||||
@@ -70,6 +71,7 @@ pub async fn route_mkcalendar<C: CalendarStore + ?Sized>(
|
||||
order: request.order.unwrap_or(0),
|
||||
displayname: request.displayname,
|
||||
timezone: request.calendar_timezone,
|
||||
timezone_id: request.calendar_timezone_id,
|
||||
color: request.calendar_color,
|
||||
description: request.calendar_description,
|
||||
deleted_at: None,
|
||||
|
||||
@@ -61,6 +61,9 @@ pub enum CalendarProp {
|
||||
CalendarDescription(Option<String>),
|
||||
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
|
||||
CalendarTimezone(Option<String>),
|
||||
// https://datatracker.ietf.org/doc/html/rfc7809
|
||||
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
|
||||
CalendarTimezoneId(Option<String>),
|
||||
#[xml(ns = "rustical_dav::namespace::NS_ICAL")]
|
||||
CalendarOrder(Option<i64>),
|
||||
#[xml(ns = "rustical_dav::namespace::NS_CALDAV", skip_deserializing)]
|
||||
@@ -138,6 +141,9 @@ impl Resource for CalendarResource {
|
||||
CalendarPropName::CalendarTimezone => {
|
||||
CalendarProp::CalendarTimezone(self.0.timezone.clone())
|
||||
}
|
||||
CalendarPropName::CalendarTimezoneId => {
|
||||
CalendarProp::CalendarTimezoneId(self.0.timezone_id.clone())
|
||||
}
|
||||
CalendarPropName::CalendarOrder => CalendarProp::CalendarOrder(Some(self.0.order)),
|
||||
CalendarPropName::SupportedCalendarComponentSet => {
|
||||
CalendarProp::SupportedCalendarComponentSet(SupportedCalendarComponentSet::default())
|
||||
@@ -186,6 +192,11 @@ impl Resource for CalendarResource {
|
||||
self.0.timezone = timezone;
|
||||
Ok(())
|
||||
}
|
||||
CalendarProp::CalendarTimezoneId(timezone_id) => {
|
||||
// TODO: Set or remove timezone accordingly
|
||||
self.0.timezone_id = timezone_id;
|
||||
Ok(())
|
||||
}
|
||||
CalendarProp::CalendarOrder(order) => {
|
||||
self.0.order = order.unwrap_or_default();
|
||||
Ok(())
|
||||
@@ -224,6 +235,10 @@ impl Resource for CalendarResource {
|
||||
self.0.timezone = None;
|
||||
Ok(())
|
||||
}
|
||||
CalendarPropName::CalendarTimezoneId => {
|
||||
self.0.timezone_id = None;
|
||||
Ok(())
|
||||
}
|
||||
CalendarPropName::CalendarOrder => {
|
||||
self.0.order = 0;
|
||||
Ok(())
|
||||
|
||||
@@ -40,7 +40,7 @@ pub fn configure_dav<AP: AuthenticationProvider, C: CalendarStore + ?Sized>(
|
||||
.insert_header((
|
||||
HeaderName::from_static("dav"),
|
||||
HeaderValue::from_static(
|
||||
"1, 2, 3, access-control, calendar-access, extended-mkcol",
|
||||
"1, 2, 3, access-control, calendar-access, extended-mkcol, calendar-no-timezone",
|
||||
),
|
||||
))
|
||||
.finish();
|
||||
|
||||
@@ -11,6 +11,7 @@ pub struct Calendar {
|
||||
pub description: Option<String>,
|
||||
pub color: Option<String>,
|
||||
pub timezone: Option<String>,
|
||||
pub timezone_id: Option<String>,
|
||||
pub deleted_at: Option<NaiveDateTime>,
|
||||
pub synctoken: i64,
|
||||
pub subscription_url: Option<String>,
|
||||
|
||||
@@ -16,7 +16,6 @@ pub struct EventObject {
|
||||
|
||||
impl EventObject {
|
||||
pub fn get_first_occurence(&self) -> Result<Option<CalDateTime>, Error> {
|
||||
// This is safe since we enforce the event's existance in the constructor
|
||||
if let Some(dtstart) = self.event.get_property("DTSTART") {
|
||||
CalDateTime::parse_prop(dtstart, &self.timezones)
|
||||
} else {
|
||||
@@ -25,7 +24,6 @@ impl EventObject {
|
||||
}
|
||||
|
||||
pub fn get_last_occurence(&self) -> Result<Option<CalDateTime>, Error> {
|
||||
// This is safe since we enforce the event's existence in the constructor
|
||||
if let Some(_rrule) = self.event.get_property("RRULE") {
|
||||
// TODO: understand recurrence rules
|
||||
return Ok(None);
|
||||
|
||||
@@ -7,6 +7,7 @@ CREATE TABLE calendars (
|
||||
"order" INT DEFAULT 0 NOT NULL,
|
||||
color TEXT,
|
||||
timezone TEXT,
|
||||
timezone_id TEXT,
|
||||
deleted_at DATETIME,
|
||||
subscription_url TEXT,
|
||||
PRIMARY KEY (principal, id)
|
||||
|
||||
@@ -62,7 +62,7 @@ impl CalendarStore for SqliteStore {
|
||||
async fn get_calendar(&self, principal: &str, id: &str) -> Result<Calendar, Error> {
|
||||
let cal = sqlx::query_as!(
|
||||
Calendar,
|
||||
r#"SELECT principal, id, synctoken, "order", displayname, description, color, timezone, deleted_at, subscription_url
|
||||
r#"SELECT principal, id, synctoken, "order", displayname, description, color, timezone, timezone_id, deleted_at, subscription_url
|
||||
FROM calendars
|
||||
WHERE (principal, id) = (?, ?)"#,
|
||||
principal,
|
||||
@@ -77,7 +77,7 @@ impl CalendarStore for SqliteStore {
|
||||
async fn get_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error> {
|
||||
let cals = sqlx::query_as!(
|
||||
Calendar,
|
||||
r#"SELECT principal, id, synctoken, displayname, "order", description, color, timezone, deleted_at, subscription_url
|
||||
r#"SELECT principal, id, synctoken, displayname, "order", description, color, timezone, timezone_id, deleted_at, subscription_url
|
||||
FROM calendars
|
||||
WHERE principal = ? AND deleted_at IS NULL"#,
|
||||
principal
|
||||
@@ -91,7 +91,7 @@ impl CalendarStore for SqliteStore {
|
||||
async fn get_deleted_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error> {
|
||||
let cals = sqlx::query_as!(
|
||||
Calendar,
|
||||
r#"SELECT principal, id, synctoken, displayname, "order", description, color, timezone, deleted_at, subscription_url
|
||||
r#"SELECT principal, id, synctoken, displayname, "order", description, color, timezone, timezone_id, deleted_at, subscription_url
|
||||
FROM calendars
|
||||
WHERE principal = ? AND deleted_at IS NOT NULL"#,
|
||||
principal
|
||||
@@ -104,15 +104,16 @@ impl CalendarStore for SqliteStore {
|
||||
#[instrument]
|
||||
async fn insert_calendar(&self, calendar: Calendar) -> Result<(), Error> {
|
||||
sqlx::query!(
|
||||
r#"INSERT INTO calendars (principal, id, displayname, description, "order", color, timezone)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)"#,
|
||||
r#"INSERT INTO calendars (principal, id, displayname, description, "order", color, timezone, timezone_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)"#,
|
||||
calendar.principal,
|
||||
calendar.id,
|
||||
calendar.displayname,
|
||||
calendar.description,
|
||||
calendar.order,
|
||||
calendar.color,
|
||||
calendar.timezone
|
||||
calendar.timezone,
|
||||
calendar.timezone_id
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await.map_err(crate::Error::from)?;
|
||||
@@ -127,7 +128,7 @@ impl CalendarStore for SqliteStore {
|
||||
calendar: Calendar,
|
||||
) -> Result<(), Error> {
|
||||
let result = sqlx::query!(
|
||||
r#"UPDATE calendars SET principal = ?, id = ?, displayname = ?, description = ?, "order" = ?, color = ?, timezone = ?
|
||||
r#"UPDATE calendars SET principal = ?, id = ?, displayname = ?, description = ?, "order" = ?, color = ?, timezone = ?, timezone_id = ?
|
||||
WHERE (principal, id) = (?, ?)"#,
|
||||
calendar.principal,
|
||||
calendar.id,
|
||||
@@ -136,6 +137,7 @@ impl CalendarStore for SqliteStore {
|
||||
calendar.order,
|
||||
calendar.color,
|
||||
calendar.timezone,
|
||||
calendar.timezone_id,
|
||||
principal,
|
||||
id
|
||||
).execute(&self.db).await.map_err(crate::Error::from)?;
|
||||
|
||||
Reference in New Issue
Block a user