mirror of
https://github.com/chatmail/core.git
synced 2026-05-04 05:46:29 +03:00
refine uid_next handling and rename and resultify configure_folder to ensure_configurer_folders
This commit is contained in:
committed by
Floris Bruynooghe
parent
7be5fe925a
commit
d14c6ea202
@@ -355,13 +355,14 @@ pub fn JobConfigureImap(context: &Context) {
|
|||||||
progress!(context, 900);
|
progress!(context, 900);
|
||||||
let create_mvbox = context.get_config_bool(Config::MvboxWatch)
|
let create_mvbox = context.get_config_bool(Config::MvboxWatch)
|
||||||
|| context.get_config_bool(Config::MvboxMove);
|
|| context.get_config_bool(Config::MvboxMove);
|
||||||
context
|
let imap = &context.inbox_thread.read().unwrap().imap;
|
||||||
.inbox_thread
|
if let Err(err) = imap.ensure_configured_folders(context, create_mvbox) {
|
||||||
.read()
|
error!(context, "configuring folders failed: {:?}", err);
|
||||||
.unwrap()
|
false
|
||||||
.imap
|
} else {
|
||||||
.configure_folders(context, create_mvbox);
|
// XXX call fetch_from_single_folder to set last_seen_uid
|
||||||
true
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
17 => {
|
17 => {
|
||||||
progress!(context, 910);
|
progress!(context, 910);
|
||||||
|
|||||||
146
src/imap.rs
146
src/imap.rs
@@ -318,19 +318,12 @@ impl Imap {
|
|||||||
// the trailing underscore is correct
|
// the trailing underscore is correct
|
||||||
|
|
||||||
if self.connect(context, ¶m) {
|
if self.connect(context, ¶m) {
|
||||||
if context
|
self.ensure_configured_folders(context, true)
|
||||||
.sql
|
} else {
|
||||||
.get_raw_config_int(context, "folders_configured")
|
Err(Error::ImapConnectionFailed(
|
||||||
.unwrap_or_default()
|
format!("{}", param).to_string(),
|
||||||
< 3
|
))
|
||||||
{
|
|
||||||
self.configure_folders(context, true);
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
return Err(Error::ImapConnectionFailed(
|
|
||||||
format!("{}", param).to_string(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// tries connecting to imap account using the specific login
|
/// tries connecting to imap account using the specific login
|
||||||
@@ -558,13 +551,11 @@ impl Imap {
|
|||||||
let config = self.config.read().await;
|
let config = self.config.read().await;
|
||||||
let mailbox = config.selected_mailbox.as_ref().expect("just selected");
|
let mailbox = config.selected_mailbox.as_ref().expect("just selected");
|
||||||
|
|
||||||
ensure!(
|
let new_uid_validity = match mailbox.uid_validity {
|
||||||
mailbox.uid_validity.is_some(),
|
Some(v) => v,
|
||||||
"Cannot get UIDVALIDITY for folder {:?}",
|
None => bail!("Cannot get UIDVALIDITY for folder {:?}", folder.as_ref()),
|
||||||
folder.as_ref()
|
};
|
||||||
);
|
|
||||||
|
|
||||||
let new_uid_validity = mailbox.uid_validity.unwrap();
|
|
||||||
if new_uid_validity != uid_validity {
|
if new_uid_validity != uid_validity {
|
||||||
if mailbox.exists == 0 {
|
if mailbox.exists == 0 {
|
||||||
info!(context, "Folder \"{}\" is empty.", folder.as_ref());
|
info!(context, "Folder \"{}\" is empty.", folder.as_ref());
|
||||||
@@ -579,35 +570,36 @@ impl Imap {
|
|||||||
|
|
||||||
// uid_validity has changed or is being set the first time.
|
// uid_validity has changed or is being set the first time.
|
||||||
// find the last seen uid within the new uid_validity scope.
|
// find the last seen uid within the new uid_validity scope.
|
||||||
|
let new_last_seen_uid = match mailbox.uid_next {
|
||||||
let new_last_seen_uid = if mailbox.uid_next.is_none() {
|
Some(uid_next) => {
|
||||||
warn!(
|
uid_next - 1 // XXX could uid_next be 0?
|
||||||
context,
|
}
|
||||||
"IMAP folder did not report uid_next, falling back to fetching"
|
None => {
|
||||||
);
|
warn!(
|
||||||
if let Some(ref mut session) = &mut *self.session.lock().await {
|
context,
|
||||||
// `FETCH <message sequence number> (UID)`
|
"IMAP folder has no uid_next, fall back to fetching"
|
||||||
// note that we use fetch by sequence number
|
);
|
||||||
// and thus we only need to get exactly the
|
if let Some(ref mut session) = &mut *self.session.lock().await {
|
||||||
// last-index message.
|
// note that we use fetch by sequence number
|
||||||
let set = format!("{}", mailbox.exists);
|
// and thus we only need to get exactly the
|
||||||
match session.fetch(set, JUST_UID).await {
|
// last-index message.
|
||||||
Ok(list) => list[0].uid.unwrap_or_else(|| 0),
|
let set = format!("{}", mailbox.exists);
|
||||||
Err(err) => {
|
match session.fetch(set, JUST_UID).await {
|
||||||
bail!("fetch failed: {:?}", err);
|
Ok(list) => list[0].uid.unwrap_or_default(),
|
||||||
}
|
Err(err) => {
|
||||||
}
|
bail!("fetch failed: {:?}", err);
|
||||||
} else {
|
}
|
||||||
return Err(Error::ImapNoConnection);
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::ImapNoConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
max(0, mailbox.uid_next.unwrap() - 1)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.set_config_last_seen_uid(context, &folder, new_uid_validity, new_last_seen_uid);
|
self.set_config_last_seen_uid(context, &folder, new_uid_validity, new_last_seen_uid);
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
"uid change: new {}/{} current {}/{}",
|
"uid/validity change: new {}/{} current {}/{}",
|
||||||
new_last_seen_uid,
|
new_last_seen_uid,
|
||||||
new_uid_validity,
|
new_uid_validity,
|
||||||
uid_validity,
|
uid_validity,
|
||||||
@@ -635,9 +627,9 @@ impl Imap {
|
|||||||
return Err(Error::ImapNoConnection);
|
return Err(Error::ImapNoConnection);
|
||||||
};
|
};
|
||||||
|
|
||||||
// go through all mails in folder (this is typically _fast_ as we already have the whole list)
|
// prefetch info from all unknown mails in the folder
|
||||||
for msg in &list {
|
for msg in &list {
|
||||||
let cur_uid = msg.uid.unwrap_or_else(|| 0);
|
let cur_uid = msg.uid.unwrap_or_default();
|
||||||
if cur_uid > last_seen_uid {
|
if cur_uid > last_seen_uid {
|
||||||
read_cnt += 1;
|
read_cnt += 1;
|
||||||
|
|
||||||
@@ -1239,19 +1231,35 @@ impl Imap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure_folders(&self, context: &Context, create_mvbox: bool) {
|
pub fn ensure_configured_folders(
|
||||||
|
&self,
|
||||||
|
context: &Context,
|
||||||
|
create_mvbox: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let folders_configured = context
|
||||||
|
.sql
|
||||||
|
.get_raw_config_int(context, "folders_configured");
|
||||||
|
if folders_configured.unwrap_or_default() >= 3 {
|
||||||
|
// the "3" here we increase if we have future updates to
|
||||||
|
// to folder configuration
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
task::block_on(async move {
|
task::block_on(async move {
|
||||||
if !self.is_connected().await {
|
ensure!(
|
||||||
return;
|
self.is_connected().await,
|
||||||
}
|
"cannot configure folders: not connected"
|
||||||
|
);
|
||||||
|
|
||||||
info!(context, "Configuring IMAP-folders.");
|
info!(context, "Configuring IMAP-folders.");
|
||||||
|
|
||||||
if let Some(ref mut session) = &mut *self.session.lock().await {
|
if let Some(ref mut session) = &mut *self.session.lock().await {
|
||||||
let folders = self
|
let folders = match self.list_folders(session, context).await {
|
||||||
.list_folders(session, context)
|
Some(f) => f,
|
||||||
.await
|
None => {
|
||||||
.expect("no folders found");
|
bail!("could not obtain list of imap folders");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let sentbox_folder =
|
let sentbox_folder =
|
||||||
folders
|
folders
|
||||||
@@ -1282,7 +1290,7 @@ impl Imap {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot create MVBOX-folder, using trying INBOX subfolder. ({})",
|
"Cannot create MVBOX-folder, trying to create INBOX subfolder. ({})",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1304,36 +1312,34 @@ impl Imap {
|
|||||||
// that may be used by other MUAs to list folders.
|
// that may be used by other MUAs to list folders.
|
||||||
// for the LIST command, the folder is always visible.
|
// for the LIST command, the folder is always visible.
|
||||||
if let Some(ref mvbox) = mvbox_folder {
|
if let Some(ref mvbox) = mvbox_folder {
|
||||||
// TODO: better error handling
|
if let Err(err) = session.subscribe(mvbox).await {
|
||||||
session.subscribe(mvbox).await.expect("failed to subscribe");
|
warn!(context, "could not subscribe to {:?}: {:?}", mvbox, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.set_raw_config(context, "configured_inbox_folder", Some("INBOX"))
|
.set_raw_config(context, "configured_inbox_folder", Some("INBOX"))?;
|
||||||
.ok();
|
|
||||||
if let Some(ref mvbox_folder) = mvbox_folder {
|
if let Some(ref mvbox_folder) = mvbox_folder {
|
||||||
context
|
context.sql.set_raw_config(
|
||||||
.sql
|
context,
|
||||||
.set_raw_config(context, "configured_mvbox_folder", Some(mvbox_folder))
|
"configured_mvbox_folder",
|
||||||
.ok();
|
Some(mvbox_folder),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
if let Some(ref sentbox_folder) = sentbox_folder {
|
if let Some(ref sentbox_folder) = sentbox_folder {
|
||||||
context
|
context.sql.set_raw_config(
|
||||||
.sql
|
context,
|
||||||
.set_raw_config(
|
"configured_sentbox_folder",
|
||||||
context,
|
Some(sentbox_folder.name()),
|
||||||
"configured_sentbox_folder",
|
)?;
|
||||||
Some(sentbox_folder.name()),
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.set_raw_config_int(context, "folders_configured", 3)
|
.set_raw_config_int(context, "folders_configured", 3)?;
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
info!(context, "FINISHED configuring IMAP-folders.");
|
info!(context, "FINISHED configuring IMAP-folders.");
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/job.rs
22
src/job.rs
@@ -228,13 +228,10 @@ impl Job {
|
|||||||
let imap_inbox = &context.inbox_thread.read().unwrap().imap;
|
let imap_inbox = &context.inbox_thread.read().unwrap().imap;
|
||||||
|
|
||||||
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
||||||
if context
|
if let Err(err) = imap_inbox.ensure_configured_folders(context, true) {
|
||||||
.sql
|
self.try_again_later(TryAgain::StandardDelay, None);
|
||||||
.get_raw_config_int(context, "folders_configured")
|
warn!(context, "could not configure folders: {:?}", err);
|
||||||
.unwrap_or_default()
|
return;
|
||||||
< 3
|
|
||||||
{
|
|
||||||
imap_inbox.configure_folders(context, true);
|
|
||||||
}
|
}
|
||||||
let dest_folder = context
|
let dest_folder = context
|
||||||
.sql
|
.sql
|
||||||
@@ -355,13 +352,10 @@ impl Job {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if 0 != self.param.get_int(Param::AlsoMove).unwrap_or_default() {
|
if 0 != self.param.get_int(Param::AlsoMove).unwrap_or_default() {
|
||||||
if context
|
if let Err(err) = imap_inbox.ensure_configured_folders(context, true) {
|
||||||
.sql
|
self.try_again_later(TryAgain::StandardDelay, None);
|
||||||
.get_raw_config_int(context, "folders_configured")
|
warn!(context, "configuring folders failed: {:?}", err);
|
||||||
.unwrap_or_default()
|
return;
|
||||||
< 3
|
|
||||||
{
|
|
||||||
imap_inbox.configure_folders(context, true);
|
|
||||||
}
|
}
|
||||||
let dest_folder = context
|
let dest_folder = context
|
||||||
.sql
|
.sql
|
||||||
|
|||||||
Reference in New Issue
Block a user