mirror of
https://github.com/soywod/himalaya.git
synced 2024-07-05 09:05:13 +00:00
review forward command
This commit is contained in:
parent
65664d5405
commit
e609fc296c
|
@ -43,14 +43,14 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result<Option<Command<'a>>> {
|
|||
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<Option<Command<'a>>> {
|
|||
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<Option<Command<'a>>> {
|
|||
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<Option<Command<'a>>> {
|
|||
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<App<'a, 'a>> {
|
|||
.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()),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ImapService: ImapServiceInterface, SmtpService: SmtpServiceIn
|
|||
msg.edit_body()?;
|
||||
|
||||
loop {
|
||||
match choice::post_edit() {
|
||||
Ok(choice) => 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<OutputService: OutputServiceInterface, ImapService: ImapServiceInt
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Forward the given message UID from the selected mailbox.
|
||||
pub fn forward<ImapService: ImapServiceInterface, SmtpService: SmtpServiceInterface>(
|
||||
uid: &str,
|
||||
attachments_paths: Vec<&str>,
|
||||
|
@ -195,14 +189,12 @@ pub fn forward<ImapService: ImapServiceInterface, SmtpService: SmtpServiceInterf
|
|||
smtp: &mut SmtpService,
|
||||
) -> 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(())
|
||||
|
|
Loading…
Reference in a new issue