Convert IMAP functions into ImapReader

Signed-off-by: Jacob Kiers <jacob@jacobkiers.net>
This commit is contained in:
Jacob Kiers 2022-06-12 22:11:47 +02:00
parent 8f29b35ae7
commit 52ec0925f2
2 changed files with 81 additions and 56 deletions

View File

@ -30,11 +30,6 @@ fn main() {
std::fs::create_dir(&dir).expect("Could not create directory"); std::fs::create_dir(&dir).expect("Could not create directory");
} }
// let messsages = messages_from_tests(&Path::new("tests/data")) //connect("my.kiers.eu", 993, "newsletters@kie.rs", "Jjkcloudron1!")
// .expect("A list of messages");
// for (uid, message) in messages {
let mut reader = TestMessagesReader::new((&Path::new("tests/data")).to_path_buf()); let mut reader = TestMessagesReader::new((&Path::new("tests/data")).to_path_buf());
for (uid, message) in reader.read_rfc822_messages() { for (uid, message) in reader.read_rfc822_messages() {

View File

@ -1,9 +1,10 @@
use std::{ use std::{
collections::HashMap,
error::Error, error::Error,
fs::{read_dir, DirEntry}, fs::{read_dir, DirEntry},
net::TcpStream, net::TcpStream,
path::PathBuf, path::PathBuf,
vec::IntoIter, collections::HashMap, vec::IntoIter,
}; };
use imap::Session; use imap::Session;
@ -54,63 +55,92 @@ impl EmailReader for TestMessagesReader {
} }
} }
fn connect( pub struct ImapReader {
server: &str, host: String,
port: u16, port: u16,
username: &str, username: String,
password: &str, password: String,
) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>> { }
let mut session = open_session(server, port, username, password)?;
session.examine("INBOX")?; impl ImapReader {
pub fn new(host: String, port: u16, username: String, password: String) -> Self {
let items = match session.uid_search("ALL") { ImapReader {
Ok(i) => i, host,
Err(e) => return Err(Box::new(e)), port,
}; username,
password,
let mut msgs = HashMap::<String, Vec<u8>>::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.to_string(), body.to_owned());
} }
session.logout().expect("Could not log out"); fn connect(&self) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>> {
let mut session = self.open_session()?;
Ok(msgs) session.examine("INBOX")?;
}
fn open_session( let items = match session.uid_search("ALL") {
server: &str, Ok(i) => i,
port: u16, Err(e) => return Err(Box::new(e)),
username: &str, };
password: &str,
) -> Result< let mut msgs = HashMap::<String, Vec<u8>>::with_capacity(items.len());
Session<
rustls_connector::rustls::StreamOwned< //println!("# of messages: {}", &items.len());
rustls_connector::rustls::ClientConnection,
TcpStream, 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.to_string(), body.to_owned());
}
session.logout().expect("Could not log out");
Ok(msgs)
}
fn open_session(
&self,
) -> Result<
Session<
rustls_connector::rustls::StreamOwned<
rustls_connector::rustls::ClientConnection,
TcpStream,
>,
>, >,
>, Box<dyn Error + 'static>,
Box<dyn Error + 'static>, > {
> { let stream = TcpStream::connect((self.host.as_ref(), self.port))?;
let stream = TcpStream::connect((server, port))?; let tls = RustlsConnector::new_with_webpki_roots_certs();
let tls = RustlsConnector::new_with_webpki_roots_certs(); let tls_stream = tls.connect(&self.host, stream)?;
let tls_stream = tls.connect(server, stream)?;
let client = imap::Client::new(tls_stream); let client = imap::Client::new(tls_stream);
Ok(client.login(username, password).map_err(|e| e.0)?) Ok(client
.login(&self.username, &self.password)
.map_err(|e| e.0)?)
}
}
impl EmailReader for ImapReader {
fn read_rfc822_messages(&mut self) -> Box<IntoIter<(String, Vec<u8>)>> {
let msgs = match self.connect() {
Ok(m) => m,
Err(_) => return Box::new(Vec::new().into_iter()),
};
let items = msgs
.iter()
.map(|i| (i.0.to_owned(), i.1.to_owned()));
let iter = items.collect::<Vec<(String, Vec<u8>)>>().into_iter();
Box::new(iter)
}
} }