aboutsummaryrefslogtreecommitdiff
path: root/src/mail.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mail.rs')
-rw-r--r--src/mail.rs107
1 files changed, 0 insertions, 107 deletions
diff --git a/src/mail.rs b/src/mail.rs
deleted file mode 100644
index d7df246..0000000
--- a/src/mail.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use chrono::Utc;
-use std::io::{Error, ErrorKind};
-use std::process::{Output, Stdio};
-use tokio::io::AsyncWriteExt;
-use tokio::process::Command;
-
-use crate::model::config::Config;
-
-static FROM_NAME: &str = "Budget";
-
-#[derive(Clone)]
-pub struct Recipient {
- pub name: String,
- pub address: String,
-}
-
-pub async fn send(
- config: &Config,
- recipients: Vec<Recipient>,
- subject: &str,
- message: &str,
-) -> bool {
- let headers = format_headers(config, recipients.clone(), subject);
-
- log::info!(
- "Sending mail{}\n{}",
- if config.mails_mock { " (MOCK)" } else { "" },
- headers.clone()
- );
-
- if config.mails_mock {
- true
- } else {
- let recipient_addresses = recipients
- .clone()
- .into_iter()
- .map(|r| r.address)
- .collect::<Vec<String>>();
-
- // https://github.com/NixOS/nixpkgs/issues/90248
- let mut command = Command::new("/run/wrappers/bin/sendmail");
- command.kill_on_drop(true);
- command.arg("-f").arg(config.mails_from.clone());
- command.arg("--").args(recipient_addresses);
- command
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped());
-
- let message = format!("{}\n\n{}", headers, message);
- match spawn(command, &message.into_bytes()).await {
- Ok(output) => {
- if output.status.success() {
- log::info!("Mail sent");
- true
- } else {
- match String::from_utf8(output.stderr) {
- Ok(error) => {
- log::error!("Error sending email: {}", error)
- }
- _ => log::error!("Error sending email"),
- };
- false
- }
- }
- Err(err) => {
- log::error!("Error spawning command: {:?}", err);
- false
- }
- }
- }
-}
-
-fn format_headers(
- config: &Config,
- recipients: Vec<Recipient>,
- subject: &str,
-) -> String {
- let recipients = recipients
- .into_iter()
- .map(|r| format_address(&r.name, &r.address))
- .collect::<Vec<String>>()
- .join(", ");
-
- format!(
- "Date: {}\nFrom: {}\nTo: {}\nSubject: {}",
- Utc::now().to_rfc2822(),
- format_address(FROM_NAME, &config.mails_from),
- recipients,
- subject,
- )
-}
-
-fn format_address(name: &str, address: &str) -> String {
- format!("{name} <{address}>")
-}
-
-async fn spawn(mut command: Command, stdin: &[u8]) -> Result<Output, Error> {
- let mut process = command.spawn()?;
- process
- .stdin
- .as_mut()
- .ok_or(Error::new(ErrorKind::Other, "Getting mutable stdin"))?
- .write_all(stdin)
- .await?;
- process.wait_with_output().await
-}