feat: Remove Config::ConfiguredSentboxFolder and everything related

It's used in `fetch_existing_msgs()`, but we can remove it and tell users that they need to
move/copy messages from Sentbox to Inbox so that Delta Chat adds all contacts from them. This way
users will be also informed that Delta Chat needs users to CC/BCC/To themselves to see messages sent
from other MUAs.
This commit is contained in:
iequidoo
2025-09-11 13:42:11 -03:00
committed by iequidoo
parent 18445c09c2
commit a06ba35ce1
7 changed files with 29 additions and 114 deletions

View File

@@ -269,7 +269,7 @@ def test_enable_mvbox_move(acfactory, lp):
assert ac2._evtracker.wait_next_incoming_message().text == "message1"
def test_mvbox_thread_and_sentbox(acfactory, lp):
def test_mvbox_thread_and_trash(acfactory, lp):
lp.sec("ac1: start with mvbox thread")
ac1 = acfactory.new_online_configuring_account(mvbox_move=True)
@@ -279,8 +279,8 @@ def test_mvbox_thread_and_sentbox(acfactory, lp):
lp.sec("ac2 and ac1: waiting for configuration")
acfactory.bring_accounts_online()
lp.sec("ac1: create sentbox")
ac1.direct_imap.create_folder("Sent")
lp.sec("ac1: create trash")
ac1.direct_imap.create_folder("Trash")
ac1.set_config("scan_all_folders_debounce_secs", "0")
ac1.stop_io()
ac1.start_io()
@@ -290,7 +290,7 @@ def test_mvbox_thread_and_sentbox(acfactory, lp):
assert ac2._evtracker.wait_next_incoming_message().text == "message1"
assert ac1.get_config("configured_mvbox_folder") == "DeltaChat"
while ac1.get_config("configured_sentbox_folder") != "Sent":
while ac1.get_config("configured_trash_folder") != "Trash":
ac1._evtracker.get_matching("DC_EVENT_CONNECTIVITY_CHANGED")
@@ -855,9 +855,9 @@ def test_no_draft_if_cant_send(acfactory):
def test_dont_show_emails(acfactory, lp):
"""Most mailboxes have a "Drafts" folder where constantly new emails appear but we don't actually want to show them.
So: If it's outgoing AND there is no Received header AND it's not in the sentbox, then ignore the email.
So: If it's outgoing AND there is no Received header, then ignore the email.
If the draft email is sent out later (i.e. moved to "Sent"), it must be shown.
If the draft email is sent out and received later (i.e. it's in "Inbox"), it must be shown.
Also, test that unknown emails in the Spam folder are not shown."""
ac1 = acfactory.new_online_configuring_account()
@@ -866,7 +866,6 @@ def test_dont_show_emails(acfactory, lp):
acfactory.wait_configured(ac1)
ac1.direct_imap.create_folder("Drafts")
ac1.direct_imap.create_folder("Sent")
ac1.direct_imap.create_folder("Spam")
ac1.direct_imap.create_folder("Junk")
@@ -882,21 +881,7 @@ def test_dont_show_emails(acfactory, lp):
Message-ID: <aepiors@example.org>
Content-Type: text/plain; charset=utf-8
message in Drafts that is moved to Sent later
""".format(
ac1.get_config("configured_addr"),
),
)
ac1.direct_imap.append(
"Sent",
"""
From: ac1 <{}>
Subject: subj
To: alice@example.org
Message-ID: <hsabaeni@example.org>
Content-Type: text/plain; charset=utf-8
message in Sent
message in Drafts received later
""".format(
ac1.get_config("configured_addr"),
),
@@ -976,14 +961,13 @@ def test_dont_show_emails(acfactory, lp):
lp.sec("All prepared, now let DC find the message")
ac1.start_io()
msg = ac1._evtracker.wait_next_messages_changed()
# Wait until each folder was scanned, this is necessary for this test to test what it should test:
ac1._evtracker.wait_idle_inbox_ready()
assert msg.text == "subj message in Sent"
fresh_msgs = list(ac1.get_fresh_messages())
msg = fresh_msgs[0]
chat_msgs = msg.chat.get_messages()
assert len(chat_msgs) == 2
assert len(chat_msgs) == 1
assert any(msg.text == "subj Actually interesting message in Spam" for msg in chat_msgs)
assert not any("unknown.address" in c.get_name() for c in ac1.get_chats())
@@ -991,16 +975,16 @@ def test_dont_show_emails(acfactory, lp):
assert ac1.direct_imap.get_uid_by_message_id("spam.message@junk.org")
ac1.stop_io()
lp.sec("'Send out' the draft, i.e. move it to the Sent folder, and wait for DC to display it this time")
lp.sec("'Send out' the draft by moving it to Inbox, and wait for DC to display it this time")
ac1.direct_imap.select_folder("Drafts")
uid = ac1.direct_imap.get_uid_by_message_id("aepiors@example.org")
ac1.direct_imap.conn.move(uid, "Sent")
ac1.direct_imap.conn.move(uid, "Inbox")
ac1.start_io()
msg2 = ac1._evtracker.wait_next_messages_changed()
assert msg2.text == "subj message in Drafts that is moved to Sent later"
assert len(msg.chat.get_messages()) == 3
assert msg2.text == "subj message in Drafts received later"
assert len(msg.chat.get_messages()) == 2
def test_bot(acfactory, lp):

View File

@@ -281,9 +281,6 @@ pub enum Config {
/// Configured folder for chat messages.
ConfiguredMvboxFolder,
/// Configured "Sent" folder.
ConfiguredSentboxFolder,
/// Configured "Trash" folder.
ConfiguredTrashFolder,

View File

@@ -857,10 +857,6 @@ impl Context {
.get_config(Config::ConfiguredInboxFolder)
.await?
.unwrap_or_else(|| "<unset>".to_string());
let configured_sentbox_folder = self
.get_config(Config::ConfiguredSentboxFolder)
.await?
.unwrap_or_else(|| "<unset>".to_string());
let configured_mvbox_folder = self
.get_config(Config::ConfiguredMvboxFolder)
.await?
@@ -955,7 +951,6 @@ impl Context {
folders_configured.to_string(),
);
res.insert("configured_inbox_folder", configured_inbox_folder);
res.insert("configured_sentbox_folder", configured_sentbox_folder);
res.insert("configured_mvbox_folder", configured_mvbox_folder);
res.insert("configured_trash_folder", configured_trash_folder);
res.insert("mdns_enabled", mdns_enabled.to_string());

View File

@@ -156,7 +156,6 @@ pub enum FolderMeaning {
Spam,
Inbox,
Mvbox,
Sent,
Trash,
/// Virtual folders.
@@ -175,7 +174,6 @@ impl FolderMeaning {
FolderMeaning::Spam => None,
FolderMeaning::Inbox => Some(Config::ConfiguredInboxFolder),
FolderMeaning::Mvbox => Some(Config::ConfiguredMvboxFolder),
FolderMeaning::Sent => Some(Config::ConfiguredSentboxFolder),
FolderMeaning::Trash => Some(Config::ConfiguredTrashFolder),
FolderMeaning::Virtual => None,
}
@@ -798,9 +796,6 @@ impl Imap {
context: &Context,
session: &mut Session,
) -> Result<()> {
add_all_recipients_as_contacts(context, session, Config::ConfiguredSentboxFolder)
.await
.context("failed to get recipients from the sentbox")?;
add_all_recipients_as_contacts(context, session, Config::ConfiguredMvboxFolder)
.await
.context("failed to get recipients from the movebox")?;
@@ -2053,7 +2048,7 @@ async fn spam_target_folder_cfg(
}
}
/// Returns `ConfiguredInboxFolder`, `ConfiguredMvboxFolder` or `ConfiguredSentboxFolder` if
/// Returns `ConfiguredInboxFolder` or `ConfiguredMvboxFolder` if
/// the message needs to be moved from `folder`. Otherwise returns `None`.
pub async fn target_folder_cfg(
context: &Context,
@@ -2142,38 +2137,6 @@ async fn needs_move_to_mvbox(
// but sth. different in others - a hard job.
fn get_folder_meaning_by_name(folder_name: &str) -> FolderMeaning {
// source: <https://stackoverflow.com/questions/2185391/localized-gmail-imap-folders>
const SENT_NAMES: &[&str] = &[
"sent",
"sentmail",
"sent objects",
"gesendet",
"Sent Mail",
"Sendte e-mails",
"Enviados",
"Messages envoyés",
"Messages envoyes",
"Posta inviata",
"Verzonden berichten",
"Wyslane",
"E-mails enviados",
"Correio enviado",
"Enviada",
"Enviado",
"Gönderildi",
"Inviati",
"Odeslaná pošta",
"Sendt",
"Skickat",
"Verzonden",
"Wysłane",
"Éléments envoyés",
"Απεσταλμένα",
"Отправленные",
"寄件備份",
"已发送邮件",
"送信済み",
"보낸편지함",
];
const SPAM_NAMES: &[&str] = &[
"spam",
"junk",
@@ -2219,8 +2182,6 @@ fn get_folder_meaning_by_name(folder_name: &str) -> FolderMeaning {
if lower == "inbox" {
FolderMeaning::Inbox
} else if SENT_NAMES.iter().any(|s| s.to_lowercase() == lower) {
FolderMeaning::Sent
} else if SPAM_NAMES.iter().any(|s| s.to_lowercase() == lower) {
FolderMeaning::Spam
} else if TRASH_NAMES.iter().any(|s| s.to_lowercase() == lower) {
@@ -2234,7 +2195,6 @@ fn get_folder_meaning_by_attrs(folder_attrs: &[NameAttribute]) -> FolderMeaning
for attr in folder_attrs {
match attr {
NameAttribute::Trash => return FolderMeaning::Trash,
NameAttribute::Sent => return FolderMeaning::Sent,
NameAttribute::Junk => return FolderMeaning::Spam,
NameAttribute::All | NameAttribute::Flagged => return FolderMeaning::Virtual,
NameAttribute::Extension(label) => {

View File

@@ -3,17 +3,6 @@ use crate::test_utils::TestContext;
#[test]
fn test_get_folder_meaning_by_name() {
assert_eq!(get_folder_meaning_by_name("Gesendet"), FolderMeaning::Sent);
assert_eq!(get_folder_meaning_by_name("GESENDET"), FolderMeaning::Sent);
assert_eq!(get_folder_meaning_by_name("gesendet"), FolderMeaning::Sent);
assert_eq!(
get_folder_meaning_by_name("Messages envoyés"),
FolderMeaning::Sent
);
assert_eq!(
get_folder_meaning_by_name("mEsSaGes envoyÉs"),
FolderMeaning::Sent
);
assert_eq!(get_folder_meaning_by_name("xxx"), FolderMeaning::Unknown);
assert_eq!(get_folder_meaning_by_name("SPAM"), FolderMeaning::Spam);
assert_eq!(get_folder_meaning_by_name("Trash"), FolderMeaning::Trash);
@@ -119,9 +108,6 @@ async fn check_target_folder_combination(
t.ctx
.set_config(Config::ConfiguredMvboxFolder, Some("DeltaChat"))
.await?;
t.ctx
.set_config(Config::ConfiguredSentboxFolder, Some("Sent"))
.await?;
t.ctx
.set_config(Config::MvboxMove, Some(if mvbox_move { "1" } else { "0" }))
.await?;

View File

@@ -84,21 +84,15 @@ impl Imap {
}
}
// Set configs for necessary folders. Or reset if the folder was deleted.
for conf in [
Config::ConfiguredSentboxFolder,
Config::ConfiguredTrashFolder,
] {
let val = folder_configs.get(&conf).map(|s| s.as_str());
let interrupt = conf == Config::ConfiguredTrashFolder
&& val.is_some()
&& context.get_config(conf).await?.is_none();
context.set_config_internal(conf, val).await?;
if interrupt {
// `Imap::fetch_move_delete()` is possible now for other folders (NB: we are in the
// Inbox loop).
context.scheduler.interrupt_oboxes().await;
}
// Set config for the Trash folder. Or reset if the folder was deleted.
let conf = Config::ConfiguredTrashFolder;
let val = folder_configs.get(&conf).map(|s| s.as_str());
let interrupt = val.is_some() && context.get_config(conf).await?.is_none();
context.set_config_internal(conf, val).await?;
if interrupt {
// `Imap::fetch_move_delete()`, particularly message deletion, is possible now for other
// folders (NB: we are in the Inbox loop).
context.scheduler.interrupt_oboxes().await;
}
info!(context, "Found folders: {folder_names:?}.");

View File

@@ -401,19 +401,18 @@ UPDATE chats SET protected=1, type=120 WHERE type=130;"#,
.await?;
}
if dbversion < 73 {
use Config::*;
sql.execute(
r#"
CREATE TABLE imap_sync (folder TEXT PRIMARY KEY, uidvalidity INTEGER DEFAULT 0, uid_next INTEGER DEFAULT 0);"#,
()
)
.await?;
for c in &[
ConfiguredInboxFolder,
ConfiguredSentboxFolder,
ConfiguredMvboxFolder,
for c in [
"configured_inbox_folder",
"configured_sentbox_folder",
"configured_mvbox_folder",
] {
if let Some(folder) = context.get_config(*c).await? {
if let Some(folder) = context.sql.get_raw_config(c).await? {
let (uid_validity, last_seen_uid) =
imap::get_config_last_seen_uid(context, &folder).await?;
if last_seen_uid > 0 {