Revert "imap: simplify select_folder() interface"

This reverts commit b614de2f80.
This commit is contained in:
Alexander Krotov
2020-05-12 00:32:18 +03:00
committed by holger krekel
parent 0594034ee6
commit 3ee81cbee0
4 changed files with 46 additions and 42 deletions

View File

@@ -59,7 +59,7 @@ impl Imap {
task::block_on(async move { self.config.read().await.can_idle }) task::block_on(async move { self.config.read().await.can_idle })
} }
pub fn idle(&self, context: &Context, watch_folder: String) -> Result<()> { pub fn idle(&self, context: &Context, watch_folder: Option<String>) -> Result<()> {
task::block_on(async move { task::block_on(async move {
if !self.can_idle() { if !self.can_idle() {
return Err(Error::IdleAbilityMissing); return Err(Error::IdleAbilityMissing);
@@ -67,7 +67,7 @@ impl Imap {
self.setup_handle_if_needed(context).await?; self.setup_handle_if_needed(context).await?;
self.select_folder(context, watch_folder).await?; self.select_folder(context, watch_folder.clone()).await?;
let session = self.session.lock().await.take(); let session = self.session.lock().await.take();
let timeout = Duration::from_secs(23 * 60); let timeout = Duration::from_secs(23 * 60);

View File

@@ -477,7 +477,7 @@ impl Imap {
folder: &str, folder: &str,
) -> Result<(u32, u32)> { ) -> Result<(u32, u32)> {
task::block_on(async move { task::block_on(async move {
self.select_folder(context, folder).await?; self.select_folder(context, Some(folder)).await?;
// compare last seen UIDVALIDITY against the current one // compare last seen UIDVALIDITY against the current one
let (uid_validity, last_seen_uid) = self.get_config_last_seen_uid(context, &folder); let (uid_validity, last_seen_uid) = self.get_config_last_seen_uid(context, &folder);
@@ -915,7 +915,7 @@ impl Imap {
return Some(ImapActionResult::RetryLater); return Some(ImapActionResult::RetryLater);
} }
} }
match self.select_folder(context, &folder).await { match self.select_folder(context, Some(&folder)).await {
Ok(()) => None, Ok(()) => None,
Err(select_folder::Error::ConnectionLost) => { Err(select_folder::Error::ConnectionLost) => {
warn!(context, "Lost imap connection"); warn!(context, "Lost imap connection");
@@ -1186,7 +1186,7 @@ impl Imap {
error!(context, "could not setup imap connection: {}", err); error!(context, "could not setup imap connection: {}", err);
return; return;
} }
if let Err(err) = self.select_folder(context, &folder).await { if let Err(err) = self.select_folder(context, Some(&folder)).await {
error!( error!(
context, context,
"Could not select {} for expunging: {}", folder, err "Could not select {} for expunging: {}", folder, err
@@ -1204,7 +1204,7 @@ impl Imap {
// we now trigger expunge to actually delete messages // we now trigger expunge to actually delete messages
self.config.write().await.selected_folder_needs_expunge = true; self.config.write().await.selected_folder_needs_expunge = true;
match self.select_folder(context, &folder).await { match self.select_folder::<String>(context, None).await {
Ok(()) => { Ok(()) => {
emit_event!(context, Event::ImapFolderEmptied(folder.to_string())); emit_event!(context, Event::ImapFolderEmptied(folder.to_string()));
} }

View File

@@ -56,7 +56,7 @@ impl Imap {
pub(super) async fn select_folder<S: AsRef<str>>( pub(super) async fn select_folder<S: AsRef<str>>(
&self, &self,
context: &Context, context: &Context,
folder: S, folder: Option<S>,
) -> Result<()> { ) -> Result<()> {
if self.session.lock().await.is_none() { if self.session.lock().await.is_none() {
let mut cfg = self.config.write().await; let mut cfg = self.config.write().await;
@@ -71,41 +71,46 @@ impl Imap {
self.close_folder(context).await?; self.close_folder(context).await?;
} }
if self.config.read().await.selected_folder.as_deref() == Some(folder.as_ref()) { let folder_str: Option<&str> = folder.as_ref().map(|x| x.as_ref());
if self.config.read().await.selected_folder.as_deref() == folder_str {
return Ok(()); return Ok(());
} }
// select new folder // select new folder
if let Some(ref mut session) = &mut *self.session.lock().await { if let Some(ref folder) = folder {
let res = session.select(&folder).await; if let Some(ref mut session) = &mut *self.session.lock().await {
let res = session.select(folder).await;
// https://tools.ietf.org/html/rfc3501#section-6.3.1 // https://tools.ietf.org/html/rfc3501#section-6.3.1
// says that if the server reports select failure we are in // says that if the server reports select failure we are in
// authenticated (not-select) state. // authenticated (not-select) state.
match res { match res {
Ok(mailbox) => { Ok(mailbox) => {
let mut config = self.config.write().await; let mut config = self.config.write().await;
config.selected_folder = Some(folder.as_ref().to_string()); config.selected_folder = Some(folder.as_ref().to_string());
config.selected_mailbox = Some(mailbox); config.selected_mailbox = Some(mailbox);
Ok(()) Ok(())
} }
Err(async_imap::error::Error::ConnectionLost) => { Err(async_imap::error::Error::ConnectionLost) => {
self.trigger_reconnect(); self.trigger_reconnect();
self.config.write().await.selected_folder = None; self.config.write().await.selected_folder = None;
Err(Error::ConnectionLost) Err(Error::ConnectionLost)
} }
Err(async_imap::error::Error::Validate(_)) => { Err(async_imap::error::Error::Validate(_)) => {
Err(Error::BadFolderName(folder.as_ref().to_string())) Err(Error::BadFolderName(folder.as_ref().to_string()))
} }
Err(err) => { Err(err) => {
self.config.write().await.selected_folder = None; self.config.write().await.selected_folder = None;
self.trigger_reconnect(); self.trigger_reconnect();
Err(Error::Other(err.to_string())) Err(Error::Other(err.to_string()))
}
} }
} else {
Err(Error::NoSession)
} }
} else { } else {
Err(Error::NoSession) Ok(())
} }
} }
} }

View File

@@ -173,15 +173,14 @@ impl JobThread {
if !self.imap.can_idle() { if !self.imap.can_idle() {
true // we have to do fake_idle true // we have to do fake_idle
} else { } else {
if let Some(watch_folder) = self.get_watch_folder(context) { let watch_folder = self.get_watch_folder(context);
info!(context, "{} started...", prefix); info!(context, "{} started...", prefix);
let res = self.imap.idle(context, watch_folder); let res = self.imap.idle(context, watch_folder);
info!(context, "{} ended...", prefix); info!(context, "{} ended...", prefix);
if let Err(err) = res { if let Err(err) = res {
warn!(context, "{} failed: {} -> reconnecting", prefix, err); warn!(context, "{} failed: {} -> reconnecting", prefix, err);
// something is Label { Label }orked, let's start afresh on the next occassion // something is borked, let's start afresh on the next occassion
self.imap.disconnect(context); self.imap.disconnect(context);
}
} }
false false
} }