Added get_items_by_url, to fetch multiple items at once
This commit is contained in:
parent
f7110c254f
commit
a973146366
3 changed files with 56 additions and 0 deletions
|
@ -326,6 +326,14 @@ impl DavCalendar for CachedCalendar {
|
|||
Ok(self.items.get(url).cloned())
|
||||
}
|
||||
|
||||
async fn get_items_by_url(&self, urls: &[Url]) -> Result<Vec<Option<Item>>, Box<dyn Error>> {
|
||||
let mut v = Vec::new();
|
||||
for url in urls {
|
||||
v.push(DavCalendar::get_item_by_url(self, url).await?);
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>> {
|
||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||
self.mock_behaviour.as_ref().map_or(Ok(()), |b| b.lock().unwrap().can_delete_item())?;
|
||||
|
|
|
@ -14,6 +14,7 @@ use crate::item::Item;
|
|||
use crate::item::VersionTag;
|
||||
use crate::item::SyncStatus;
|
||||
use crate::resource::Resource;
|
||||
use crate::utils::find_elem;
|
||||
|
||||
static TASKS_BODY: &str = r#"
|
||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
|
@ -28,6 +29,15 @@ static TASKS_BODY: &str = r#"
|
|||
</c:calendar-query>
|
||||
"#;
|
||||
|
||||
static MULTIGET_BODY_PREFIX: &str = r#"
|
||||
<c:calendar-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<c:calendar-data />
|
||||
</d:prop>
|
||||
"#;
|
||||
static MULTIGET_BODY_SUFFIX: &str = r#"
|
||||
</c:calendar-multiget>
|
||||
"#;
|
||||
|
||||
|
||||
|
||||
|
@ -191,6 +201,40 @@ impl DavCalendar for RemoteCalendar {
|
|||
Ok(Some(item))
|
||||
}
|
||||
|
||||
async fn get_items_by_url(&self, urls: &[Url]) -> Result<Vec<Option<Item>>, Box<dyn Error>> {
|
||||
// Build the request body
|
||||
let mut hrefs = String::new();
|
||||
for url in urls {
|
||||
hrefs.push_str(&format!(" <d:href>{}</d:href>\n", url.path()));
|
||||
}
|
||||
let body = format!("{}{}{}", MULTIGET_BODY_PREFIX, hrefs, MULTIGET_BODY_SUFFIX);
|
||||
|
||||
// Send the request
|
||||
let xml_replies = crate::client::sub_request_and_extract_elems(&self.resource, "REPORT", body, "response").await?;
|
||||
|
||||
// This is supposed to be cached
|
||||
let version_tags = self.get_item_version_tags().await?;
|
||||
|
||||
// Parse the results
|
||||
let mut results = Vec::new();
|
||||
for xml_reply in xml_replies {
|
||||
let href = find_elem(&xml_reply, "href").ok_or("Missing HREF")?.text();
|
||||
let mut url = self.resource.url().clone();
|
||||
url.set_path(&href);
|
||||
let ical_data = find_elem(&xml_reply, "calendar-data").ok_or("Missing calendar-data")?.text();
|
||||
|
||||
let vt = match version_tags.get(&url) {
|
||||
None => return Err(format!("Inconsistent data: {} has no version tag", url).into()),
|
||||
Some(vt) => vt,
|
||||
};
|
||||
|
||||
let item = crate::ical::parse(&ical_data, url.clone(), SyncStatus::Synced(vt.clone()))?;
|
||||
results.push(Some(item));
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>> {
|
||||
let del_response = reqwest::Client::new()
|
||||
.delete(item_url.clone())
|
||||
|
|
|
@ -83,6 +83,10 @@ pub trait DavCalendar : BaseCalendar {
|
|||
/// Returns a particular item
|
||||
async fn get_item_by_url(&self, url: &Url) -> Result<Option<Item>, Box<dyn Error>>;
|
||||
|
||||
/// Returns a set of items.
|
||||
/// This is usually faster than calling multiple consecutive [`get_item_by_url`], since it only issues one HTTP request.
|
||||
async fn get_items_by_url(&self, urls: &[Url]) -> Result<Vec<Option<Item>>, Box<dyn Error>>;
|
||||
|
||||
/// Delete an item
|
||||
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>>;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue