Add printable CLI to strip unwanted characters from email.
This commit is contained in:
89
src/bin/mailparse.rs
Normal file
89
src/bin/mailparse.rs
Normal 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
27
src/bin/printable.rs
Normal 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(())
|
||||
}
|
||||
Reference in New Issue
Block a user