Remove inbox_watch option

Also resultified `get_watched_folders`.

Python test `test_moved_markseen` is modified to test using incoming
message instead of BCC-self message, because BCC-self message is
detected immediately in the Inbox.
This commit is contained in:
link2xt
2021-12-25 18:07:14 +00:00
parent 12313543ca
commit 246cae5d9e
8 changed files with 52 additions and 70 deletions

View File

@@ -293,9 +293,6 @@ char* dc_get_blobdir (const dc_context_t* context);
* 1=send a copy of outgoing messages to self. * 1=send a copy of outgoing messages to self.
* Sending messages to self is needed for a proper multi-account setup, * Sending messages to self is needed for a proper multi-account setup,
* however, on the other hand, may lead to unwanted notifications in non-delta clients. * however, on the other hand, may lead to unwanted notifications in non-delta clients.
* - `inbox_watch` = 1=watch `INBOX`-folder for changes (default),
* 0=do not watch the `INBOX`-folder,
* changes require restarting IO by calling dc_stop_io() and then dc_start_io().
* - `sentbox_watch`= 1=watch `Sent`-folder for changes (default), * - `sentbox_watch`= 1=watch `Sent`-folder for changes (default),
* 0=do not watch the `Sent`-folder, * 0=do not watch the `Sent`-folder,
* changes require restarting IO by calling dc_stop_io() and then dc_start_io(). * changes require restarting IO by calling dc_stop_io() and then dc_start_io().

View File

@@ -1039,27 +1039,34 @@ class TestOnlineAccount:
def test_moved_markseen(self, acfactory, lp): def test_moved_markseen(self, acfactory, lp):
"""Test that message already moved to DeltaChat folder is marked as seen.""" """Test that message already moved to DeltaChat folder is marked as seen."""
ac1 = acfactory.get_online_configuring_account(move=True, config={"inbox_watch": "0"}) ac1 = acfactory.get_online_configuring_account()
ac2 = acfactory.get_online_configuring_account() ac2 = acfactory.get_online_configuring_account(move=True)
acfactory.wait_configure_and_start_io([ac1, ac2]) acfactory.wait_configure_and_start_io([ac1, ac2])
ac1.set_config("bcc_self", "1")
ac1.direct_imap.idle_start() ac2.stop_io()
ac2.direct_imap.idle_start()
ac1.create_chat(ac2).send_text("Hello!") ac1.create_chat(ac2).send_text("Hello!")
ac1.direct_imap.idle_check(terminate=True)
ac1.stop_io() # Wait for the message to arrive.
ac2.direct_imap.idle_check(terminate=True)
# Emulate moving of the message to DeltaChat folder by Sieve rule. # Emulate moving of the message to DeltaChat folder by Sieve rule.
# mailcow server contains this rule by default. # mailcow server contains this rule by default.
ac1.direct_imap.conn.move(["*"], "DeltaChat") ac2.direct_imap.conn.move(["*"], "DeltaChat")
ac1.direct_imap.select_folder("DeltaChat") ac2.direct_imap.select_folder("DeltaChat")
ac1.direct_imap.idle_start() ac2.direct_imap.idle_start()
ac1.start_io() ac2.start_io()
ac1.direct_imap.idle_wait_for_seen() msg = ac2._evtracker.wait_next_incoming_message()
ac1.direct_imap.idle_done()
fetch = list(ac1.direct_imap.conn.fetch("*", b'FLAGS').values()) # Accept the contact request.
msg.chat.accept()
ac2.mark_seen_messages([msg])
ac2.direct_imap.idle_wait_for_seen()
ac2.direct_imap.idle_done()
fetch = list(ac2.direct_imap.conn.fetch("*", b'FLAGS').values())
flags = fetch[-1][b'FLAGS'] flags = fetch[-1][b'FLAGS']
is_seen = b'\\Seen' in flags is_seen = b'\\Seen' in flags
assert is_seen assert is_seen
@@ -2117,10 +2124,8 @@ class TestOnlineAccount:
assert msg_back.chat == chat assert msg_back.chat == chat
assert chat.get_profile_image() is None assert chat.get_profile_image() is None
@pytest.mark.parametrize("inbox_watch", ["0", "1"]) def test_connectivity(self, acfactory, lp):
def test_connectivity(self, acfactory, lp, inbox_watch):
ac1, ac2 = acfactory.get_two_online_accounts() ac1, ac2 = acfactory.get_two_online_accounts()
ac1.set_config("inbox_watch", inbox_watch)
ac1.set_config("scan_all_folders_debounce_secs", "0") ac1.set_config("scan_all_folders_debounce_secs", "0")
ac1._evtracker.wait_for_connectivity(const.DC_CONNECTIVITY_CONNECTED) ac1._evtracker.wait_for_connectivity(const.DC_CONNECTIVITY_CONNECTED)
@@ -2621,31 +2626,26 @@ class TestOnlineAccount:
assert received_reply.quoted_text == "hello" assert received_reply.quoted_text == "hello"
assert received_reply.quote.id == out_msg.id assert received_reply.quote.id == out_msg.id
@pytest.mark.parametrize("folder,move,expected_destination,inbox_watch,", [ @pytest.mark.parametrize("folder,move,expected_destination,", [
("xyz", False, "xyz", "1"), # Test that emails are recognized in a random folder but not moved ("xyz", False, "xyz"), # Test that emails are recognized in a random folder but not moved
("xyz", True, "DeltaChat", "1"), # ...emails are found in a random folder and moved to DeltaChat ("xyz", True, "DeltaChat"), # ...emails are found in a random folder and moved to DeltaChat
("Spam", False, "INBOX", "1"), # ...emails are moved from the spam folder to the Inbox ("Spam", False, "INBOX"), # ...emails are moved from the spam folder to the Inbox
("INBOX", False, "INBOX", "0"), # ...emails are found in the `Inbox` folder even if `inbox_watch` is "0"
]) ])
# Testrun.org does not support the CREATE-SPECIAL-USE capability, which means that we can't create a folder with # Testrun.org does not support the CREATE-SPECIAL-USE capability, which means that we can't create a folder with
# the "\Junk" flag (see https://tools.ietf.org/html/rfc6154). So, we can't test spam folder detection by flag. # the "\Junk" flag (see https://tools.ietf.org/html/rfc6154). So, we can't test spam folder detection by flag.
def test_scan_folders(self, acfactory, lp, folder, move, expected_destination, inbox_watch): def test_scan_folders(self, acfactory, lp, folder, move, expected_destination):
"""Delta Chat periodically scans all folders for new messages to make sure we don't miss any.""" """Delta Chat periodically scans all folders for new messages to make sure we don't miss any."""
variant = folder + "-" + str(move) + "-" + expected_destination variant = folder + "-" + str(move) + "-" + expected_destination
lp.sec("Testing variant " + variant) lp.sec("Testing variant " + variant)
ac1 = acfactory.get_online_configuring_account(move=move) ac1 = acfactory.get_online_configuring_account(move=move)
ac2 = acfactory.get_online_configuring_account() ac2 = acfactory.get_online_configuring_account()
ac1.set_config("inbox_watch", inbox_watch)
acfactory.wait_configure(ac1) acfactory.wait_configure(ac1)
ac1.direct_imap.create_folder(folder) ac1.direct_imap.create_folder(folder)
acfactory.wait_configure_and_start_io() acfactory.wait_configure_and_start_io()
# Wait until each folder was selected once and we are IDLEing: # Wait until each folder was selected once and we are IDLEing:
if inbox_watch == "1":
ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state") ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state")
else:
ac1._evtracker.get_info_contains("IMAP-fake-IDLE: no folder, waiting for interrupt")
ac1.stop_io() ac1.stop_io()
# Send a message to ac1 and move it to the mvbox: # Send a message to ac1 and move it to the mvbox:

View File

@@ -67,9 +67,6 @@ pub enum Config {
#[strum(props(default = "1"))] #[strum(props(default = "1"))]
MdnsEnabled, MdnsEnabled,
#[strum(props(default = "1"))]
InboxWatch,
#[strum(props(default = "1"))] #[strum(props(default = "1"))]
SentboxWatch, SentboxWatch,

View File

@@ -322,7 +322,6 @@ impl Context {
Err(err) => format!("<key failure: {}>", err), Err(err) => format!("<key failure: {}>", err),
}; };
let inbox_watch = self.get_config_int(Config::InboxWatch).await?;
let sentbox_watch = self.get_config_int(Config::SentboxWatch).await?; let sentbox_watch = self.get_config_int(Config::SentboxWatch).await?;
let mvbox_move = self.get_config_int(Config::MvboxMove).await?; let mvbox_move = self.get_config_int(Config::MvboxMove).await?;
let sentbox_move = self.get_config_int(Config::SentboxMove).await?; let sentbox_move = self.get_config_int(Config::SentboxMove).await?;
@@ -380,7 +379,6 @@ impl Context {
.await? .await?
.to_string(), .to_string(),
); );
res.insert("inbox_watch", inbox_watch.to_string());
res.insert("sentbox_watch", sentbox_watch.to_string()); res.insert("sentbox_watch", sentbox_watch.to_string());
res.insert("mvbox_move", mvbox_move.to_string()); res.insert("mvbox_move", mvbox_move.to_string());
res.insert("sentbox_move", sentbox_move.to_string()); res.insert("sentbox_move", sentbox_move.to_string());

View File

@@ -29,7 +29,7 @@ impl Imap {
let session = self.session.as_mut(); let session = self.session.as_mut();
let session = session.context("scan_folders(): IMAP No Connection established")?; let session = session.context("scan_folders(): IMAP No Connection established")?;
let folders: Vec<_> = session.list(Some(""), Some("*")).await?.collect().await; 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();
@@ -102,19 +102,21 @@ impl Imap {
} }
} }
pub(crate) async fn get_watched_folders(context: &Context) -> Vec<String> { pub(crate) async fn get_watched_folders(context: &Context) -> Result<Vec<String>> {
let mut res = Vec::new(); let mut res = Vec::new();
if let Some(inbox_folder) = context.get_config(Config::ConfiguredInboxFolder).await? {
res.push(inbox_folder);
}
let folder_watched_configured = &[ let folder_watched_configured = &[
(Config::SentboxWatch, Config::ConfiguredSentboxFolder), (Config::SentboxWatch, Config::ConfiguredSentboxFolder),
(Config::MvboxMove, Config::ConfiguredMvboxFolder), (Config::MvboxMove, Config::ConfiguredMvboxFolder),
(Config::InboxWatch, Config::ConfiguredInboxFolder),
]; ];
for (watched, configured) in folder_watched_configured { for (watched, configured) in folder_watched_configured {
if context.get_config_bool(*watched).await.unwrap_or_default() { if context.get_config_bool(*watched).await? {
if let Ok(Some(folder)) = context.get_config(*configured).await { if let Some(folder) = context.get_config(*configured).await? {
res.push(folder); res.push(folder);
} }
} }
} }
res Ok(res)
} }

View File

@@ -137,7 +137,7 @@ impl Context {
} }
let quota = if imap.can_check_quota() { let quota = if imap.can_check_quota() {
let folders = get_watched_folders(self).await; let folders = get_watched_folders(self).await?;
get_unique_quota_roots_and_usage(folders, imap).await get_unique_quota_roots_and_usage(folders, imap).await
} else { } else {
Err(anyhow!(stock_str::not_supported_by_provider(self).await)) Err(anyhow!(stock_str::not_supported_by_provider(self).await))

View File

@@ -98,35 +98,15 @@ async fn inbox_loop(ctx: Context, started: Sender<()>, inbox_handlers: ImapConne
Some(job) => { Some(job) => {
// Let the fetch run, but return back to the job afterwards. // Let the fetch run, but return back to the job afterwards.
jobs_loaded = 0; jobs_loaded = 0;
if ctx
.get_config_bool(Config::InboxWatch)
.await
.unwrap_or_default()
{
info!(ctx, "postponing imap-job {} to run fetch...", job); info!(ctx, "postponing imap-job {} to run fetch...", job);
fetch(&ctx, &mut connection).await; fetch(&ctx, &mut connection).await;
} }
}
None => { None => {
jobs_loaded = 0; jobs_loaded = 0;
maybe_add_time_based_warnings(&ctx).await; maybe_add_time_based_warnings(&ctx).await;
info = if ctx info = fetch_idle(&ctx, &mut connection, Config::ConfiguredInboxFolder).await;
.get_config_bool(Config::InboxWatch)
.await
.unwrap_or_default()
{
fetch_idle(&ctx, &mut connection, Config::ConfiguredInboxFolder).await
} else {
if let Err(err) = connection.scan_folders(&ctx).await {
warn!(ctx, "{}", err);
connection.connectivity.set_err(&ctx, err).await;
} else {
connection.connectivity.set_not_configured(&ctx).await;
}
connection.fake_idle(&ctx, None).await
};
} }
} }
} }

View File

@@ -362,17 +362,17 @@ impl Context {
[ [
( (
Config::ConfiguredInboxFolder, Config::ConfiguredInboxFolder,
Config::InboxWatch, None,
inbox.state.connectivity.clone(), inbox.state.connectivity.clone(),
), ),
( (
Config::ConfiguredMvboxFolder, Config::ConfiguredMvboxFolder,
Config::MvboxMove, Some(Config::MvboxMove),
mvbox.state.connectivity.clone(), mvbox.state.connectivity.clone(),
), ),
( (
Config::ConfiguredSentboxFolder, Config::ConfiguredSentboxFolder,
Config::SentboxWatch, Some(Config::SentboxWatch),
sentbox.state.connectivity.clone(), sentbox.state.connectivity.clone(),
), ),
], ],
@@ -393,10 +393,18 @@ impl Context {
ret += &format!("<h3>{}</h3><ul>", stock_str::incoming_messages(self).await); ret += &format!("<h3>{}</h3><ul>", stock_str::incoming_messages(self).await);
for (folder, watch, state) in &folders_states { for (folder, watch, state) in &folders_states {
let w = self.get_config(*watch).await.ok_or_log(self); let w = if let Some(watch_config) = *watch {
self.get_config(watch_config)
.await
.ok_or_log(self)
.flatten()
== Some("1".to_string())
} else {
true
};
let mut folder_added = false; let mut folder_added = false;
if w.flatten() == Some("1".to_string()) { if w {
let f = self.get_config(*folder).await.ok_or_log(self).flatten(); let f = self.get_config(*folder).await.ok_or_log(self).flatten();
if let Some(foldername) = f { if let Some(foldername) = f {