From f8680724f81730c817cb10fae26e56658b8dbfeb Mon Sep 17 00:00:00 2001 From: Hocuri Date: Tue, 14 Apr 2020 21:38:28 +0200 Subject: [PATCH] Set subject to Re: for better compability with normal MUAs The code in dc_receive_imf.rs looks a bit funny, an alternative would be a function: fn upcate_chat_last_subject(context: &Context, chat_id: &ChatId, mime_parser: &mut MimeMessage) -> Result<()> { let mut chat = Chat::load_from_db(context, *chat_id)?; chat.param.set(Param::LastSubject, mime_parser.get_subject().ok_or_else(||Error::Message("No subject in email".to_string()))?); chat.update_param(context)?; Ok(()) } --- src/dc_receive_imf.rs | 21 +++++- src/mimefactory.rs | 157 +++++++++++++++++++++++++++++++++++++++--- src/param.rs | 3 + 3 files changed, 170 insertions(+), 11 deletions(-) diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 38191ddff..1460043a8 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -10,7 +10,7 @@ use crate::constants::*; use crate::contact::*; use crate::context::Context; use crate::dc_tools::*; -use crate::error::{bail, ensure, Result}; +use crate::error::{bail, ensure, format_err, Result}; use crate::events::Event; use crate::headerdef::HeaderDef; use crate::job::{self, Action}; @@ -749,6 +749,25 @@ async fn add_parts( } } + || -> Result<()> { + let mut chat = Chat::load_from_db(context, *chat_id)?; + chat.param.set( + Param::LastSubject, + mime_parser + .get_subject() + .ok_or_else(|| format_err!("No subject in email"))?, + ); + chat.update_param(context)?; + Ok(()) + }() + .unwrap_or_else(|e| { + warn!( + context, + "Could not update LastSubject of chat: {}", + e.to_string() + ) + }); + Ok(()) } diff --git a/src/mimefactory.rs b/src/mimefactory.rs index e17cf668e..f0b58eaf7 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -351,16 +351,41 @@ impl<'a, 'b> MimeFactory<'a, 'b> { }; format!("{}{}", re, chat.name) } else { - let raw = message::get_summarytext_by_raw( - self.msg.viewtype, - self.msg.text.as_ref(), - &self.msg.param, - 32, - self.context, - ) - .await; - let raw_subject = raw.lines().next().unwrap_or_default(); - format!("Chat: {}", raw_subject) + match chat.param.get(Param::LastSubject) { + Some(last_subject) => { + let subject_start = if last_subject.starts_with("Chat:") { + 0 + } else { + // "Antw:" is the longest abbreviation in + // https://en.wikipedia.org/wiki/List_of_email_subject_abbreviations#Abbreviations_in_other_languages, + // so look at the first _5_ characters: + match last_subject.chars().take(5).position(|c| c == ':') { + Some(prefix_end) => prefix_end + 1, + None => 0, + } + }; + format!( + "Re: {}", + last_subject + .chars() + .skip(subject_start) + .collect::() + .trim() + ) + } + None => { + let raw = message::get_summarytext_by_raw( + self.msg.viewtype, + Some(""), + &self.msg.param, + 32, + self.context, + ) + .await; + let raw_subject = raw.lines().next().unwrap_or_default(); + format!("Chat: {}", raw_subject) + } + } } } Loaded::MDN { .. } => self @@ -1234,4 +1259,116 @@ mod tests { assert!(needs_encoding(" ")); assert!(needs_encoding("foo bar")); } + + use crate::test_utils::{dummy_context, TestContext}; + + fn configured_offline_context() -> TestContext { + let t = dummy_context(); + t.ctx + .set_config(Config::Addr, Some("alice@example.org")) + .unwrap(); + t.ctx + .set_config(Config::ConfiguredAddr, Some("alice@example.org")) + .unwrap(); + t.ctx.set_config(Config::Configured, Some("1")).unwrap(); + t + } + + #[test] + fn test_subject() { + // 1.: Receive a mail from an MUA or Delta Chat + assert_eq!( + msg_to_subject_str( + b"From: Bob \n\ + To: alice@example.org\n\ + Subject: Antw: Chat: hello\n\ + Message-ID: <2222@example.org>\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ + \n\ + hello\n" + ), + "Re: Chat: hello" + ); + + // 2. Receive a message from Delta Chat when we did not send any messages before + assert_eq!( + msg_to_subject_str( + b"From: Charlie \n\ + To: alice@example.org\n\ + Subject: Chat: hello\n\ + Chat-Version: 1.0\n\ + Message-ID: <2223@example.org>\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ + \n\ + hello\n" + ), + "Re: Chat: hello" + ); + + // 3. Send the first message to a new contact + let t = configured_offline_context(); + t.ctx.set_config(Config::ShowEmails, Some("2")).unwrap(); + + let contact_id = + Contact::add_or_lookup(&t.ctx, "Dave", "dave@example.org", Origin::ManuallyCreated) + .unwrap() + .0; + + let chat_id = chat::create_by_contact_id(&t.ctx, contact_id).unwrap(); + + let mut new_msg = Message::new(Viewtype::Text); + new_msg.set_text(Some("Hi".to_string())); + new_msg.chat_id = chat_id; + chat::prepare_msg(&t.ctx, chat_id, &mut new_msg).unwrap(); + + let mf = MimeFactory::from_msg(&t.ctx, &new_msg, false).unwrap(); + assert_eq!(mf.subject_str(), "Chat: "); + + // 4. Receive messages with unicode characters and make sure that we do not panic (we do not care about the result) + msg_to_subject_str( + "From: Charlie \n\ + To: alice@example.org\n\ + Subject: äääää\n\ + Chat-Version: 1.0\n\ + Message-ID: <2893@example.org>\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ + \n\ + hello\n" + .as_bytes(), + ); + + msg_to_subject_str( + "From: Charlie \n\ + To: alice@example.org\n\ + Subject: aäääää\n\ + Chat-Version: 1.0\n\ + Message-ID: <2893@example.org>\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ + \n\ + hello\n" + .as_bytes(), + ); + } + + fn msg_to_subject_str(imf_raw: &[u8]) -> String { + use crate::chatlist::Chatlist; + use crate::dc_receive_imf::dc_receive_imf; + + let t = configured_offline_context(); + t.ctx.set_config(Config::ShowEmails, Some("2")).unwrap(); + + dc_receive_imf(&t.ctx, imf_raw, "INBOX", 1, false).unwrap(); + + let chats = Chatlist::try_load(&t.ctx, 0, None, None).unwrap(); + + let chat_id = chat::create_by_msg_id(&t.ctx, chats.get_msg_id(0).unwrap()).unwrap(); + + let mut new_msg = Message::new(Viewtype::Text); + new_msg.set_text(Some("Hi".to_string())); + new_msg.chat_id = chat_id; + chat::prepare_msg(&t.ctx, chat_id, &mut new_msg).unwrap(); + + let mf = MimeFactory::from_msg(&t.ctx, &new_msg, false).unwrap(); + mf.subject_str() + } } diff --git a/src/param.rs b/src/param.rs index 7d72adad9..7e2d8f08c 100644 --- a/src/param.rs +++ b/src/param.rs @@ -103,6 +103,9 @@ pub enum Param { /// For Chats Selftalk = b'K', + /// For Chats: So that on sending a new message we can sent the subject to "Re: " + LastSubject = b't', + /// For Chats Devicetalk = b'D',