mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
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:
@@ -269,7 +269,7 @@ def test_enable_mvbox_move(acfactory, lp):
|
|||||||
assert ac2._evtracker.wait_next_incoming_message().text == "message1"
|
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")
|
lp.sec("ac1: start with mvbox thread")
|
||||||
ac1 = acfactory.new_online_configuring_account(mvbox_move=True)
|
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")
|
lp.sec("ac2 and ac1: waiting for configuration")
|
||||||
acfactory.bring_accounts_online()
|
acfactory.bring_accounts_online()
|
||||||
|
|
||||||
lp.sec("ac1: create sentbox")
|
lp.sec("ac1: create trash")
|
||||||
ac1.direct_imap.create_folder("Sent")
|
ac1.direct_imap.create_folder("Trash")
|
||||||
ac1.set_config("scan_all_folders_debounce_secs", "0")
|
ac1.set_config("scan_all_folders_debounce_secs", "0")
|
||||||
ac1.stop_io()
|
ac1.stop_io()
|
||||||
ac1.start_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 ac2._evtracker.wait_next_incoming_message().text == "message1"
|
||||||
|
|
||||||
assert ac1.get_config("configured_mvbox_folder") == "DeltaChat"
|
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")
|
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):
|
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.
|
"""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."""
|
Also, test that unknown emails in the Spam folder are not shown."""
|
||||||
ac1 = acfactory.new_online_configuring_account()
|
ac1 = acfactory.new_online_configuring_account()
|
||||||
@@ -866,7 +866,6 @@ def test_dont_show_emails(acfactory, lp):
|
|||||||
|
|
||||||
acfactory.wait_configured(ac1)
|
acfactory.wait_configured(ac1)
|
||||||
ac1.direct_imap.create_folder("Drafts")
|
ac1.direct_imap.create_folder("Drafts")
|
||||||
ac1.direct_imap.create_folder("Sent")
|
|
||||||
ac1.direct_imap.create_folder("Spam")
|
ac1.direct_imap.create_folder("Spam")
|
||||||
ac1.direct_imap.create_folder("Junk")
|
ac1.direct_imap.create_folder("Junk")
|
||||||
|
|
||||||
@@ -882,21 +881,7 @@ def test_dont_show_emails(acfactory, lp):
|
|||||||
Message-ID: <aepiors@example.org>
|
Message-ID: <aepiors@example.org>
|
||||||
Content-Type: text/plain; charset=utf-8
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
message in Drafts that is moved to Sent later
|
message in Drafts received 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
|
|
||||||
""".format(
|
""".format(
|
||||||
ac1.get_config("configured_addr"),
|
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")
|
lp.sec("All prepared, now let DC find the message")
|
||||||
ac1.start_io()
|
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:
|
# Wait until each folder was scanned, this is necessary for this test to test what it should test:
|
||||||
ac1._evtracker.wait_idle_inbox_ready()
|
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()
|
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 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())
|
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")
|
assert ac1.direct_imap.get_uid_by_message_id("spam.message@junk.org")
|
||||||
|
|
||||||
ac1.stop_io()
|
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")
|
ac1.direct_imap.select_folder("Drafts")
|
||||||
uid = ac1.direct_imap.get_uid_by_message_id("aepiors@example.org")
|
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()
|
ac1.start_io()
|
||||||
msg2 = ac1._evtracker.wait_next_messages_changed()
|
msg2 = ac1._evtracker.wait_next_messages_changed()
|
||||||
|
|
||||||
assert msg2.text == "subj – message in Drafts that is moved to Sent later"
|
assert msg2.text == "subj – message in Drafts received later"
|
||||||
assert len(msg.chat.get_messages()) == 3
|
assert len(msg.chat.get_messages()) == 2
|
||||||
|
|
||||||
|
|
||||||
def test_bot(acfactory, lp):
|
def test_bot(acfactory, lp):
|
||||||
|
|||||||
@@ -281,9 +281,6 @@ pub enum Config {
|
|||||||
/// Configured folder for chat messages.
|
/// Configured folder for chat messages.
|
||||||
ConfiguredMvboxFolder,
|
ConfiguredMvboxFolder,
|
||||||
|
|
||||||
/// Configured "Sent" folder.
|
|
||||||
ConfiguredSentboxFolder,
|
|
||||||
|
|
||||||
/// Configured "Trash" folder.
|
/// Configured "Trash" folder.
|
||||||
ConfiguredTrashFolder,
|
ConfiguredTrashFolder,
|
||||||
|
|
||||||
|
|||||||
@@ -857,10 +857,6 @@ impl Context {
|
|||||||
.get_config(Config::ConfiguredInboxFolder)
|
.get_config(Config::ConfiguredInboxFolder)
|
||||||
.await?
|
.await?
|
||||||
.unwrap_or_else(|| "<unset>".to_string());
|
.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
|
let configured_mvbox_folder = self
|
||||||
.get_config(Config::ConfiguredMvboxFolder)
|
.get_config(Config::ConfiguredMvboxFolder)
|
||||||
.await?
|
.await?
|
||||||
@@ -955,7 +951,6 @@ impl Context {
|
|||||||
folders_configured.to_string(),
|
folders_configured.to_string(),
|
||||||
);
|
);
|
||||||
res.insert("configured_inbox_folder", configured_inbox_folder);
|
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_mvbox_folder", configured_mvbox_folder);
|
||||||
res.insert("configured_trash_folder", configured_trash_folder);
|
res.insert("configured_trash_folder", configured_trash_folder);
|
||||||
res.insert("mdns_enabled", mdns_enabled.to_string());
|
res.insert("mdns_enabled", mdns_enabled.to_string());
|
||||||
|
|||||||
42
src/imap.rs
42
src/imap.rs
@@ -156,7 +156,6 @@ pub enum FolderMeaning {
|
|||||||
Spam,
|
Spam,
|
||||||
Inbox,
|
Inbox,
|
||||||
Mvbox,
|
Mvbox,
|
||||||
Sent,
|
|
||||||
Trash,
|
Trash,
|
||||||
|
|
||||||
/// Virtual folders.
|
/// Virtual folders.
|
||||||
@@ -175,7 +174,6 @@ impl FolderMeaning {
|
|||||||
FolderMeaning::Spam => None,
|
FolderMeaning::Spam => None,
|
||||||
FolderMeaning::Inbox => Some(Config::ConfiguredInboxFolder),
|
FolderMeaning::Inbox => Some(Config::ConfiguredInboxFolder),
|
||||||
FolderMeaning::Mvbox => Some(Config::ConfiguredMvboxFolder),
|
FolderMeaning::Mvbox => Some(Config::ConfiguredMvboxFolder),
|
||||||
FolderMeaning::Sent => Some(Config::ConfiguredSentboxFolder),
|
|
||||||
FolderMeaning::Trash => Some(Config::ConfiguredTrashFolder),
|
FolderMeaning::Trash => Some(Config::ConfiguredTrashFolder),
|
||||||
FolderMeaning::Virtual => None,
|
FolderMeaning::Virtual => None,
|
||||||
}
|
}
|
||||||
@@ -798,9 +796,6 @@ impl Imap {
|
|||||||
context: &Context,
|
context: &Context,
|
||||||
session: &mut Session,
|
session: &mut Session,
|
||||||
) -> Result<()> {
|
) -> 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)
|
add_all_recipients_as_contacts(context, session, Config::ConfiguredMvboxFolder)
|
||||||
.await
|
.await
|
||||||
.context("failed to get recipients from the movebox")?;
|
.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`.
|
/// the message needs to be moved from `folder`. Otherwise returns `None`.
|
||||||
pub async fn target_folder_cfg(
|
pub async fn target_folder_cfg(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
@@ -2142,38 +2137,6 @@ async fn needs_move_to_mvbox(
|
|||||||
// but sth. different in others - a hard job.
|
// but sth. different in others - a hard job.
|
||||||
fn get_folder_meaning_by_name(folder_name: &str) -> FolderMeaning {
|
fn get_folder_meaning_by_name(folder_name: &str) -> FolderMeaning {
|
||||||
// source: <https://stackoverflow.com/questions/2185391/localized-gmail-imap-folders>
|
// 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] = &[
|
const SPAM_NAMES: &[&str] = &[
|
||||||
"spam",
|
"spam",
|
||||||
"junk",
|
"junk",
|
||||||
@@ -2219,8 +2182,6 @@ fn get_folder_meaning_by_name(folder_name: &str) -> FolderMeaning {
|
|||||||
|
|
||||||
if lower == "inbox" {
|
if lower == "inbox" {
|
||||||
FolderMeaning::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) {
|
} else if SPAM_NAMES.iter().any(|s| s.to_lowercase() == lower) {
|
||||||
FolderMeaning::Spam
|
FolderMeaning::Spam
|
||||||
} else if TRASH_NAMES.iter().any(|s| s.to_lowercase() == lower) {
|
} 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 {
|
for attr in folder_attrs {
|
||||||
match attr {
|
match attr {
|
||||||
NameAttribute::Trash => return FolderMeaning::Trash,
|
NameAttribute::Trash => return FolderMeaning::Trash,
|
||||||
NameAttribute::Sent => return FolderMeaning::Sent,
|
|
||||||
NameAttribute::Junk => return FolderMeaning::Spam,
|
NameAttribute::Junk => return FolderMeaning::Spam,
|
||||||
NameAttribute::All | NameAttribute::Flagged => return FolderMeaning::Virtual,
|
NameAttribute::All | NameAttribute::Flagged => return FolderMeaning::Virtual,
|
||||||
NameAttribute::Extension(label) => {
|
NameAttribute::Extension(label) => {
|
||||||
|
|||||||
@@ -3,17 +3,6 @@ use crate::test_utils::TestContext;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_folder_meaning_by_name() {
|
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("xxx"), FolderMeaning::Unknown);
|
||||||
assert_eq!(get_folder_meaning_by_name("SPAM"), FolderMeaning::Spam);
|
assert_eq!(get_folder_meaning_by_name("SPAM"), FolderMeaning::Spam);
|
||||||
assert_eq!(get_folder_meaning_by_name("Trash"), FolderMeaning::Trash);
|
assert_eq!(get_folder_meaning_by_name("Trash"), FolderMeaning::Trash);
|
||||||
@@ -119,9 +108,6 @@ async fn check_target_folder_combination(
|
|||||||
t.ctx
|
t.ctx
|
||||||
.set_config(Config::ConfiguredMvboxFolder, Some("DeltaChat"))
|
.set_config(Config::ConfiguredMvboxFolder, Some("DeltaChat"))
|
||||||
.await?;
|
.await?;
|
||||||
t.ctx
|
|
||||||
.set_config(Config::ConfiguredSentboxFolder, Some("Sent"))
|
|
||||||
.await?;
|
|
||||||
t.ctx
|
t.ctx
|
||||||
.set_config(Config::MvboxMove, Some(if mvbox_move { "1" } else { "0" }))
|
.set_config(Config::MvboxMove, Some(if mvbox_move { "1" } else { "0" }))
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -84,21 +84,15 @@ impl Imap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set configs for necessary folders. Or reset if the folder was deleted.
|
// Set config for the Trash folder. Or reset if the folder was deleted.
|
||||||
for conf in [
|
let conf = Config::ConfiguredTrashFolder;
|
||||||
Config::ConfiguredSentboxFolder,
|
let val = folder_configs.get(&conf).map(|s| s.as_str());
|
||||||
Config::ConfiguredTrashFolder,
|
let interrupt = val.is_some() && context.get_config(conf).await?.is_none();
|
||||||
] {
|
context.set_config_internal(conf, val).await?;
|
||||||
let val = folder_configs.get(&conf).map(|s| s.as_str());
|
if interrupt {
|
||||||
let interrupt = conf == Config::ConfiguredTrashFolder
|
// `Imap::fetch_move_delete()`, particularly message deletion, is possible now for other
|
||||||
&& val.is_some()
|
// folders (NB: we are in the Inbox loop).
|
||||||
&& context.get_config(conf).await?.is_none();
|
context.scheduler.interrupt_oboxes().await;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(context, "Found folders: {folder_names:?}.");
|
info!(context, "Found folders: {folder_names:?}.");
|
||||||
|
|||||||
@@ -401,19 +401,18 @@ UPDATE chats SET protected=1, type=120 WHERE type=130;"#,
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
if dbversion < 73 {
|
if dbversion < 73 {
|
||||||
use Config::*;
|
|
||||||
sql.execute(
|
sql.execute(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE imap_sync (folder TEXT PRIMARY KEY, uidvalidity INTEGER DEFAULT 0, uid_next INTEGER DEFAULT 0);"#,
|
CREATE TABLE imap_sync (folder TEXT PRIMARY KEY, uidvalidity INTEGER DEFAULT 0, uid_next INTEGER DEFAULT 0);"#,
|
||||||
()
|
()
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
for c in &[
|
for c in [
|
||||||
ConfiguredInboxFolder,
|
"configured_inbox_folder",
|
||||||
ConfiguredSentboxFolder,
|
"configured_sentbox_folder",
|
||||||
ConfiguredMvboxFolder,
|
"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) =
|
let (uid_validity, last_seen_uid) =
|
||||||
imap::get_config_last_seen_uid(context, &folder).await?;
|
imap::get_config_last_seen_uid(context, &folder).await?;
|
||||||
if last_seen_uid > 0 {
|
if last_seen_uid > 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user