newsletter-to-web/src/main.rs

126 lines
3.2 KiB
Rust
Raw Normal View History

use std::{
collections::HashMap,
error::Error,
fs::OpenOptions,
io::Write,
net::TcpStream,
path::{Path, PathBuf},
};
use imap::Session;
use mail_parser::Message;
use rustls_connector::RustlsConnector;
extern crate imap;
extern crate mail_parser;
extern crate rustls_connector;
fn main() {
let dir = Path::new("data");
if !dir.exists() {
std::fs::create_dir(&dir).expect("Could not create directory");
}
let messsages = connect("my.kiers.eu", 993, "newsletters@kie.rs", "Jjkcloudron1!")
.expect("A list of messages");
for (uid, message) in messsages {
println!("Processing message {}\n", &uid);
let parsed = Message::parse(&message).expect("A parsed messsage.");
// let from = match parsed.get_from() {
// mail_parser::HeaderValue::Address(a) => Some(a),
// _ => None,
// }
// .expect("An address");
// println!(
// "{} <{}>",
// from.name.as_ref().unwrap(),
// from.address.as_ref().unwrap()
// );
// println!(
// "HML: {}, Text: {}",
// parsed.get_html_body_count(),
// parsed.get_text_body_count()
// );
let html_body = parsed.get_html_body(0).expect("Could not read body");
let html_bytes = html_body.as_bytes();
println!("{}", &html_body);
let path: PathBuf = [dir, Path::new(&format!("{}.html", uid))].iter().collect();
let mut file = OpenOptions::new()
.write(true)
.create(true)
.open(path)
.expect("Could not open file fir writing");
file.write_all(html_bytes)
.expect("Could not write to file.");
}
}
fn connect(
server: &str,
port: u16,
username: &str,
password: &str,
) -> Result<HashMap<u32, Vec<u8>>, Box<dyn Error>> {
let mut session = open_session(server, port, username, password)?;
session.examine("INBOX")?;
let items = match session.uid_search("ALL") {
Ok(i) => i,
Err(e) => return Err(Box::new(e)),
};
let mut msgs = HashMap::with_capacity(items.len());
//println!("# of messages: {}", &items.len());
for item in items {
let msg = session.uid_fetch(&item.to_string(), "(BODY.PEEK[] UID)")?;
let message = if let Some(m) = msg.iter().next() {
m
} else {
continue;
};
let body = message.body().expect("Message did not have a body.");
msgs.insert(item, body.to_owned());
}
session.logout().expect("Could not log out");
Ok(msgs)
}
fn open_session(
server: &str,
port: u16,
username: &str,
password: &str,
) -> Result<
Session<
rustls_connector::rustls::StreamOwned<
rustls_connector::rustls::ClientConnection,
TcpStream,
>,
>,
Box<dyn Error + 'static>,
> {
let stream = TcpStream::connect((server, port))?;
let tls = RustlsConnector::new_with_webpki_roots_certs();
let tls_stream = tls.connect(server, stream)?;
let client = imap::Client::new(tls_stream);
Ok(client.login(username, password).map_err(|e| e.0)?)
}