diff --git a/Cargo.lock b/Cargo.lock index b66de70a..5b38ad7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2155,11 +2155,14 @@ version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a62049a808f1c4e2356a2a380bd5f2aca3b011b0b482cf3b914ba1731426969" dependencies = [ + "async-trait", "base64 0.22.1", "chumsky", "email-encoding", "email_address", "fastrand 2.1.0", + "futures-io", + "futures-util", "httpdate", "idna", "mime", diff --git a/ffplayout/Cargo.toml b/ffplayout/Cargo.toml index d5973a21..eff220ca 100644 --- a/ffplayout/Cargo.toml +++ b/ffplayout/Cargo.toml @@ -31,7 +31,7 @@ futures-util = { version = "0.3", default-features = false, features = ["std"] } home = "0.5" jsonwebtoken = "9" lazy_static = "1.4" -lettre = { version = "0.11", features = ["builder", "rustls-tls", "smtp-transport"], default-features = false } +lettre = { version = "0.11", features = ["builder", "rustls-tls", "smtp-transport", "tokio1"], default-features = false } lexical-sort = "0.3" local-ip-address = "0.6" log = { version = "0.4", features = ["std", "serde", "kv", "kv_std", "kv_sval", "kv_serde"] } diff --git a/ffplayout/src/utils/logging.rs b/ffplayout/src/utils/logging.rs index 6741be98..41da1c19 100644 --- a/ffplayout/src/utils/logging.rs +++ b/ffplayout/src/utils/logging.rs @@ -1,6 +1,3 @@ -extern crate log; -extern crate simplelog; - use std::{ collections::HashMap, io::{self, ErrorKind, Write}, @@ -10,14 +7,15 @@ use std::{ time::Duration, }; +use actix_web::{rt::time::interval, web}; use chrono::prelude::*; use flexi_logger::writers::{FileLogWriter, LogWriter}; use flexi_logger::{Age, Cleanup, Criterion, DeferredNow, FileSpec, Logger, Naming}; use lettre::{ - message::header, transport::smtp::authentication::Credentials, Message, SmtpTransport, - Transport, + message::header, transport::smtp::authentication::Credentials, AsyncSmtpTransport, + AsyncTransport, Message, Tokio1Executor, }; -use log::{kv::Value, Level, LevelFilter, Log, Metadata, Record}; +use log::{kv::Value, *}; use paris::formatter::colorize_string; use crate::utils::{ @@ -140,6 +138,76 @@ fn file_logger(config: &Logging) -> Box { } } +/// send log messages to mail recipient +pub async fn send_mail(config: &PlayoutConfig, msg: String) { + let recipient = config + .mail + .recipient + .split_terminator([',', ';', ' ']) + .filter(|s| s.contains('@')) + .map(|s| s.trim()) + .collect::>(); + + let mut message = Message::builder() + .from(config.mail.sender_addr.parse().unwrap()) + .subject(&config.mail.subject) + .header(header::ContentType::TEXT_PLAIN); + + for r in recipient { + message = message.to(r.parse().unwrap()); + } + + if let Ok(mail) = message.body(msg) { + let credentials = Credentials::new( + config.mail.sender_addr.clone(), + config.mail.sender_pass.clone(), + ); + + let mut transporter = + AsyncSmtpTransport::::relay(config.mail.smtp_server.clone().as_str()); + + if config.mail.starttls { + transporter = AsyncSmtpTransport::::starttls_relay( + config.mail.smtp_server.clone().as_str(), + ); + } + + let mailer = transporter.unwrap().credentials(credentials).build(); + + // Send the mail + if let Err(e) = mailer.send(&mail).await? { + error!(target: "{file}", channel = 1; "Could not send mail: {e}"); + } + } else { + error!(target: "{file}", channel = 1; "Mail Message failed!"); + } +} + +/// Basic Mail Queue +/// +/// Check every give seconds for messages and send them. +fn mail_queue(config: PlayoutConfig, messages: Arc>>) { + let sec = config.mail.interval; + + actix_web::rt::spawn(async move { + let mut interval = interval(Duration::from_secs(sec)); + + loop { + let mut msg = messages.lock().unwrap(); + + if msg.len() > 0 { + send_mail(&config, msg.join("\n")).await; + + msg.clear(); + } + + drop(msg); + + interval.tick().await; + } + }); +} + /// Initialize our logging, to have: /// /// - console logger