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())
|
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>> {
|
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>> {
|
||||||
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
|
||||||
self.mock_behaviour.as_ref().map_or(Ok(()), |b| b.lock().unwrap().can_delete_item())?;
|
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::VersionTag;
|
||||||
use crate::item::SyncStatus;
|
use crate::item::SyncStatus;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
|
use crate::utils::find_elem;
|
||||||
|
|
||||||
static TASKS_BODY: &str = r#"
|
static TASKS_BODY: &str = r#"
|
||||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
<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>
|
</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))
|
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>> {
|
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>> {
|
||||||
let del_response = reqwest::Client::new()
|
let del_response = reqwest::Client::new()
|
||||||
.delete(item_url.clone())
|
.delete(item_url.clone())
|
||||||
|
|
|
@ -83,6 +83,10 @@ pub trait DavCalendar : BaseCalendar {
|
||||||
/// Returns a particular item
|
/// Returns a particular item
|
||||||
async fn get_item_by_url(&self, url: &Url) -> Result<Option<Item>, Box<dyn Error>>;
|
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
|
/// Delete an item
|
||||||
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>>;
|
async fn delete_item(&mut self, item_url: &Url) -> Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue