diff --git a/src/mimeparser.rs b/src/mimeparser.rs index e61b20c1a..924280eb3 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -1099,6 +1099,32 @@ impl MimeMessage { } } + // Explicitly look for a `text/calendar` part. + // Messages conforming to + // contain `text/calendar` part as an alternative + // to the text or HTML representation. + // + // While we cannot display `text/calendar` and therefore do not prefer it, + // we still make it available by presenting as an attachment + // with a generic filename. + for cur_data in mail.subparts.iter().rev() { + let mimetype = cur_data.ctype.mimetype.parse::()?; + if mimetype.type_() == mime::TEXT && mimetype.subtype() == "calendar" { + let filename = get_attachment_filename(context, cur_data)? + .unwrap_or_else(|| "calendar.ics".to_string()); + self.do_add_single_file_part( + context, + Viewtype::File, + mimetype, + &mail.ctype.mimetype.to_lowercase(), + &mail.get_body_raw()?, + &filename, + is_related, + ) + .await?; + } + } + if !any_part_added { for cur_part in mail.subparts.iter().rev() { if self diff --git a/src/receive_imf/receive_imf_tests.rs b/src/receive_imf/receive_imf_tests.rs index c5dffdc79..6c2e56204 100644 --- a/src/receive_imf/receive_imf_tests.rs +++ b/src/receive_imf/receive_imf_tests.rs @@ -5565,7 +5565,8 @@ async fn test_lookup_key_contact_by_address_self() -> Result<()> { /// messages with three parts: /// `text/plain`, `text/html` and `text/calendar`. /// -/// We display `text/plain` part in this case. +/// We display `text/plain` part in this case, +/// but .ics file is available as an attachment. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_calendar_alternative() -> Result<()> { let mut tcm = TestContextManager::new(); @@ -5574,11 +5575,13 @@ async fn test_calendar_alternative() -> Result<()> { let msg = receive_imf(t, raw, false).await?.unwrap(); assert_eq!(msg.msg_ids.len(), 1); - let text_msg = Message::load_from_db(t, msg.msg_ids[0]).await?; - assert_eq!(text_msg.text, "Subject was here – Hello!"); - assert_eq!(text_msg.viewtype, Viewtype::Text); - assert!(text_msg.has_html()); - let html = text_msg.get_id().get_html(t).await.unwrap().unwrap(); + let calendar_msg = Message::load_from_db(t, msg.msg_ids[0]).await?; + assert_eq!(calendar_msg.text, "Subject was here – Hello!"); + assert_eq!(calendar_msg.viewtype, Viewtype::File); + assert_eq!(calendar_msg.get_filename().unwrap(), "calendar.ics"); + + assert!(calendar_msg.has_html()); + let html = calendar_msg.get_id().get_html(t).await.unwrap().unwrap(); assert_eq!(html, "Hello!"); Ok(())