crabmail

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

commit a8785af68de317c2b63895e5ef4a499887b708cf
parent f002afcde0f158a05a1eb75d85aa8489a350aea1
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 12 Dec 2021 16:21:46 -0800

add timeago

Diffstat:
Mcrabmail/src/filters.rs | 36+++++++++++++++++++++++++++++++++++-
Mcrabmail/src/main.rs | 4++--
Mcrabmail/src/utils.rs | 66+-----------------------------------------------------------------
Mcrabmail/templates/thread.html | 2+-
Mcrabmail/templates/threadlist.html | 2+-
5 files changed, 40 insertions(+), 70 deletions(-)

diff --git a/crabmail/src/filters.rs b/crabmail/src/filters.rs @@ -1,7 +1,41 @@ use mailparse::{parse_mail, MailHeaderMap, ParsedMail}; +use std::time::{SystemTime, UNIX_EPOCH}; +pub fn time_ago(amount: &u64) -> askama::Result<String> { + Ok(timeago(*amount)) +} + +fn timeago(unixtime: u64) -> String { + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(); + if unixtime > current_time { + return "in the future".to_owned(); + } + let diff = current_time - unixtime; + let amount: u64; + let metric: &str; + if diff < 60 { + amount = diff; + metric = "second"; + } else if diff < 60 * 60 { + amount = diff / 60; + metric = "minute"; + } else if diff < 60 * 60 * 24 { + amount = diff / (60 * 60); + metric = "hour"; + } else { + amount = diff / (60 * 60 * 24); + metric = "day"; + } + match amount { + 1 => format!("{} {} ago", amount, metric), + _ => format!("{} {}s ago", amount, metric), + } +} // // NOTE this function is currently unsafe -// pub fn get_body(email: &&ParsedMail) -> Result<String> { +// pub fn get_body(email: &&ParsedMail) -> askama::Result<String> { // let core_email = email.subparts.get(0).unwrap_or(email); // #[cfg(feature = "html")] diff --git a/crabmail/src/main.rs b/crabmail/src/main.rs @@ -29,7 +29,7 @@ struct Email { from: String, subject: String, in_reply_to: Option<String>, - date: i64, // unix epoch. received date + date: u64, // unix epoch. received date body: String, // raw_email: String, } @@ -54,7 +54,7 @@ fn local_parse_email(data: &[u8]) -> Result<Email> { &headers .get_first_value("received") .context("No date header")?, - )?; + )? as u64; let from = headers.get_first_value("from").context("No from header")?; let body = "lorem ipsum".to_owned(); return Ok(Email { diff --git a/crabmail/src/utils.rs b/crabmail/src/utils.rs @@ -1,65 +1 @@ -use std::fmt; -use std::io; -use std::io::Write; - -// Derived from https://github.com/raphlinus/pulldown-cmark/blob/master/src/escape.rs -// Don't use single quotes (') in any of your attributes - -const fn create_html_escape_table() -> [u8; 256] { - let mut table = [0; 256]; - table[b'"' as usize] = 1; - table[b'&' as usize] = 2; - table[b'<' as usize] = 3; - table[b'>' as usize] = 4; - table -} - -static HTML_ESCAPE_TABLE: [u8; 256] = create_html_escape_table(); - -static HTML_ESCAPES: [&str; 5] = ["", "&quot;", "&amp;", "&lt;", "&gt;"]; - -#[derive(Debug)] -pub struct EscapedHTML<'a>(pub &'a str); - -impl fmt::Display for EscapedHTML<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let s = self.0; - let bytes = s.as_bytes(); - let mut mark = 0; - let mut i = 0; - // does this work - while i < s.len() { - match bytes[i..] - .iter() - .position(|&c| HTML_ESCAPE_TABLE[c as usize] != 0) - { - Some(pos) => { - i += pos; - } - None => break, - } - let c = bytes[i]; - let escape = HTML_ESCAPE_TABLE[c as usize]; - let escape_seq = HTML_ESCAPES[escape as usize]; - f.write_str(&s[mark..i])?; - f.write_str(escape_seq)?; - i += 1; - mark = i; // all escaped characters are ASCII - } - f.write_str(&s[mark..])?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_add() { - assert_eq!( - format!("{}", EscapedHTML("<b>'hello&world\"</b>")), - "&lt;b&gt;'hello&amp;world&quot;&lt;/b&gt;".to_string() - ); - } -} +use std::time::{SystemTime, UNIX_EPOCH}; diff --git a/crabmail/templates/thread.html b/crabmail/templates/thread.html @@ -7,7 +7,7 @@ {% for message in messages %} <h3>{{message.subject}}</h3> <b>From: </b>{{message.from}}<br> - <b>Date: </b>{{message.date}}<br> + <b>Date: </b>{{message.date | time_ago}}<br> <div class="email-body"> {{message.body}} </div> diff --git a/crabmail/templates/threadlist.html b/crabmail/templates/threadlist.html @@ -8,7 +8,7 @@ <tr> <td><a href="threads/{{message.date}}">{{message.subject}}</a></td> <td> {{message.from}}</td> - <td>{{message.date}}</td> + <td>{{message.date | time_ago}}</td> {% endfor %} </table> </div>