Add printable CLI to strip unwanted characters from email.

This commit is contained in:
2022-12-29 10:30:19 -08:00
parent 7685b0e5b2
commit af87a3cade
4 changed files with 77 additions and 16 deletions

89
src/bin/mailparse.rs Normal file
View File

@@ -0,0 +1,89 @@
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::process::exit;
use std::slice::Iter;
use mailparse::dateparse;
use mailparse::MailHeaderMap;
fn newline(b: &u8) -> bool {
*b == b'\n'
}
fn index_of(it: &mut Iter<u8>, needle: &[u8]) -> Option<usize> {
let mut needle_ix = 0;
it.position(move |&b| {
if b == needle[needle_ix] {
needle_ix += 1;
if needle_ix == needle.len() {
return true;
}
} else if b == needle[0] {
needle_ix = 1;
} else {
needle_ix = 0;
}
false
})
}
fn parse_mbox(mbox_bytes: &Vec<u8>) -> Result<(), Box<dyn Error>> {
let mut it = mbox_bytes.iter();
let mut ix = 0;
loop {
let mail_start = it.position(newline);
if mail_start.is_none() {
return Ok(());
}
ix += mail_start.unwrap() + 1;
let start = ix;
let delim = b"\nFrom ";
let next_mail_start = index_of(&mut it, delim);
let end = match next_mail_start {
Some(x) => {
ix += x + 1;
ix - delim.len()
}
None => mbox_bytes.len(),
};
let mail_bytes = &mbox_bytes[start..end];
let mail = mailparse::parse_mail(mail_bytes).unwrap();
println!(
"{:?} {:?} from {:?}",
match mail.headers.get_first_value("Date")? {
Some(date) => date,
None => "NO DATE".to_string(),
},
match mail.headers.get_first_value("Subject")? {
Some(subject) => subject,
None => "NO SUBJECT".to_string(),
},
match mail.headers.get_first_value("From")? {
Some(from) => from,
None => "NO FROM".to_string(),
},
);
}
}
fn main() {
if env::args().count() <= 1 {
println!("Provide mbox files as arguments");
exit(1);
}
let mut args = env::args();
args.next(); // drop executable name
args.for_each(|mbox_path| {
let mut mbox = File::open(mbox_path).unwrap();
let mut mails = Vec::new();
mbox.read_to_end(&mut mails).unwrap();
parse_mbox(&mails);
});
}

27
src/bin/printable.rs Normal file
View File

@@ -0,0 +1,27 @@
use std::{io, io::Read};
use regex::Regex;
fn main() -> io::Result<()> {
let re = Regex::new("[^[[:print:]]\n]").expect("invalid regex");
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer)?;
let buffer = re.replace_all(&buffer, "");
let mut last_c = 0;
for l in buffer.lines() {
let c = l
.as_bytes()
.iter()
.filter(|b| match b {
b' ' | b'\t' => false,
_ => true,
})
.count();
if !(c == 0 && last_c == 0) {
println!("{l}");
}
last_c = c;
}
Ok(())
}