Add purge command, simplify event RRULE until clients are fixed
This commit is contained in:
parent
04fadd3d89
commit
76968d5977
9 changed files with 124 additions and 16 deletions
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
63
src/commands/purge.rs
Normal 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(())
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue