diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-10-08 16:52:13 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-10-11 16:53:04 +0300 |
commit | a2f11c341d66715ac5a311b7a68264200e5e2ade (patch) | |
tree | cb385ccec1eb10b6ead5a19a8d64608135c59469 /src/conf | |
parent | afee1e2be5fe0232e8c3c66a3a03a21ccc7635d6 (diff) |
compose: add async draft filter stack in sending mail
Add a stack of "filter" closures that edit a draft before sending it.
Add PGP signing filter. An encryption filter will be added in a future
commit.
Diffstat (limited to 'src/conf')
-rw-r--r-- | src/conf/accounts.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/conf/accounts.rs b/src/conf/accounts.rs index 593f14b8..dc034673 100644 --- a/src/conf/accounts.rs +++ b/src/conf/accounts.rs @@ -48,6 +48,7 @@ use std::borrow::Cow; use std::collections::VecDeque; use std::convert::TryFrom; use std::fs; +use std::future::Future; use std::io; use std::ops::{Index, IndexMut}; use std::os::unix::fs::PermissionsExt; @@ -1277,6 +1278,68 @@ impl Account { } } + pub fn send_async( + &self, + send_mail: crate::conf::composing::SendMail, + ) -> impl FnOnce(Arc<String>) -> Pin<Box<dyn Future<Output = Result<()>> + Send>> + Send { + |message: Arc<String>| -> Pin<Box<dyn Future<Output = Result<()>> + Send>> { + Box::pin(async move { + use crate::conf::composing::SendMail; + use std::io::Write; + use std::process::{Command, Stdio}; + match send_mail { + SendMail::ShellCommand(ref command) => { + if command.is_empty() { + return Err(MeliError::new( + "send_mail shell command configuration value is empty", + )); + } + let mut msmtp = Command::new("sh") + .args(&["-c", command]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to start mailer command"); + { + let stdin = msmtp.stdin.as_mut().expect("failed to open stdin"); + stdin + .write_all(message.as_bytes()) + .expect("Failed to write to stdin"); + } + let output = msmtp.wait().expect("Failed to wait on mailer"); + if output.success() { + melib::log("Message sent.", melib::LoggingLevel::TRACE); + } else { + let error_message = if let Some(exit_code) = output.code() { + format!( + "Could not send e-mail using `{}`: Process exited with {}", + command, exit_code + ) + } else { + format!( + "Could not send e-mail using `{}`: Process was killed by signal", + command + ) + }; + melib::log(&error_message, melib::LoggingLevel::ERROR); + return Err(MeliError::new(error_message.clone()) + .set_summary("Message not sent.")); + } + Ok(()) + } + #[cfg(feature = "smtp")] + SendMail::Smtp(conf) => { + let mut smtp_connection = + melib::smtp::SmtpConnection::new_connection(conf).await?; + smtp_connection + .mail_transaction(message.as_str(), None) + .await + } + } + }) + } + } + pub fn delete( &mut self, env_hash: EnvelopeHash, |