Add purge command, simplify event RRULE until clients are fixed

This commit is contained in:
Matteo Settenvini 2022-08-02 15:41:55 +02:00
parent 04fadd3d89
commit 76968d5977
Signed by: matteo
GPG key ID: 8576CC1AD97D42DF
9 changed files with 124 additions and 16 deletions

View file

@ -1,5 +1,3 @@
use reqwest::Method;
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: AGPL-3.0-or-later
@ -10,7 +8,7 @@ use {
chrono::{Duration, Local},
icalendar::Component,
regex::Regex,
reqwest::StatusCode,
reqwest::{Method, StatusCode},
std::collections::HashSet,
std::ops::Range,
};

View file

@ -4,5 +4,6 @@
pub mod groceries;
pub mod import;
pub mod init;
pub mod purge;
pub mod schedule;
pub mod schedule_csv;

63
src/commands/purge.rs Normal file
View file

@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: AGPL-3.0-or-later
use {crate::api_client::ApiClient, crate::constants, anyhow::Result, reqwest::Method};
pub async fn with(api_client: &ApiClient, calendar_name: &str) -> Result<()> {
let report_method = Method::from_bytes(b"REPORT")?;
let events_xml = api_client
.rest()
.request(
report_method,
// TODO extract into helper method
api_client.caldav_base_url().join(&format!(
"calendars/{}/{}/",
api_client.username(),
calendar_name.to_lowercase().replace(" ", "-")
))?,
)
.header("Prefer", "return-minimal")
.header("Content-Type", "application/xml; charset=utf-8")
.header("Depth", 1)
.body(format!(
"<c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">
<d:prop>
<d:getetag/>
</d:prop>
<c:filter>
<c:comp-filter name=\"VCALENDAR\">
<c:prop-filter name=\"PRODID\">
<c:text-match>{}</c:text-match>
</c:prop-filter>
</c:comp-filter>
</c:filter>
</c:calendar-query>
",
constants::CALENDAR_PROVIDER,
))
.send()
.await?
.text()
.await?;
let xml_doc = libxml::parser::Parser::default().parse_string(events_xml.as_bytes())?;
let mut xpath_ctx = libxml::xpath::Context::new(&xml_doc).unwrap();
xpath_ctx.register_namespace("d", "DAV:").unwrap();
let events_to_purge = xpath_ctx
.findnodes("//d:response/d:href/text()", None)
.unwrap()
.into_iter()
.map(|n| icalendar::parser::unfold(&n.get_content()))
.collect::<Vec<_>>();
for url in events_to_purge {
api_client
.rest()
.delete(api_client.base_url().join(&url)?)
.send()
.await?;
log::debug!("Purged {}", &url);
}
Ok(())
}

View file

@ -115,13 +115,7 @@ async fn publish_events<'a, EventsIter>(
where
EventsIter: Iterator<Item = Event>,
{
let dav_base = api_client
.rest()
.head(api_client.base_url().join("/.well-known/caldav")?)
.send()
.await?;
let calendar_url = dav_base.url().join(&format!(
let calendar_url = api_client.caldav_base_url().join(&format!(
"calendars/{}/{}/",
&api_client.username(),
calendar.to_lowercase().as_str().replace(" ", "-")
@ -160,7 +154,6 @@ where
// TODO: wrap this
let _ = api_client.rest_semaphore.acquire().await.unwrap();
log::info!("{}", info_message);
let response = api_client
.rest()
.put(url)
@ -169,6 +162,8 @@ where
.send()
.await;
log::info!("{}", info_message);
// TODO: magic numbers are bad...
std::thread::sleep(std::time::Duration::from_millis(300));
response