Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 117 in 50 files Dangling module declarations removed: 5 Cargo edits turning enterprise off: 14 Verification: clean Enterprise feature gates left for rebuilt features: 19 in 18 files Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::changes::state::StateManager;
|
||||
use common::{Server, auth::AccessToken};
|
||||
use email::cache::{MessageCacheFetch, email::MessageCacheAccess};
|
||||
use jmap_proto::{
|
||||
method::get::{GetRequest, GetResponse},
|
||||
object::thread::{Thread, ThreadProperty, ThreadValue},
|
||||
request::MaybeInvalid,
|
||||
};
|
||||
use jmap_tools::Map;
|
||||
use std::future::Future;
|
||||
use store::{
|
||||
ahash::AHashMap,
|
||||
roaring::RoaringBitmap,
|
||||
search::{EmailSearchField, SearchComparator, SearchField, SearchQuery},
|
||||
write::SearchIndex,
|
||||
};
|
||||
use trc::AddContext;
|
||||
use types::{acl::Acl, collection::SyncCollection, id::Id};
|
||||
|
||||
pub trait ThreadGet: Sync + Send {
|
||||
fn thread_get(
|
||||
&self,
|
||||
request: GetRequest<Thread>,
|
||||
access_token: &AccessToken,
|
||||
) -> impl Future<Output = trc::Result<GetResponse<Thread>>> + Send;
|
||||
}
|
||||
|
||||
impl ThreadGet for Server {
|
||||
async fn thread_get(
|
||||
&self,
|
||||
mut request: GetRequest<Thread>,
|
||||
access_token: &AccessToken,
|
||||
) -> trc::Result<GetResponse<Thread>> {
|
||||
let account_id = request.account_id.document_id();
|
||||
let cache = self
|
||||
.get_cached_messages(account_id)
|
||||
.await
|
||||
.caused_by(trc::location!())?;
|
||||
let shared_ids = if access_token.is_shared(account_id) {
|
||||
Some(cache.shared_messages(access_token, Acl::ReadItems))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut thread_map: AHashMap<u32, RoaringBitmap> = AHashMap::with_capacity(32);
|
||||
let mut all_ids = RoaringBitmap::new();
|
||||
for item in &cache.emails.items {
|
||||
if shared_ids
|
||||
.as_ref()
|
||||
.is_some_and(|ids| !ids.contains(item.document_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
thread_map
|
||||
.entry(item.thread_id)
|
||||
.or_default()
|
||||
.insert(item.document_id);
|
||||
all_ids.insert(item.document_id);
|
||||
}
|
||||
|
||||
let (ids, not_found_ids) = request.unwrap_ids(self.core.jmap.get_max_objects)?;
|
||||
let ids = if let Some(ids) = ids {
|
||||
ids
|
||||
} else {
|
||||
thread_map
|
||||
.keys()
|
||||
.copied()
|
||||
.take(self.core.jmap.get_max_objects)
|
||||
.map(Into::into)
|
||||
.collect()
|
||||
};
|
||||
let add_email_ids = request.properties.is_none_or(|p| {
|
||||
p.unwrap()
|
||||
.contains(&MaybeInvalid::Value(ThreadProperty::EmailIds))
|
||||
});
|
||||
let mut response = GetResponse {
|
||||
account_id: request.account_id.into(),
|
||||
state: self
|
||||
.get_state(account_id, SyncCollection::Thread)
|
||||
.await?
|
||||
.into(),
|
||||
list: Vec::with_capacity(ids.len()),
|
||||
not_found: not_found_ids,
|
||||
};
|
||||
|
||||
let ordered_ids = if add_email_ids && !all_ids.is_empty() {
|
||||
Some(
|
||||
self.search_store()
|
||||
.query_account(
|
||||
SearchQuery::new(SearchIndex::Email)
|
||||
.with_account_id(account_id)
|
||||
.with_mask(all_ids)
|
||||
.with_comparator(SearchComparator::Field {
|
||||
field: SearchField::Email(EmailSearchField::ReceivedAt),
|
||||
ascending: true,
|
||||
}),
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for id in ids {
|
||||
let thread_id = id.document_id();
|
||||
if let Some(mut document_ids) = thread_map.remove(&thread_id) {
|
||||
let mut thread: Map<'_, ThreadProperty, ThreadValue> =
|
||||
Map::with_capacity(2).with_key_value(ThreadProperty::Id, id);
|
||||
if let Some(ordered_ids) = &ordered_ids {
|
||||
let mut ids = Vec::with_capacity(document_ids.len() as usize);
|
||||
for &id in ordered_ids.iter() {
|
||||
if document_ids.remove(id) {
|
||||
ids.push(Id::from_parts(thread_id, id));
|
||||
}
|
||||
}
|
||||
for id in document_ids.iter() {
|
||||
ids.push(Id::from_parts(thread_id, id));
|
||||
}
|
||||
|
||||
thread.insert_unchecked(ThreadProperty::EmailIds, ids);
|
||||
}
|
||||
response.list.push(thread.into());
|
||||
} else {
|
||||
response.push_not_found(id);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
pub mod get;
|
||||
Reference in New Issue
Block a user