mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 05:16:28 +03:00
Also resync UIDs in folders that are not configured (#2289)
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- avoid archived, fresh chats #3053
|
- avoid archived, fresh chats #3053
|
||||||
|
- Also resync UIDs in folders that are not configured #2289
|
||||||
- treat "NO" IMAP response to MOVE and COPY commands as an error #3058
|
- treat "NO" IMAP response to MOVE and COPY commands as an error #3058
|
||||||
- Fix a bug where messages in the Spam folder created contact requests #3015
|
- Fix a bug where messages in the Spam folder created contact requests #3015
|
||||||
- Fix a bug where drafts disappeared after some days #3067
|
- Fix a bug where drafts disappeared after some days #3067
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ use std::{collections::BTreeMap, time::Instant};
|
|||||||
|
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::imap::Imap;
|
use crate::imap::Imap;
|
||||||
use crate::{config::Config, log::LogExt};
|
use crate::log::LogExt;
|
||||||
use crate::{context::Context, imap::FolderMeaning};
|
use crate::{context::Context, imap::FolderMeaning};
|
||||||
use async_std::prelude::*;
|
|
||||||
|
use async_std::stream::StreamExt;
|
||||||
|
|
||||||
use super::{get_folder_meaning, get_folder_meaning_by_name};
|
use super::{get_folder_meaning, get_folder_meaning_by_name};
|
||||||
|
|
||||||
@@ -27,22 +29,12 @@ impl Imap {
|
|||||||
info!(context, "Starting full folder scan");
|
info!(context, "Starting full folder scan");
|
||||||
|
|
||||||
self.prepare(context).await?;
|
self.prepare(context).await?;
|
||||||
let session = self.session.as_mut();
|
let folders = self.list_folders(context).await?;
|
||||||
let session = session.context("scan_folders(): IMAP No Connection established")?;
|
|
||||||
let folders: Vec<_> = session.list(Some(""), Some("*")).await?.collect().await;
|
|
||||||
let watched_folders = get_watched_folders(context).await?;
|
let watched_folders = get_watched_folders(context).await?;
|
||||||
|
|
||||||
let mut folder_configs = BTreeMap::new();
|
let mut folder_configs = BTreeMap::new();
|
||||||
|
|
||||||
for folder in folders {
|
for folder in folders {
|
||||||
let folder = match folder {
|
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => {
|
|
||||||
warn!(context, "Can't get folder: {}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Gmail labels are not folders and should be skipped. For example,
|
// Gmail labels are not folders and should be skipped. For example,
|
||||||
// emails appear in the inbox and under "All Mail" as soon as it is
|
// emails appear in the inbox and under "All Mail" as soon as it is
|
||||||
// received. The code used to wrongly conclude that the email had
|
// received. The code used to wrongly conclude that the email had
|
||||||
@@ -101,6 +93,20 @@ impl Imap {
|
|||||||
last_scan.replace(Instant::now());
|
last_scan.replace(Instant::now());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the names of all folders on the IMAP server.
|
||||||
|
pub async fn list_folders(
|
||||||
|
self: &mut Imap,
|
||||||
|
context: &Context,
|
||||||
|
) -> Result<Vec<async_imap::types::Name>> {
|
||||||
|
let session = self.session.as_mut();
|
||||||
|
let session = session.context("No IMAP connection")?;
|
||||||
|
let list = session
|
||||||
|
.list(Some(""), Some("*"))
|
||||||
|
.await?
|
||||||
|
.filter_map(|f| f.ok_or_log_msg(context, "list_folders() can't get folder"));
|
||||||
|
Ok(list.collect().await)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_watched_folder_configs(context: &Context) -> Result<Vec<Config>> {
|
pub(crate) async fn get_watched_folder_configs(context: &Context) -> Result<Vec<Config>> {
|
||||||
|
|||||||
37
src/job.rs
37
src/job.rs
@@ -365,29 +365,38 @@ impl Job {
|
|||||||
Status::Finished(Ok(()))
|
Status::Finished(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronizes UIDs for sentbox, inbox and mvbox.
|
/// Synchronizes UIDs for all folders.
|
||||||
async fn resync_folders(&mut self, context: &Context, imap: &mut Imap) -> Status {
|
async fn resync_folders(&mut self, context: &Context, imap: &mut Imap) -> Status {
|
||||||
if let Err(err) = imap.prepare(context).await {
|
if let Err(err) = imap.prepare(context).await {
|
||||||
warn!(context, "could not connect: {:?}", err);
|
warn!(context, "could not connect: {:?}", err);
|
||||||
return Status::RetryLater;
|
return Status::RetryLater;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sentbox_folder = job_try!(context.get_config(Config::ConfiguredSentboxFolder).await);
|
let all_folders = match imap.list_folders(context).await {
|
||||||
if let Some(sentbox_folder) = sentbox_folder {
|
Ok(v) => v,
|
||||||
job_try!(imap.resync_folder_uids(context, sentbox_folder).await);
|
Err(e) => {
|
||||||
|
warn!(context, "Listing folders for resync failed: {:#}", e);
|
||||||
|
return Status::RetryLater;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut any_failed = false;
|
||||||
|
|
||||||
|
for folder in all_folders {
|
||||||
|
if let Err(e) = imap
|
||||||
|
.resync_folder_uids(context, folder.name().to_string())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
warn!(context, "{:#}", e);
|
||||||
|
any_failed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inbox_folder = job_try!(context.get_config(Config::ConfiguredInboxFolder).await);
|
if any_failed {
|
||||||
if let Some(inbox_folder) = inbox_folder {
|
Status::RetryLater
|
||||||
job_try!(imap.resync_folder_uids(context, inbox_folder).await);
|
} else {
|
||||||
|
Status::Finished(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let mvbox_folder = job_try!(context.get_config(Config::ConfiguredMvboxFolder).await);
|
|
||||||
if let Some(mvbox_folder) = mvbox_folder {
|
|
||||||
job_try!(imap.resync_folder_uids(context, mvbox_folder).await);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status::Finished(Ok(()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn markseen_msg_on_imap(&mut self, context: &Context, imap: &mut Imap) -> Status {
|
async fn markseen_msg_on_imap(&mut self, context: &Context, imap: &mut Imap) -> Status {
|
||||||
|
|||||||
Reference in New Issue
Block a user