summaryrefslogtreecommitdiffstats
path: root/src/conf
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-08 16:52:13 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-11 16:53:04 +0300
commita2f11c341d66715ac5a311b7a68264200e5e2ade (patch)
treecb385ccec1eb10b6ead5a19a8d64608135c59469 /src/conf
parentafee1e2be5fe0232e8c3c66a3a03a21ccc7635d6 (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.rs63
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,