mbdirnotify/src/main.rs

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)
}