crabmail

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

commit 0a352310c65eadb72345af63c187da3e0e7eab34
parent dcd2b4845e82d951e14da39efd849a9e3b249aea
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 13 Mar 2022 17:08:53 -0700

fill in stuff

Diffstat:
Msrc/models.rs | 8+++++++-
Msrc/threading.rs | 10++++++++--
Msrc/utils.rs | 24+++++++++---------------
3 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/src/models.rs b/src/models.rs @@ -59,7 +59,13 @@ pub struct Thread { impl Thread { pub fn new(thread_idx: &Vec<Msg>) -> Self { - Thread { messages: vec![] } + let mut out = vec![]; + for m in thread_idx { + let data = std::fs::read(&m.path).unwrap(); + let msg = StrMessage::new(&Message::parse(&data).unwrap()); + out.push(msg); + } + Thread { messages: out } } } diff --git a/src/threading.rs b/src/threading.rs @@ -3,6 +3,7 @@ // Assumes msg can be found on disk at `path` -- should be made more abstract to handle other mail // stores +use crate::utils::epoch_time; use mail_parser::parsers::fields::thread::thread_name; use mail_parser::{DateTime, Message}; use std::collections::HashMap; @@ -13,6 +14,7 @@ pub type MessageId = String; pub struct Msg { pub id: MessageId, pub path: PathBuf, + pub time: i64, } impl Msg {} @@ -34,11 +36,12 @@ impl ThreadIdx { pub fn add_email(&mut self, msg: &Message, path: PathBuf) { let msg_id = msg.get_message_id().unwrap(); // TODO unwrap // TODO handle duplicate id case - let received = msg + let t = msg .get_received() .as_datetime_ref() .or_else(|| msg.get_date()) .unwrap(); // TODO fix unwrap + let time = epoch_time(&t); let in_reply_to = msg.get_in_reply_to().as_text_ref(); let last_reference = msg.get_in_reply_to().as_text_ref(); let thread_name = thread_name(msg.get_subject().unwrap_or("(No Subject)")); @@ -46,6 +49,7 @@ impl ThreadIdx { let msg = Msg { id: msg_id.to_owned(), path, + time, }; let reference = in_reply_to.or_else(|| last_reference); @@ -68,6 +72,8 @@ impl ThreadIdx { } pub fn finalize(&mut self) { - // TODO sort thread list by last reply date + for t in &mut self.threads { + t.sort_by_key(|a| a.time); + } } } diff --git a/src/utils.rs b/src/utils.rs @@ -3,22 +3,14 @@ use std::fs::{read, write}; use std::io::prelude::*; use std::path::PathBuf; -// TODO: use checksum / cache. bool whether it writes -fn write_if_unchanged(path: PathBuf, data: &[u8]) -> bool { - if let Ok(d) = read(&path) { - if &d == data { - return false; - } - } else { - write(&path, data).unwrap() - } - return true; -} - // from https://github.com/protocolbuffers/upb/blob/22182e6e/upb/json_decode.c#L982-L992 -fn epoch_days(y: u32, m: u32, d: u32) -> i64 { +// TODO make rust-idiomatic +pub fn epoch_days(y: u32, m: u32, d: u32) -> i64 { let year_base = 4800; - let m_adj = m - 3; + let m_adj = match m < 3 { + true => 0, + false => m - 3, + }; let carry = match m_adj > m { true => 1, false => 0, @@ -30,7 +22,9 @@ fn epoch_days(y: u32, m: u32, d: u32) -> i64 { y_adj as i64 * 365 + leap_days as i64 + month_days as i64 + (d as i64 - 1) - 2472632 } -fn epoch_time(dt: &DateTime) -> i64 { +// leap seconds? +// TODO test +pub fn epoch_time(dt: &DateTime) -> i64 { let mut h = dt.hour as i64; let mut m = dt.minute as i64; let s = dt.second;