From e609fc296cfb84620e0af323821fc582ba2cbdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Sun, 19 Sep 2021 16:35:52 +0200 Subject: [PATCH] review forward command --- src/domain/msg/arg.rs | 12 ++-- src/domain/msg/entity.rs | 33 ++++++---- src/domain/msg/handler.rs | 132 ++++++++++++++++++-------------------- 3 files changed, 90 insertions(+), 87 deletions(-) diff --git a/src/domain/msg/arg.rs b/src/domain/msg/arg.rs index 26b423a..1dd3189 100644 --- a/src/domain/msg/arg.rs +++ b/src/domain/msg/arg.rs @@ -43,14 +43,14 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { if let Some(m) = m.subcommand_matches("attachments") { debug!("attachments command matched"); let uid = m.value_of("uid").unwrap(); - debug!("uid: {}", &uid); + debug!("uid: {}", uid); return Ok(Some(Command::Attachments(uid))); } if let Some(m) = m.subcommand_matches("copy") { debug!("copy command matched"); let uid = m.value_of("uid").unwrap(); - debug!("uid: {}", &uid); + debug!("uid: {}", uid); let target = m.value_of("target"); debug!("target mailbox: `{:?}`", target); return Ok(Some(Command::Copy(uid, target))); @@ -59,7 +59,7 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { if let Some(m) = m.subcommand_matches("delete") { debug!("copy command matched"); let uid = m.value_of("uid").unwrap(); - debug!("uid: {}", &uid); + debug!("uid: {}", uid); return Ok(Some(Command::Delete(uid))); } @@ -68,7 +68,7 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { let uid = m.value_of("uid").unwrap(); let paths: Vec<&str> = m.values_of("attachments").unwrap_or_default().collect(); debug!("attachments paths: {:?}", paths); - debug!("uid: {}", &uid); + debug!("uid: {}", uid); return Ok(Some(Command::Forward(uid, paths))); } @@ -90,7 +90,7 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { if let Some(m) = m.subcommand_matches("move") { debug!("move command matched"); let uid = m.value_of("uid").unwrap(); - debug!("uid: {}", &uid); + debug!("uid: {}", uid); let target = m.value_of("target"); debug!("target mailbox: `{:?}`", target); return Ok(Some(Command::Move(uid, target))); @@ -283,7 +283,7 @@ pub fn subcmds<'a>() -> Vec> { .arg(reply_all_arg()) .arg(msg::attachment::arg::path_arg()), SubCommand::with_name("forward") - .aliases(&["fwd"]) + .aliases(&["fwd", "f"]) .about("Forwards a message") .arg(uid_arg()) .arg(msg::attachment::arg::path_arg()), diff --git a/src/domain/msg/entity.rs b/src/domain/msg/entity.rs index 7f79ff7..44eb8c1 100644 --- a/src/domain/msg/entity.rs +++ b/src/domain/msg/entity.rs @@ -325,28 +325,39 @@ impl Msg { /// ``` pub fn change_to_forwarding(&mut self, account: &Account) { // -- Header -- - let old_subject = self.headers.subject.clone().unwrap_or(String::new()); + let subject = self + .headers + .subject + .as_ref() + .map(|sub| { + if sub.starts_with("Fwd:") { + sub.to_owned() + } else { + format!("Fwd: {}", sub) + } + }) + .unwrap_or_default(); self.headers = Headers { - subject: Some(format!("Fwd: {}", old_subject)), - sender: Some(account.address()), + subject: Some(subject), + sender: None, + reply_to: None, + message_id: None, + from: vec![account.address()], + to: vec![], // and use the rest of the headers ..self.headers.clone() }; - let mut body = String::new(); - - // -- Body -- - // apply a line which should indicate where the forwarded message begins - body.push_str(&format!( - "\n---------- Forwarded Message ----------\n{}", + // TODO: add Subject, Date, From and To headers after "Forwarded Message" + self.body = Body::new_with_text(format!( + "\n\n---------- Forwarded Message ----------\n{}", self.body .plain - .clone() + .to_owned() .unwrap_or_default() .replace("\r", ""), )); - self.body = Body::new_with_text(body); self.sig = account.signature.to_owned(); } diff --git a/src/domain/msg/handler.rs b/src/domain/msg/handler.rs index 29b5602..434192f 100644 --- a/src/domain/msg/handler.rs +++ b/src/domain/msg/handler.rs @@ -6,7 +6,7 @@ use anyhow::{Context, Result}; use atty::Stream; use imap::types::Flag; use lettre::message::header::ContentTransferEncoding; -use log::{debug, error, trace}; +use log::{debug, trace}; use std::{ borrow::Cow, convert::TryFrom, @@ -30,7 +30,10 @@ use crate::{ smtp::service::SmtpServiceInterface, }, output::service::{OutputService, OutputServiceInterface}, - ui::choice::{self, PostEditChoice}, + ui::{ + choice::{self, PostEditChoice}, + editor, + }, }; // TODO: move this function to the right folder @@ -44,76 +47,66 @@ fn msg_interaction match choice { - PostEditChoice::Send => { - debug!("sending message…"); + match choice::post_edit()? { + PostEditChoice::Send => { + debug!("sending message…"); - // prepare the msg to be send - let sendable = match msg.to_sendable_msg() { - Ok(sendable) => sendable, - // In general if an error occured, then this is normally - // due to a missing value of a header. So let's give the - // user another try and give him/her the chance to fix - // that :) - Err(err) => { - println!("{}", err); - println!("Please reedit your msg to make it to a sendable message!"); - continue; - } - }; - smtp.send(&sendable)?; - - // TODO: Gmail sent mailboxes are called `[Gmail]/Sent` - // which creates a conflict, fix this! - - // let the server know, that the user sent a msg - msg.flags.insert(Flag::Seen); - let mbox = Mbox::from("Sent"); - imap.append_msg(&mbox, msg)?; - - // remove the draft, since we sent it - msg::utils::remove_draft()?; - output.print("Message successfully sent")?; - break; - } - // edit the body of the msg - PostEditChoice::Edit => { - // Did something goes wrong when the user changed the - // content? - if let Err(err) = msg.edit_body() { - println!("[ERROR] {}", err); - println!(concat!( - "Please try to fix the problem by editing", - "the msg again." - )); + // prepare the msg to be send + let sendable = match msg.to_sendable_msg() { + Ok(sendable) => sendable, + // In general if an error occured, then this is normally + // due to a missing value of a header. So let's give the + // user another try and give him/her the chance to fix + // that :) + Err(err) => { + println!("{}", err); + println!("Please reedit your msg to make it to a sendable message!"); + continue; } - } - PostEditChoice::LocalDraft => break, - PostEditChoice::RemoteDraft => { - debug!("saving to draft…"); + }; + smtp.send(&sendable)?; - msg.flags.insert(Flag::Seen); + // TODO: Gmail sent mailboxes are called `[Gmail]/Sent` + // which creates a conflict, fix this! - let mbox = Mbox::from("Drafts"); - match imap.append_msg(&mbox, msg) { - Ok(_) => { - msg::utils::remove_draft()?; - output.print("Message successfully saved to Drafts")?; - } - Err(err) => { - output.print("Cannot save draft to the server")?; - return Err(err.into()); - } - }; - break; - } - PostEditChoice::Discard => { - msg::utils::remove_draft()?; - break; - } - }, - Err(err) => error!("{}", err), + // let the server know, that the user sent a msg + msg.flags.insert(Flag::Seen); + let mbox = Mbox::from("Sent"); + imap.append_msg(&mbox, msg)?; + + // remove the draft, since we sent it + msg::utils::remove_draft()?; + output.print("Message successfully sent")?; + break; + } + // edit the body of the msg + PostEditChoice::Edit => { + Msg::parse_from_str(msg, &editor::open_editor_with_draft()?)?; + continue; + } + PostEditChoice::LocalDraft => break, + PostEditChoice::RemoteDraft => { + debug!("saving to draft…"); + + msg.flags.insert(Flag::Seen); + + let mbox = Mbox::from("Drafts"); + match imap.append_msg(&mbox, msg) { + Ok(_) => { + msg::utils::remove_draft()?; + output.print("Message successfully saved to Drafts")?; + } + Err(err) => { + output.print("Cannot save draft to the server")?; + return Err(err.into()); + } + }; + break; + } + PostEditChoice::Discard => { + msg::utils::remove_draft()?; + break; + } } } @@ -186,6 +179,7 @@ pub fn delete( uid: &str, attachments_paths: Vec<&str>, @@ -195,14 +189,12 @@ pub fn forward Result<()> { let mut msg = imap.get_msg(&uid)?; - // prepare to forward it msg.change_to_forwarding(&account); attachments_paths .iter() .for_each(|path| msg.add_attachment(path)); debug!("found {} attachments", attachments_paths.len()); trace!("attachments: {:?}", attachments_paths); - // apply changes msg_interaction(output, &mut msg, imap, smtp)?; imap.logout()?; Ok(())