Changed email transport from sendmail to smtp.

This commit is contained in:
Thelie 2021-06-09 18:45:44 +02:00
parent 4980c9e24c
commit a1e1a0df5f
2 changed files with 59 additions and 32 deletions

View file

@ -27,8 +27,12 @@ use std::{
thread, thread,
}; };
use lettre::{ use lettre::{
SendmailTransport, SmtpClient,
Transport smtp::authentication::{
Credentials,
Mechanism,
},
Transport,
}; };
fn main() { fn main() {
@ -57,17 +61,19 @@ fn main() {
None => config = config::get_main_config(PathBuf::from("/etc/Mention2Mail/config.toml")) None => config = config::get_main_config(PathBuf::from("/etc/Mention2Mail/config.toml"))
.expect("Could not get default config in /etc/Mention2Mail/default.toml"), .expect("Could not get default config in /etc/Mention2Mail/default.toml"),
} }
let mail_config = &config.get("email").expect("No email config found.");
let server_configs; let server_configs;
match server_conf_path { match server_conf_path {
Some(p) => server_configs = config::get_server_configs(config, PathBuf::from(p)) Some(p) => server_configs = config::get_server_configs(config.clone(), PathBuf::from(p))
.expect("Could not get server config."), .expect("Could not get server config."),
None => server_configs = vec![config], None => server_configs = vec![config.clone()],
} }
// TODO: This line has many problems… // TODO: This line has many problems…
let (tx,rx): (std::sync::mpsc::Sender<(String, String, String, [Option<[String; 2]>; 5])>, std::sync::mpsc::Receiver<(String, String, String, [Option<[String; 2]>; 5])>)= channel(); let (tx,rx): (std::sync::mpsc::Sender<(String, String, String, Vec<Option<[String; 2]>>)>, std::sync::mpsc::Receiver<(String, String, String, Vec<Option<[String; 2]>>)>)= channel();
let mut server_threads = vec![]; let mut server_threads = vec![];
for s_conf in server_configs { for s_conf in server_configs {
@ -75,12 +81,30 @@ fn main() {
server_threads.push(thread::Builder::new() server_threads.push(thread::Builder::new()
.name("server name here".to_string()) .name("server name here".to_string())
.spawn(move || { .spawn(move || {
servers::handle_server(s_conf, t).unwrap(); servers::handle_server(s_conf, t, 5).unwrap();
}) })
); );
} }
let mut mailer = SendmailTransport::new(); let smtp_address = mail_config.get("address")
.expect("No SMTP server address found.")
.as_str()
.unwrap();
let smpt_user = mail_config.get("user")
.expect("No SMTP user name found.")
.as_str()
.unwrap();
let smtp_pass = mail_config.get("pass")
.expect("No SMTP password found.")
.as_str()
.unwrap();
let mail_client = SmtpClient::new_simple(smtp_address).unwrap();
let mail_client = mail_client.credentials(
Credentials::new(smpt_user.to_owned(), smtp_pass.to_owned())
);
let mail_client = mail_client.authentication_mechanism(Mechanism::Plain);
let mut mailer = mail_client.transport();
loop { loop {
match rx.recv() { match rx.recv() {
@ -92,9 +116,9 @@ fn main() {
channel, server); channel, server);
for opt in context.iter() { for opt in context.iter() {
match opt{ match opt{
Some([sender, msg]) => body.push_str( Some([sender, msg]) => {
&format!("{} wrote: {}", sender, msg) body.push_str(&format!("{} wrote: {}\n", sender, msg))
), },
None => (), None => (),
} }
} }
@ -115,7 +139,7 @@ fn main() {
match mailer.send(mail) { match mailer.send(mail) {
Ok(_) => println!("Email sent successfully!"), Ok(_) => println!("Email sent successfully!"),
Err(e) => panic!("Could not send email: {:?}", e), Err(e) => println!("Could not send email: {:?}", e),
} }
} }
Err(_e) => (), Err(_e) => (),

View file

@ -34,43 +34,46 @@ use toml::value::Value;
/// A static implementation of a ringbuffer. /// A static implementation of a ringbuffer.
/// It holds arrays of three strings each, /// It holds arrays of three strings each,
/// which are meant to represent the author and message respectively. /// which are meant to represent the author and message respectively.
struct MessageRingBuf<const SIZE: usize> { pub struct MessageRingBuf<T> {
buf: [Option<[String; 2]>; SIZE], buf: Vec<Option<T>>,
ptr: usize, ptr: usize,
} }
impl <const SIZE: usize> MessageRingBuf<SIZE> { impl <T: Clone> MessageRingBuf<T> {
pub fn new() -> Self { pub fn new(size: usize) -> Self {
Self{ Self{
buf: [None; SIZE], buf: vec!(None; size),
ptr: 0 ptr: 0
} }
} }
/// Adds a message to the end of the buffer, /// Adds a message to the end of the buffer,
/// overwriting the first value if the buffer is full. /// overwriting the first value if the buffer is full.
pub fn push(&mut self, val: [String; 2]) { pub fn push(&mut self, val: T) {
self.ptr = (self.ptr + 1) % SIZE; self.ptr = (self.ptr + 1) % self.buf.len();
self.buf[self.ptr] = Some(val); self.buf[self.ptr] = Some(val);
} }
/// Returns the last element of the buffer, /// Returns the last element of the buffer,
/// replacing it with none. /// replacing it with none.
pub fn pop(&mut self) -> Option<[String; 2]> { pub fn pop(&mut self) -> Option<T> {
self.ptr = (self.ptr + SIZE - 1) % SIZE; let l = self.buf.len();
self.buf[self.ptr].take() self.ptr = (self.ptr + l - 1) % l;
self.buf[self.ptr].take()
} }
/// Returns the contained buffer in the correct order. /// Returns the contained buffer in the correct order.
pub fn get_queue(& self) -> [Option<[String; 2]>; SIZE] { pub fn get_queue(& self) -> Vec<Option<T>> {
let l = self.buf.len();
let mut queue = self.buf.clone(); let mut queue = self.buf.clone();
for i in self.ptr .. SIZE { for i in self.ptr .. l {
queue[i - self.ptr] = self.buf[i].clone(); queue[i - self.ptr] = self.buf[i].clone();
} }
for i in 0 .. self.ptr { for i in 0 .. self.ptr {
queue[SIZE - self.ptr + i] = self.buf[i].clone(); queue[l - self.ptr + i] = self.buf[i].clone();
} }
return queue return queue
@ -151,9 +154,9 @@ fn get_irc_join_messages(channels: &Vec<Value>, queue: VecDeque<Message>)
/// - None and None in the case no mention or command is recognized /// - None and None in the case no mention or command is recognized
/// - The appropriate answer as Message and None for a command /// - The appropriate answer as Message and None for a command
/// - None and the mentioned user and channel as String and the context as a MessageRingBuf for mentions. /// - None and the mentioned user and channel as String and the context as a MessageRingBuf for mentions.
fn handle_message <const SIZE: usize> (message: Message, nick: &String, fn handle_message (message: Message, nick: &String,
client_names: Keys, contexts: &mut HashMap<String, MessageRingBuf<SIZE>>) client_names: Keys, contexts: &mut HashMap<String, MessageRingBuf<[String; 2]>>)
-> (Option<Message>, Option<(String, String, [Option<[String; 2]>; SIZE])>) { -> (Option<Message>, Option<(String, String, Vec<Option<[String; 2]>>)>) {
let sender = match message.clone().source_nickname() { let sender = match message.clone().source_nickname() {
Some(s) => String::from(s), Some(s) => String::from(s),
@ -183,7 +186,7 @@ fn handle_message <const SIZE: usize> (message: Message, nick: &String,
) )
} else { } else {
match contexts.get_mut(&rec.clone()) { match contexts.get_mut(&rec.clone()) {
Some(ref buf) => { Some(ref mut buf) => {
buf.push([sender.clone(), msg.clone()]); buf.push([sender.clone(), msg.clone()]);
for c_name in client_names { for c_name in client_names {
if msg.contains(c_name) { if msg.contains(c_name) {
@ -210,8 +213,8 @@ fn handle_message <const SIZE: usize> (message: Message, nick: &String,
/// Calls handle_message on each one and pushes /// Calls handle_message on each one and pushes
/// email, server, channel as Strings /// email, server, channel as Strings
/// and the context as MessageRingBuf to the given stream. /// and the context as MessageRingBuf to the given stream.
pub fn handle_server <const SIZE: usize> pub fn handle_server
(config: Value, tx: Sender<(String, String, String, [Option<[String; 2]>; SIZE])>) (config: Value, tx: Sender<(String, String, String, Vec<Option<[String; 2]>>)>,context_size: usize)
-> Result<(), Box<dyn std::error::Error>> { -> Result<(), Box<dyn std::error::Error>> {
let server_name = config.get("server").unwrap().as_str() let server_name = config.get("server").unwrap().as_str()
@ -233,7 +236,7 @@ pub fn handle_server <const SIZE: usize>
channel.as_str() channel.as_str()
.ok_or("Could not parse one of the channels")? .ok_or("Could not parse one of the channels")?
.to_owned(), .to_owned(),
MessageRingBuf::new(), MessageRingBuf::new(context_size),
); );
} }