Show messages in rev chrono order

This commit is contained in:
Jon Gjengset 2019-02-13 14:16:29 -05:00
parent f2a6149294
commit 49ae811259
No known key found for this signature in database
GPG Key ID: D64AC9D67176DC71
3 changed files with 44 additions and 13 deletions

3
Cargo.lock generated
View File

@ -151,9 +151,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "buzz" name = "buzz"
version = "1.1.3" version = "1.1.4"
dependencies = [ dependencies = [
"askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"imap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "imap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mailparse 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "mailparse 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "buzz" name = "buzz"
version = "1.1.3" version = "1.1.4"
description = "A simple system tray application for notifying about unseen e-mail" description = "A simple system tray application for notifying about unseen e-mail"
readme = "README.md" readme = "README.md"
@ -31,3 +31,4 @@ xdg = "2.1.0"
notify-rust = "3.4.0" notify-rust = "3.4.0"
rayon = "1.0.0" rayon = "1.0.0"
askama_escape = "0.1" askama_escape = "0.1"
chrono = "0.4"

View File

@ -1,4 +1,5 @@
extern crate askama_escape; extern crate askama_escape;
extern crate chrono;
extern crate imap; extern crate imap;
extern crate mailparse; extern crate mailparse;
extern crate native_tls; extern crate native_tls;
@ -11,6 +12,8 @@ extern crate xdg;
use native_tls::{TlsConnector, TlsStream}; use native_tls::{TlsConnector, TlsStream};
use rayon::prelude::*; use rayon::prelude::*;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::TcpStream; use std::net::TcpStream;
@ -105,7 +108,7 @@ impl<T: Read + Write + imap::extensions::idle::SetReadTimeout> Connection<T> {
} }
let uids: Vec<_> = uids.into_iter().map(|v: u32| format!("{}", v)).collect(); let uids: Vec<_> = uids.into_iter().map(|v: u32| format!("{}", v)).collect();
let mut subjects = Vec::new(); let mut subjects = BTreeMap::new();
if !uids.is_empty() { if !uids.is_empty() {
for msg in self for msg in self
.socket .socket
@ -120,17 +123,34 @@ impl<T: Read + Write + imap::extensions::idle::SetReadTimeout> Connection<T> {
match mailparse::parse_headers(msg.unwrap()) { match mailparse::parse_headers(msg.unwrap()) {
Ok((headers, _)) => { Ok((headers, _)) => {
use mailparse::MailHeaderMap; use mailparse::MailHeaderMap;
match headers.get_first_value("Subject") {
Ok(Some(subject)) => { let subject = match headers.get_first_value("Subject") {
subjects.push(subject); Ok(Some(subject)) => Cow::from(subject),
} Ok(None) => Cow::from("<no subject>"),
Ok(None) => {
subjects.push(String::from("<no subject>"));
}
Err(e) => { Err(e) => {
println!("failed to get message subject: {:?}", e); println!("failed to get message subject: {:?}", e);
continue;
} }
} };
let date = match headers.get_first_value("Date") {
Ok(Some(date)) => {
match chrono::DateTime::parse_from_rfc2822(&date) {
Ok(date) => date.with_timezone(&chrono::Local),
Err(e) => {
println!("failed to parse message date: {:?}", e);
chrono::Local::now()
}
}
}
Ok(None) => chrono::Local::now(),
Err(e) => {
println!("failed to get message date: {:?}", e);
continue;
}
};
subjects.insert(date, subject);
} }
Err(e) => println!("failed to parse headers of message: {:?}", e), Err(e) => println!("failed to parse headers of message: {:?}", e),
} }
@ -143,12 +163,21 @@ impl<T: Read + Write + imap::extensions::idle::SetReadTimeout> Connection<T> {
"@{} has new mail ({} unseen)", "@{} has new mail ({} unseen)",
self.account.name, num_unseen self.account.name, num_unseen
); );
let notification = format!("> {}", subjects.join("\n> "));
// we want the n newest e-mail in reverse chronological order
let mut notification = String::new();
for subject in subjects.values().rev() {
notification.push_str("> ");
notification.push_str(subject);
notification.push_str("\n");
}
let notification = notification.trim_end();
println!("! {}", title); println!("! {}", title);
println!("{}", notification); println!("{}", notification);
Notification::new() Notification::new()
.summary(&title) .summary(&title)
.body(&format!("{}", askama_escape::escape(&notification))) .body(&format!("{}", askama_escape::escape(notification)))
.icon("notification-message-email") .icon("notification-message-email")
.hint(NotificationHint::Category("email".to_owned())) .hint(NotificationHint::Category("email".to_owned()))
.timeout(-1) .timeout(-1)