crabmail

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

commit ef39f649715f93bfeaf13e69038ee095598d1b31
parent 60bd931257ced9e2ac9825cb674c4496e5045582
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sat, 19 Mar 2022 14:13:57 -0700

Setup more headers

Diffstat:
MCargo.lock | 7-------
MCargo.toml | 1-
MTODO | 11+----------
Msrc/models.rs | 25+++++++++++++++----------
Msrc/style.css | 6++++--
Msrc/templates/html.rs | 42++++++++++++++++++++++++++++++++----------
6 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -15,7 +15,6 @@ dependencies = [ "anyhow", "linkify", "mail-parser", - "nanohtml2text", "nanotemplate", "once_cell", "urlencoding", @@ -42,12 +41,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] -name = "nanohtml2text" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb649921a71ed2f2c70d7a3426f97912f31570400756867d7f3cede9653f4b81" - -[[package]] name = "nanotemplate" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -16,7 +16,6 @@ mail-parser = {git = "https://github.com/alexwennerberg/mail-parser", default-fe # Small, effective dependencies, little benefit to vendoring linkify = "0.8.0" urlencoding = "2.1.0" -nanohtml2text = "0.1.2" # TODO rem # Should be in stdlib once_cell = "1.9.0" diff --git a/TODO b/TODO @@ -1,14 +1,7 @@ TODO ==== -Move from mailparse to mail-parser - - This will simplify a lot of the code, as mail-parser has a better API IMO - and a lot of helper functions to do things I need - - This should also make the "raw mail" export actually work - -Rewrite thread builder - - See src/threading for more info. Consider algorithm specified there, or - jwz threading +dkim Duplicate ID verification: warn on duplicate ID, use first received-date. This is to prevent someone overwriting old emails secretly @@ -19,8 +12,6 @@ Add replies as well as parents Color highlight on anchor select -Move from horrowshow -> nanotemplate - Refactor so there is a better interface with the filesystem, which then will let me do some caching stuff diff --git a/src/models.rs b/src/models.rs @@ -1,8 +1,8 @@ use crate::config::{Config, Subsection}; use crate::threading::{Msg, ThreadIdx}; use crate::time::Date; -use mail_parser::MimeHeaders; -use mail_parser::{Addr, HeaderValue, Message}; +use mail_parser::{Addr, HeaderValue, Message, MessagePart}; +use mail_parser::{MimeHeaders, RfcHeader}; use std::borrow::Cow; use std::path::PathBuf; @@ -95,7 +95,6 @@ pub struct StrMessage { pub in_reply_to: Option<String>, pub to: Vec<MailAddress>, pub cc: Vec<MailAddress>, - pub content_type: String, // url: Cow<'a, str>, // reply-to string // download_path: PathBuf, // TODO @@ -144,7 +143,17 @@ impl StrMessage { }; let from = MailAddress::from_addr(from); let date = msg.get_date().unwrap().to_iso8601(); - let to = "Tbd"; + let to = match msg.get_to() { + HeaderValue::Address(fr) => vec![MailAddress::from_addr(fr)], + HeaderValue::AddressList(fr) => fr.iter().map(|a| MailAddress::from_addr(a)).collect(), + _ => vec![], + }; + // todo no copypaste + let cc = match msg.get_cc() { + HeaderValue::Address(fr) => vec![MailAddress::from_addr(fr)], + HeaderValue::AddressList(fr) => fr.iter().map(|a| MailAddress::from_addr(a)).collect(), + _ => vec![], + }; let in_reply_to = msg .get_in_reply_to() .as_text_ref() @@ -158,14 +167,10 @@ impl StrMessage { StrMessage { id: id.to_owned(), subject: subject.to_owned(), - content_type: msg - .get_content_type() - .map(|x| x.c_type.to_string()) - .unwrap_or(String::new()), from: from, preview, - to: vec![], - cc: vec![], + to: to, + cc: cc, date: date.to_owned(), body: body.to_string(), in_reply_to: in_reply_to, diff --git a/src/style.css b/src/style.css @@ -1,6 +1,7 @@ :root { --main-text: white; - --light-text: #BBB; + --light-text: #CCC; + --light-hr: #AAA; --link: #21e6c1; --background: #1b222c; --emph-background: #1a1a1a; @@ -11,6 +12,7 @@ --background: white; --main-text: black; --light-text: dimgrey; + --light-hr:grey; --emph-background: #EEE; } } @@ -87,7 +89,7 @@ a { hr { border: 0; height: 0; - color: var(--light-text); + color: var(--light-hr); border-top: 1px solid; } diff --git a/src/templates/html.rs b/src/templates/html.rs @@ -146,17 +146,36 @@ impl Thread { // TODO converted from html // fix from header parsing // TODO in reply to - let mut extra_headers = format!("Message-Id: {}<br>\n", &x(&msg.id)); - if let Some(irt) = &msg.in_reply_to { - extra_headers.push_str(&format!("In-Reply-To: {}<br>\n", x(irt))); + let in_reply_to = if let Some(irt) = &msg.in_reply_to { + format!("In-Reply-To: <a href='#{0}'>{0}</a><br>\n", x(irt)) + } else { + String::new() + }; + let mut extra_headers = + format!("Message-Id: <a href='#{0}'>{0}</a><br>\n", &x(&msg.id)); + + extra_headers.push_str("To: \n"); + extra_headers.push_str( + &msg.to + .iter() + .map(|x| x.to_html()) + .collect::<Vec<String>>() + .join(","), + ); + // todo no copy pasta + extra_headers.push_str("<br>\n"); + if msg.cc.len() > 0 { + extra_headers.push_str("Cc: "); + extra_headers.push_str( + &msg.cc + .iter() + .map(|x| x.to_html()) + .collect::<Vec<String>>() + .join(","), + ); + extra_headers.push_str("<br>\n"); } - extra_headers.push_str("To: "); - // extra_headers.push_str(msg.to.iter().map(|x| x.to_html()).collect().join(",")); - extra_headers.push_str("Cc: \n"); - // extra_headers.push_str(msg.cc.iter().map(|x| x.to_html()).collect().join(",")); - extra_headers.push_str(&format!("Content-Type: {}<br>\n", &x(&msg.content_type))); - // Content-Type: tbd <br> let ms = r#"<div id="{msg_id}" class="message"> <div class="message-meta"> <span class="bold"> @@ -166,8 +185,10 @@ impl Thread { From: {from} <br> Date: <span>{date}</span> + <br> + {in_reply_to} <details> - <summary>More headers</summary> + <summary>More</summary> {extra_headers} </details> <a class="bold" href="tbd">Reply</a> @@ -186,6 +207,7 @@ impl Thread { ("subject", &x(&msg.subject)), ("from", &msg.from.to_html()), ("date", &x(&msg.date)), + ("in_reply_to", &in_reply_to), ("extra_headers", &extra_headers), ("body", &email_body(&msg.body)), ],