mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 12:56:30 +03:00
imap: always close folder before selecting if expunge is needed
This commit is contained in:
committed by
link2xt
parent
54395a7252
commit
c41a6b87b8
@@ -23,6 +23,34 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Imap {
|
impl Imap {
|
||||||
|
/// Issues a CLOSE command to expunge selected folder.
|
||||||
|
///
|
||||||
|
/// CLOSE is considerably faster than an EXPUNGE, see
|
||||||
|
/// https://tools.ietf.org/html/rfc3501#section-6.4.2
|
||||||
|
async fn close_folder(&self, context: &Context) -> Result<()> {
|
||||||
|
if let Some(ref folder) = self.config.read().await.selected_folder {
|
||||||
|
info!(context, "Expunge messages in \"{}\".", folder);
|
||||||
|
|
||||||
|
if let Some(ref mut session) = &mut *self.session.lock().await {
|
||||||
|
match session.close().await {
|
||||||
|
Ok(_) => {
|
||||||
|
info!(context, "close/expunge succeeded");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
self.trigger_reconnect();
|
||||||
|
return Err(Error::CloseExpungeFailed(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::NoSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut cfg = self.config.write().await;
|
||||||
|
cfg.selected_folder = None;
|
||||||
|
cfg.selected_folder_needs_expunge = false;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// select a folder, possibly update uid_validity and, if needed,
|
/// select a folder, possibly update uid_validity and, if needed,
|
||||||
/// expunge the folder to remove delete-marked messages.
|
/// expunge the folder to remove delete-marked messages.
|
||||||
pub(super) async fn select_folder<S: AsRef<str>>(
|
pub(super) async fn select_folder<S: AsRef<str>>(
|
||||||
@@ -38,39 +66,14 @@ impl Imap {
|
|||||||
return Err(Error::NoSession);
|
return Err(Error::NoSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is a new folder and the new folder is equal to the selected one, there's nothing to do.
|
let needs_expunge = self.config.read().await.selected_folder_needs_expunge;
|
||||||
// if there is _no_ new folder, we continue as we might want to expunge below.
|
if needs_expunge {
|
||||||
if let Some(ref folder) = folder {
|
self.close_folder(context).await?;
|
||||||
if let Some(ref selected_folder) = self.config.read().await.selected_folder {
|
|
||||||
if folder.as_ref() == selected_folder {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then)
|
let folder_str: Option<&str> = folder.as_ref().map(|x| x.as_ref());
|
||||||
let needs_expunge = { self.config.read().await.selected_folder_needs_expunge };
|
if self.config.read().await.selected_folder.as_deref() == folder_str {
|
||||||
if needs_expunge {
|
return Ok(());
|
||||||
if let Some(ref folder) = self.config.read().await.selected_folder {
|
|
||||||
info!(context, "Expunge messages in \"{}\".", folder);
|
|
||||||
|
|
||||||
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
|
|
||||||
// https://tools.ietf.org/html/rfc3501#section-6.4.2
|
|
||||||
if let Some(ref mut session) = &mut *self.session.lock().await {
|
|
||||||
match session.close().await {
|
|
||||||
Ok(_) => {
|
|
||||||
info!(context, "close/expunge succeeded");
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
self.trigger_reconnect();
|
|
||||||
return Err(Error::CloseExpungeFailed(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(Error::NoSession);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.config.write().await.selected_folder_needs_expunge = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// select new folder
|
// select new folder
|
||||||
|
|||||||
Reference in New Issue
Block a user