84 lines
2.1 KiB
Rust
84 lines
2.1 KiB
Rust
use std::{fs::File, io::Read, path::PathBuf};
|
|
|
|
use anyhow::Result;
|
|
use clap::{
|
|
builder::{
|
|
styling::{AnsiColor, Effects},
|
|
Styles,
|
|
},
|
|
Parser,
|
|
};
|
|
use mailparse::MailHeaderMap;
|
|
use notify::{Event, EventKind, RecursiveMode, Watcher};
|
|
use notify_rust::Notification;
|
|
|
|
fn styles() -> Styles {
|
|
Styles::styled()
|
|
.header(AnsiColor::Red.on_default() | Effects::BOLD)
|
|
.usage(AnsiColor::Red.on_default() | Effects::BOLD)
|
|
.literal(AnsiColor::Blue.on_default() | Effects::BOLD)
|
|
.placeholder(AnsiColor::Green.on_default())
|
|
}
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(author, version, about, long_about = None, styles=styles())]
|
|
pub struct Args {
|
|
maildir: String,
|
|
}
|
|
|
|
fn main() {
|
|
let args = Args::parse();
|
|
|
|
let mut watcher = notify::recommended_watcher(watch).unwrap();
|
|
|
|
watcher
|
|
.watch(&PathBuf::from(args.maildir), RecursiveMode::NonRecursive)
|
|
.unwrap();
|
|
|
|
loop {
|
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
|
}
|
|
}
|
|
|
|
fn watch(event: notify::Result<Event>) {
|
|
if let Err(e) = parse_event(event) {
|
|
eprintln!("{}", e);
|
|
}
|
|
}
|
|
|
|
fn parse_event(event: notify::Result<Event>) -> Result<()> {
|
|
let event = event?;
|
|
if let EventKind::Modify(_kind) = event.kind {
|
|
if let Some(p) = event.paths.first() {
|
|
if !p.exists() {
|
|
return Ok(());
|
|
}
|
|
let mut f = File::open(&p)?;
|
|
let mut buf = vec![];
|
|
f.read_to_end(&mut buf)?;
|
|
let mail_data = mailparse::parse_mail(&buf)?;
|
|
let subject = mail_data
|
|
.headers
|
|
.get_first_value("Subject")
|
|
.unwrap_or_default();
|
|
let from_raw = mail_data
|
|
.headers
|
|
.get_first_value("From")
|
|
.unwrap_or_default();
|
|
let from = parse_name(&from_raw);
|
|
|
|
Notification::new()
|
|
.summary(&from)
|
|
.body(&subject)
|
|
.icon("email")
|
|
.show()
|
|
.unwrap();
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn parse_name(s: &str) -> &str {
|
|
s.split("\"").nth(1).unwrap_or(s)
|
|
}
|