commit a8785af68de317c2b63895e5ef4a499887b708cf
parent f002afcde0f158a05a1eb75d85aa8489a350aea1
Author: alex wennerberg <alex@alexwennerberg.com>
Date: Sun, 12 Dec 2021 16:21:46 -0800
add timeago
Diffstat:
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] = ["", """, "&", "<", ">"];
-
-#[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>")),
- "<b>'hello&world"</b>".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>