diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 4e23d7698..f82f89c15 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -63,6 +63,10 @@ pub(crate) struct MimeMessage { /// Whether the From address was repeated in the signed part /// (and we know that the signer intended to send from this address) pub from_is_signed: bool, + + /// List-Id header as defined in . + pub list_id: Option, + pub list_post: Option, pub chat_disposition_notification_to: Option, pub decryption_info: DecryptionInfo, @@ -212,6 +216,7 @@ impl MimeMessage { let mut headers = Default::default(); let mut recipients = Default::default(); let mut from = Default::default(); + let mut list_id = Default::default(); let mut list_post = Default::default(); let mut chat_disposition_notification_to = None; @@ -221,6 +226,7 @@ impl MimeMessage { &mut headers, &mut recipients, &mut from, + &mut list_id, &mut list_post, &mut chat_disposition_notification_to, &mail.headers, @@ -239,6 +245,7 @@ impl MimeMessage { &mut headers, &mut recipients, &mut from, + &mut list_id, &mut list_post, &mut chat_disposition_notification_to, &part.headers, @@ -344,6 +351,7 @@ impl MimeMessage { &mut headers, &mut recipients, &mut signed_from, + &mut list_id, &mut list_post, &mut chat_disposition_notification_to, &mail.headers, @@ -386,6 +394,7 @@ impl MimeMessage { parts: Vec::new(), header: headers, recipients, + list_id, list_post, from, from_is_signed, @@ -1375,6 +1384,7 @@ impl MimeMessage { headers: &mut HashMap, recipients: &mut Vec, from: &mut Option, + list_id: &mut Option, list_post: &mut Option, chat_disposition_notification_to: &mut Option, fields: &[mailparse::MailHeader<'_>], @@ -1392,6 +1402,14 @@ impl MimeMessage { } Err(e) => warn!(context, "Could not read {} address: {}", key, e), } + } else if key == HeaderDef::ListId.get_headername() { + match addrparse_header(field) { + Ok(addrlist) => { + *list_id = addrlist.extract_single_info(); + } + Err(e) => warn!(context, "Could not read {} address: {}", key, e), + } + eprintln!("LIST ID parsed as {:?}", *list_id); } else { let value = field.get_value(); headers.insert(key.to_string(), value); diff --git a/src/receive_imf.rs b/src/receive_imf.rs index b592fc3ba..837b6fe75 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -5,7 +5,7 @@ use std::collections::HashSet; use std::convert::TryFrom; use anyhow::{bail, ensure, Context as _, Result}; -use mailparse::{parse_mail, SingleInfo}; +use mailparse::{addrparse, parse_mail, SingleInfo}; use num_traits::FromPrimitive; use once_cell::sync::Lazy; use regex::Regex; @@ -1835,15 +1835,23 @@ async fn create_or_lookup_mailinglist( mime_parser: &MimeMessage, ) -> Result> { static LIST_ID: Lazy = Lazy::new(|| Regex::new(r"^(.+)<(.+)>$").unwrap()); + eprintln!("List ID is {list_id_header:?}"); let (mut name, listid) = match LIST_ID.captures(list_id_header) { Some(cap) => (cap[1].trim().to_string(), cap[2].trim().to_string()), None => ( "".to_string(), - list_id_header - .trim() - .trim_start_matches('<') - .trim_end_matches('>') - .to_string(), + match addrparse(list_id_header) + .ok() + .and_then(|addrlist| addrlist.extract_single_info()) + .and_then(|info| info.display_name) + { + Some(name) => name.clone(), + None => list_id_header + .trim() + .trim_start_matches('<') + .trim_end_matches('>') + .to_string(), + }, ), };