From ed5ab292e4c3279200698d63749bd67f0780ff93 Mon Sep 17 00:00:00 2001 From: jb-alvarado Date: Wed, 25 May 2022 14:54:16 +0200 Subject: [PATCH] allow multiple recipients, fix program exit after mail sending --- src/main.rs | 20 ++++++++++-------- src/utils/logging.rs | 49 ++++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index fac3efe5..4feba587 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,14 +61,16 @@ fn main() { let play_control = PlayerControl::new(); let playout_stat = PlayoutStatus::new(); let proc_control = ProcessControl::new(); - let proc_ctl = proc_control.clone(); + let play_ctl = play_control.clone(); + let play_stat = playout_stat.clone(); + let proc_ctl1 = proc_control.clone(); + let proc_ctl2 = proc_control.clone(); let messages = Arc::new(Mutex::new(Vec::new())); - let logging = init_logging(&config, proc_ctl, messages.clone()); + let logging = init_logging(&config, proc_ctl1, messages.clone()); CombinedLogger::init(logging).unwrap(); validate_ffmpeg(&config); - status_file(&config.general.stat_file, &playout_stat); if let Some(range) = config.general.generate.clone() { // run a simple playlist generator and save them to disk @@ -77,15 +79,13 @@ fn main() { exit(0); } - let play_ctl = play_control.clone(); - let play_stat = playout_stat.clone(); - let proc_ctl = proc_control.clone(); - if config.rpc_server.enable { // If RPC server is enable we also fire up a JSON RPC server. - thread::spawn(move || json_rpc_server(config_clone, play_ctl, play_stat, proc_ctl)); + thread::spawn(move || json_rpc_server(config_clone, play_ctl, play_stat, proc_ctl2)); } + status_file(&config.general.stat_file, &playout_stat); + if &config.out.mode.to_lowercase() == "hls" { // write files/playlist to HLS m3u8 playlist write_hls(&config, play_control, playout_stat, proc_control); @@ -94,11 +94,13 @@ fn main() { player(&config, play_control, playout_stat, proc_control); } + info!("Playout done..."); + let msg = messages.lock().unwrap(); if msg.len() > 0 { send_mail(&config, msg.join("\n")); } - info!("Playout done..."); + drop(msg); } diff --git a/src/utils/logging.rs b/src/utils/logging.rs index 56ab8f47..88a379f4 100644 --- a/src/utils/logging.rs +++ b/src/utils/logging.rs @@ -26,30 +26,41 @@ use crate::utils::{GlobalConfig, ProcessControl}; /// send log messages to mail recipient pub fn send_mail(cfg: &GlobalConfig, msg: String) { - if let Ok(email) = Message::builder() + let recip = cfg + .mail + .recipient + .split_terminator([',', ';', ' ']) + .filter(|s| s.contains('@')) + .map(|s| s.trim()) + .collect::>(); + + let mut message = Message::builder() .from(cfg.mail.sender_addr.parse().unwrap()) - .to(cfg.mail.recipient.parse().unwrap()) - .subject(cfg.mail.subject.clone()) - .header(header::ContentType::TEXT_PLAIN) - .body(clean_string(&msg)) - { + .subject(&cfg.mail.subject) + .header(header::ContentType::TEXT_PLAIN); + + for r in recip { + message = message.to(r.parse().unwrap()); + } + + if let Ok(email) = message.body(clean_string(&msg)) { let credentials = Credentials::new(cfg.mail.sender_addr.clone(), cfg.mail.sender_pass.clone()); let mut transporter = SmtpTransport::relay(cfg.mail.smtp_server.clone().as_str()); if cfg.mail.starttls { - transporter = SmtpTransport::starttls_relay(cfg.mail.smtp_server.clone().as_str()) + transporter = SmtpTransport::starttls_relay(cfg.mail.smtp_server.clone().as_str()); } let mailer = transporter.unwrap().credentials(credentials).build(); // Send the email if let Err(e) = mailer.send(&email) { - error!("Could not send email: {:?}", e) + error!("Could not send email: {:?}", e); } } else { - error!("Mail Message failed!") + error!("Mail Message failed!"); } } @@ -62,14 +73,16 @@ fn mail_queue( messages: Arc>>, interval: u64, ) { - while !proc_ctl.is_terminated.load(Ordering::SeqCst) { - if messages.lock().unwrap().len() > 0 { - let msg = messages.lock().unwrap().join("\n"); - send_mail(&cfg, msg); + while !(*proc_ctl.is_terminated).load(Ordering::SeqCst) { + let mut msg = messages.lock().unwrap(); - messages.lock().unwrap().clear(); + if msg.len() > 0 { + send_mail(&cfg, msg.join("\n")); + msg.clear(); } + drop(msg); + sleep(Duration::from_secs(interval)); } } @@ -104,9 +117,6 @@ impl Log for LogMailer { fn log(&self, record: &Record<'_>) { if self.enabled(record.metadata()) { - let local: DateTime = Local::now(); - let time_stamp = local.format("[%Y-%m-%d %H:%M:%S%.3f]"); - let level = record.level().to_string().to_uppercase(); let rec = record.args().to_string(); let mut last_msg = self.last_message.lock().unwrap(); @@ -114,7 +124,10 @@ impl Log for LogMailer { // this we do to prevent spamming the mail box if *last_msg != rec { *last_msg = rec.clone(); - let full_line: String = format!("{time_stamp} [{level: >5}] {rec}"); + let local: DateTime = Local::now(); + let time_stamp = local.format("[%Y-%m-%d %H:%M:%S%.3f]"); + let level = record.level().to_string().to_uppercase(); + let full_line = format!("{time_stamp} [{level: >5}] {rec}"); self.messages.lock().unwrap().push(full_line); }