add new emails listing feature #6

This commit is contained in:
Clément DOUIN
2021-01-02 18:26:03 +01:00
parent 80fb4bd1d9
commit 2970828db9
6 changed files with 177 additions and 11 deletions
+4 -4
View File
@@ -15,19 +15,19 @@ pub struct ServerInfo {
impl ServerInfo {
pub fn get_host(&self) -> &str {
&self.host[..]
&self.host
}
pub fn get_addr(&self) -> (&str, u16) {
(&self.host[..], self.port)
(&self.host, self.port)
}
pub fn get_login(&self) -> &str {
&self.login[..]
&self.login
}
pub fn get_password(&self) -> &str {
&self.password[..]
&self.password
}
}
+105 -2
View File
@@ -1,8 +1,10 @@
use imap;
use native_tls::{TlsConnector, TlsStream};
use rfc2047_decoder;
use std::net::TcpStream;
use crate::config::{Config, ServerInfo};
use crate::table;
type ImapClient = imap::Client<TlsStream<TcpStream>>;
type ImapSession = imap::Session<TlsStream<TcpStream>>;
@@ -40,6 +42,107 @@ pub fn create_imap_sess(client: ImapClient, server: &ServerInfo) -> ImapSession
pub fn login(config: &Config) -> ImapSession {
let tls = create_tls_connector();
let client = create_imap_client(&config.imap, &tls);
let sess = create_imap_sess(client, &config.imap);
sess
let imap_sess = create_imap_sess(client, &config.imap);
imap_sess
}
fn subject_from_fetch(fetch: &imap::types::Fetch) -> String {
let envelope = fetch.envelope().expect("envelope is missing");
match &envelope.subject {
None => String::new(),
Some(bytes) => match rfc2047_decoder::decode(bytes) {
Err(_) => String::new(),
Ok(subject) => subject,
},
}
}
fn first_addr_from_fetch(fetch: &imap::types::Fetch) -> String {
let envelope = fetch.envelope().expect("envelope is missing");
match &envelope.from {
None => String::new(),
Some(addresses) => match addresses.first() {
None => String::new(),
Some(address) => {
let mbox = String::from_utf8(address.mailbox.expect("invalid addr mbox").to_vec())
.expect("invalid addr mbox");
let host = String::from_utf8(address.host.expect("invalid addr host").to_vec())
.expect("invalid addr host");
let email = format!("{}@{}", mbox, host);
match address.name {
None => email,
Some(name) => match rfc2047_decoder::decode(name) {
Err(_) => email,
Ok(name) => name,
},
}
}
},
}
}
fn date_from_fetch(fetch: &imap::types::Fetch) -> String {
let envelope = fetch.envelope().expect("envelope is missing");
match &envelope.date {
None => String::new(),
Some(date) => match String::from_utf8(date.to_vec()) {
Err(_) => String::new(),
Ok(date) => date,
},
}
}
pub fn read_new_emails(imap_sess: &mut ImapSession, mbox: &str) -> imap::Result<()> {
imap_sess.select(mbox)?;
// let mboxes = imap_sess.list(Some(""), Some("*"))?;
// println!("Mboxes {:?}", mboxes);
let seqs = imap_sess
.search("NOT SEEN")?
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",");
let table_head = vec![
table::Cell::new(
vec![table::BOLD, table::UNDERLINE, table::WHITE],
String::from("FLAGS"),
),
table::Cell::new(
vec![table::BOLD, table::UNDERLINE, table::WHITE],
String::from("FROM"),
),
table::Cell::new(
vec![table::BOLD, table::UNDERLINE, table::WHITE],
String::from("SUBJECT"),
),
table::Cell::new(
vec![table::BOLD, table::UNDERLINE, table::WHITE],
String::from("DATE"),
),
];
let mut table_rows = imap_sess
.fetch(seqs, "(INTERNALDATE ENVELOPE)")?
.iter()
.map(|fetch| {
vec![
table::Cell::new(vec![table::WHITE], String::from("!@")),
table::Cell::new(vec![table::BLUE], first_addr_from_fetch(fetch)),
table::Cell::new(vec![table::GREEN], subject_from_fetch(fetch)),
table::Cell::new(vec![table::YELLOW], date_from_fetch(fetch)),
]
})
.collect::<Vec<_>>();
table_rows.insert(0, table_head);
println!("{}", table::render(table_rows));
Ok(())
}
+11 -2
View File
@@ -1,8 +1,17 @@
mod config;
mod imap;
mod table;
use std::env;
fn main() {
let mbox = env::args().nth(1).unwrap_or(String::from("inbox"));
let args = env::args().skip(2).collect::<Vec<_>>().join(" ").to_owned();
let config = config::read_file();
let sess = imap::login(&config);
println!("{:?}", sess);
let mut imap_sess = imap::login(&config);
match args.as_str() {
"read new" => imap::read_new_emails(&mut imap_sess, &mbox).unwrap(),
_ => println!("Himalaya: command not found e"),
}
}