From 52ec0925f27e5841cfe8c7485676e3e963a2ad47 Mon Sep 17 00:00:00 2001 From: Jacob Kiers Date: Sun, 12 Jun 2022 22:11:47 +0200 Subject: [PATCH] Convert IMAP functions into ImapReader Signed-off-by: Jacob Kiers --- bin/src/main.rs | 5 -- bin/src/message_reader.rs | 132 +++++++++++++++++++++++--------------- 2 files changed, 81 insertions(+), 56 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 580120f..2c070f0 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -30,11 +30,6 @@ fn main() { 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()); for (uid, message) in reader.read_rfc822_messages() { diff --git a/bin/src/message_reader.rs b/bin/src/message_reader.rs index 1c4d15e..af66aea 100644 --- a/bin/src/message_reader.rs +++ b/bin/src/message_reader.rs @@ -1,9 +1,10 @@ use std::{ + collections::HashMap, error::Error, fs::{read_dir, DirEntry}, net::TcpStream, path::PathBuf, - vec::IntoIter, collections::HashMap, + vec::IntoIter, }; use imap::Session; @@ -54,63 +55,92 @@ impl EmailReader for TestMessagesReader { } } -fn connect( - server: &str, +pub struct ImapReader { + host: String, port: u16, - username: &str, - password: &str, -) -> Result>, Box> { - let mut session = open_session(server, port, username, password)?; + username: String, + password: String, +} - 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.to_string(), body.to_owned()); +impl ImapReader { + pub fn new(host: String, port: u16, username: String, password: String) -> Self { + ImapReader { + host, + port, + username, + password, + } } - session.logout().expect("Could not log out"); + fn connect(&self) -> Result>, Box> { + let mut session = self.open_session()?; - Ok(msgs) -} + session.examine("INBOX")?; -fn open_session( - server: &str, - port: u16, - username: &str, - password: &str, -) -> Result< - Session< - rustls_connector::rustls::StreamOwned< - rustls_connector::rustls::ClientConnection, - TcpStream, + 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.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, -> { - let stream = TcpStream::connect((server, port))?; - let tls = RustlsConnector::new_with_webpki_roots_certs(); - let tls_stream = tls.connect(server, stream)?; + Box, + > { + let stream = TcpStream::connect((self.host.as_ref(), self.port))?; + let tls = RustlsConnector::new_with_webpki_roots_certs(); + let tls_stream = tls.connect(&self.host, 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)>> { + 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::)>>().into_iter(); + + Box::new(iter) + } }