Author: Manos Pitsidianakis [manos@pitsidianak.is]
Hash: 43098af2c879046552b004884048f82ad9960927
Timestamp: Fri, 09 Jun 2023 13:34:23 +0000 (1 year ago)

+47 -11 +/-1 browse
core: add separate message filter for subject list tag prefixes
1diff --git a/core/src/message_filters.rs b/core/src/message_filters.rs
2index 2a0ecbd..7da07c7 100644
3--- a/core/src/message_filters.rs
4+++ b/core/src/message_filters.rs
5 @@ -51,9 +51,10 @@ impl Connection {
6 /// Return the post filters of a mailing list.
7 pub fn list_filters(&self, _list: &DbVal<MailingList>) -> Vec<Box<dyn PostFilter>> {
8 vec![
9- Box::new(FixCRLF),
10 Box::new(PostRightsCheck),
11+ Box::new(FixCRLF),
12 Box::new(AddListHeaders),
13+ Box::new(AddSubjectTagPrefix),
14 Box::new(FinalizeRecipients),
15 ]
16 }
17 @@ -163,16 +164,6 @@ impl PostFilter for AddListHeaders {
18 let (mut headers, body) = melib::email::parser::mail(&post.bytes).unwrap();
19 let sender = format!("<{}>", ctx.list.address);
20 headers.push((&b"Sender"[..], sender.as_bytes()));
21- let mut subject = format!("[{}] ", ctx.list.id).into_bytes();
22- if let Some((_, subj_val)) = headers
23- .iter_mut()
24- .find(|(k, _)| k.eq_ignore_ascii_case(b"Subject"))
25- {
26- subject.extend(subj_val.iter().cloned());
27- *subj_val = subject.as_slice();
28- } else {
29- headers.push((&b"Subject"[..], subject.as_slice()));
30- }
31
32 let list_id = Some(ctx.list.id_header());
33 let list_help = ctx.list.help_header();
34 @@ -220,6 +211,51 @@ impl PostFilter for AddListHeaders {
35 }
36 }
37
38+ /// Add List ID prefix in Subject header (e.g. `[list-id] ...`)
39+ pub struct AddSubjectTagPrefix;
40+ impl PostFilter for AddSubjectTagPrefix {
41+ fn feed<'p, 'list>(
42+ self: Box<Self>,
43+ post: &'p mut PostEntry,
44+ ctx: &'p mut ListContext<'list>,
45+ ) -> std::result::Result<(&'p mut PostEntry, &'p mut ListContext<'list>), ()> {
46+ trace!("Running AddSubjectTagPrefix filter");
47+ let (mut headers, body) = melib::email::parser::mail(&post.bytes).unwrap();
48+ let mut subject;
49+ if let Some((_, subj_val)) = headers
50+ .iter_mut()
51+ .find(|(k, _)| k.eq_ignore_ascii_case(b"Subject"))
52+ {
53+ subject = format!("[{}] ", ctx.list.id).into_bytes();
54+ subject.extend(subj_val.iter().cloned());
55+ *subj_val = subject.as_slice();
56+ } else {
57+ subject = format!("[{}] (no subject)", ctx.list.id).into_bytes();
58+ headers.push((&b"Subject"[..], subject.as_slice()));
59+ }
60+
61+ let mut new_vec = Vec::with_capacity(
62+ headers
63+ .iter()
64+ .map(|(h, v)| h.len() + v.len() + ": \r\n".len())
65+ .sum::<usize>()
66+ + "\r\n\r\n".len()
67+ + body.len(),
68+ );
69+ for (h, v) in headers {
70+ new_vec.extend_from_slice(h);
71+ new_vec.extend_from_slice(b": ");
72+ new_vec.extend_from_slice(v);
73+ new_vec.extend_from_slice(b"\r\n");
74+ }
75+ new_vec.extend_from_slice(b"\r\n\r\n");
76+ new_vec.extend_from_slice(body);
77+
78+ post.bytes = new_vec;
79+ Ok((post, ctx))
80+ }
81+ }
82+
83 /// Adds `Archived-At` field, if configured.
84 pub struct ArchivedAtLink;
85 impl PostFilter for ArchivedAtLink {