crabmail

Static HTML email archive viewer in Rust
git clone git://git.alexwennerberg.com/crabmail
Log | Files | Refs | README | LICENSE

commit c3ed327dba04ed8a34f128af3f0da888cfcff01a
parent 790053fcc9a65f3d28cf169d7912c36a23ec25d9
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Mon, 17 Jan 2022 09:42:39 -0800

Add reply link cfg option

Diffstat:
Mcrabmail.conf | 2+-
Mdoc/crabmail-config.5 | 9++++++++-
Mdoc/crabmail-config.5.scd | 5+++++
Msrc/config.rs | 4++--
Msrc/main.rs | 24+++++++++++++++++-------
Msrc/utils.rs | 4++++
6 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/crabmail.conf b/crabmail.conf @@ -3,7 +3,7 @@ base_url=https://lists.flounder.online email_fmt=lists+%s@flounder.online description=All my lists -reply_thread_link=true +reply_add_link=true # optionally wirte/overwrite config for specific lists [smallweb] diff --git a/doc/crabmail-config.5 b/doc/crabmail-config.5 @@ -5,7 +5,7 @@ .nh .ad l .\" Begin generated content: -.TH "crabmail-config" "5" "2022-01-13" +.TH "crabmail-config" "5" "2022-01-17" .P .SH NAME .P @@ -44,6 +44,13 @@ A description for your homepage, will be displayed as a single line.\& HTML is allowed if you want.\& .P .RE +\fBreply_add_link\fR +.RS 4 +Add a link to the thread in the "reply to" url.\& This allows users to see the +thread context when receiving responses via email.\& TBD: This will allow poorly designed +clients (eg Gmail) to still be threaded properly.\& Default: false +.P +.RE .SS LISTS .P Each list is specified with a [subsection] header.\& diff --git a/doc/crabmail-config.5.scd b/doc/crabmail-config.5.scd @@ -31,6 +31,11 @@ don't fill in values from user input somehow). A description for your homepage, will be displayed as a single line. HTML is allowed if you want. +*reply_add_link* + Add a link to the thread in the "reply to" url. This allows users to see the + thread context when receiving responses via email. TBD: This will allow poorly designed + clients (eg Gmail) to still be threaded properly. Default: false + ## LISTS Each list is specified with a [subsection] header. diff --git a/src/config.rs b/src/config.rs @@ -30,7 +30,7 @@ pub struct Config { pub relative_times: bool, // TODO rem pub include_raw: bool, // TODO rem pub now: String, // TODO rem - pub reply_thread_link: bool, + pub reply_add_link: bool, pub subsections: Vec<Subsection>, } @@ -41,7 +41,7 @@ impl Config { "email_fmt" => self.email_fmt = value.to_string(), "base_url" => self.base_url = value.to_string(), "description" => self.description = value.to_string(), - "reply_thread_link" => self.reply_thread_link = value == "true", + "reply_add_link" => self.reply_add_link = value == "true", _ => {} } } diff --git a/src/main.rs b/src/main.rs @@ -243,8 +243,8 @@ impl<'a> MailThread<'a> { </entry> "#, title = xml_safe(&message.subject), - item_link = xml_safe(&self.url()), - entry_id = xml_safe(&format!("{}#{}", self.url(), message.id)), + item_link = xml_safe(&message.url(&self)), + entry_id = xml_safe(&message.url(&self)), updated_at = time::secs_to_date(message.date).rfc3339(), author_name = xml_safe(short_name(&message.from)), author_email = xml_safe(&message.from.addr), @@ -335,7 +335,7 @@ impl<'a> MailThread<'a> { } } br; - a (class="bold", href=message.mailto(&root.subject, &self.list_name)) { + a (class="bold", href=message.mailto(&self)) { :"✉️ Reply" } @ if Config::global().include_raw { @@ -382,13 +382,17 @@ impl<'a> MailThread<'a> { impl Email { // mailto:... populated with everything you need - pub fn mailto(&self, thread_subject: &str, list_name: &str) -> String { + // TODO add these to constructors + pub fn url(&self, thread: &MailThread) -> String { + format!("{}#{}", thread.url(), self.id) + } + pub fn mailto(&self, thread: &MailThread) -> String { let config = Config::global(); - let d = config.default_subsection(&list_name); + let d = config.default_subsection(&thread.list_name); let subsection_config = config .subsections .iter() - .find(|s| s.name == list_name) + .find(|s| s.name == thread.list_name) .unwrap_or(&d); let mut url = format!("mailto:{}?", subsection_config.email); @@ -401,9 +405,15 @@ impl Email { let fixed_id = format!("<{}>", &self.id); pushencode("cc", &from); pushencode("in-reply-to", &fixed_id); - pushencode("subject", &format!("Re: {}", thread_subject)); + pushencode("subject", &format!("Re: {}", thread.messages[0].subject)); // quoted body url.push_str("body="); + if Config::global().reply_add_link { + url.push_str(&format!( + "[View original message: {}]%0A%0A", + &urlencoding::encode(&thread.url()) + )); + } for line in self.body.lines() { url.push_str("%3E%20"); url.push_str(&urlencoding::encode(&line)); diff --git a/src/utils.rs b/src/utils.rs @@ -24,6 +24,10 @@ pub fn email_body(body: &str) -> String { let mut bytes = Vec::new(); let mut in_reply: bool = false; for line in body.lines() { + if line.starts_with("[View original message") { + // see main.rs + continue; + } if line.starts_with(">") || (line.starts_with("On ") && line.ends_with("wrote:")) { if !in_reply { in_reply = true;