mirror of
https://github.com/soywod/himalaya.git
synced 2024-07-08 18:45: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") {
|
if let Some(m) = m.subcommand_matches("attachments") {
|
||||||
debug!("attachments command matched");
|
debug!("attachments command matched");
|
||||||
let uid = m.value_of("uid").unwrap();
|
let uid = m.value_of("uid").unwrap();
|
||||||
debug!("uid: {}", &uid);
|
debug!("uid: {}", uid);
|
||||||
return Ok(Some(Command::Attachments(uid)));
|
return Ok(Some(Command::Attachments(uid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(m) = m.subcommand_matches("copy") {
|
if let Some(m) = m.subcommand_matches("copy") {
|
||||||
debug!("copy command matched");
|
debug!("copy command matched");
|
||||||
let uid = m.value_of("uid").unwrap();
|
let uid = m.value_of("uid").unwrap();
|
||||||
debug!("uid: {}", &uid);
|
debug!("uid: {}", uid);
|
||||||
let target = m.value_of("target");
|
let target = m.value_of("target");
|
||||||
debug!("target mailbox: `{:?}`", target);
|
debug!("target mailbox: `{:?}`", target);
|
||||||
return Ok(Some(Command::Copy(uid, 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") {
|
if let Some(m) = m.subcommand_matches("delete") {
|
||||||
debug!("copy command matched");
|
debug!("copy command matched");
|
||||||
let uid = m.value_of("uid").unwrap();
|
let uid = m.value_of("uid").unwrap();
|
||||||
debug!("uid: {}", &uid);
|
debug!("uid: {}", uid);
|
||||||
return Ok(Some(Command::Delete(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 uid = m.value_of("uid").unwrap();
|
||||||
let paths: Vec<&str> = m.values_of("attachments").unwrap_or_default().collect();
|
let paths: Vec<&str> = m.values_of("attachments").unwrap_or_default().collect();
|
||||||
debug!("attachments paths: {:?}", paths);
|
debug!("attachments paths: {:?}", paths);
|
||||||
debug!("uid: {}", &uid);
|
debug!("uid: {}", uid);
|
||||||
return Ok(Some(Command::Forward(uid, paths)));
|
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") {
|
if let Some(m) = m.subcommand_matches("move") {
|
||||||
debug!("move command matched");
|
debug!("move command matched");
|
||||||
let uid = m.value_of("uid").unwrap();
|
let uid = m.value_of("uid").unwrap();
|
||||||
debug!("uid: {}", &uid);
|
debug!("uid: {}", uid);
|
||||||
let target = m.value_of("target");
|
let target = m.value_of("target");
|
||||||
debug!("target mailbox: `{:?}`", target);
|
debug!("target mailbox: `{:?}`", target);
|
||||||
return Ok(Some(Command::Move(uid, 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(reply_all_arg())
|
||||||
.arg(msg::attachment::arg::path_arg()),
|
.arg(msg::attachment::arg::path_arg()),
|
||||||
SubCommand::with_name("forward")
|
SubCommand::with_name("forward")
|
||||||
.aliases(&["fwd"])
|
.aliases(&["fwd", "f"])
|
||||||
.about("Forwards a message")
|
.about("Forwards a message")
|
||||||
.arg(uid_arg())
|
.arg(uid_arg())
|
||||||
.arg(msg::attachment::arg::path_arg()),
|
.arg(msg::attachment::arg::path_arg()),
|
||||||
|
|
|
@ -325,28 +325,39 @@ impl Msg {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn change_to_forwarding(&mut self, account: &Account) {
|
pub fn change_to_forwarding(&mut self, account: &Account) {
|
||||||
// -- Header --
|
// -- 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 {
|
self.headers = Headers {
|
||||||
subject: Some(format!("Fwd: {}", old_subject)),
|
subject: Some(subject),
|
||||||
sender: Some(account.address()),
|
sender: None,
|
||||||
|
reply_to: None,
|
||||||
|
message_id: None,
|
||||||
|
from: vec![account.address()],
|
||||||
|
to: vec![],
|
||||||
// and use the rest of the headers
|
// and use the rest of the headers
|
||||||
..self.headers.clone()
|
..self.headers.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut body = String::new();
|
// TODO: add Subject, Date, From and To headers after "Forwarded Message"
|
||||||
|
self.body = Body::new_with_text(format!(
|
||||||
// -- Body --
|
"\n\n---------- Forwarded Message ----------\n{}",
|
||||||
// apply a line which should indicate where the forwarded message begins
|
|
||||||
body.push_str(&format!(
|
|
||||||
"\n---------- Forwarded Message ----------\n{}",
|
|
||||||
self.body
|
self.body
|
||||||
.plain
|
.plain
|
||||||
.clone()
|
.to_owned()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.replace("\r", ""),
|
.replace("\r", ""),
|
||||||
));
|
));
|
||||||
self.body = Body::new_with_text(body);
|
|
||||||
self.sig = account.signature.to_owned();
|
self.sig = account.signature.to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use anyhow::{Context, Result};
|
||||||
use atty::Stream;
|
use atty::Stream;
|
||||||
use imap::types::Flag;
|
use imap::types::Flag;
|
||||||
use lettre::message::header::ContentTransferEncoding;
|
use lettre::message::header::ContentTransferEncoding;
|
||||||
use log::{debug, error, trace};
|
use log::{debug, trace};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
|
@ -30,7 +30,10 @@ use crate::{
|
||||||
smtp::service::SmtpServiceInterface,
|
smtp::service::SmtpServiceInterface,
|
||||||
},
|
},
|
||||||
output::service::{OutputService, OutputServiceInterface},
|
output::service::{OutputService, OutputServiceInterface},
|
||||||
ui::choice::{self, PostEditChoice},
|
ui::{
|
||||||
|
choice::{self, PostEditChoice},
|
||||||
|
editor,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: move this function to the right folder
|
// TODO: move this function to the right folder
|
||||||
|
@ -44,76 +47,66 @@ fn msg_interaction<ImapService: ImapServiceInterface, SmtpService: SmtpServiceIn
|
||||||
msg.edit_body()?;
|
msg.edit_body()?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match choice::post_edit() {
|
match choice::post_edit()? {
|
||||||
Ok(choice) => match choice {
|
PostEditChoice::Send => {
|
||||||
PostEditChoice::Send => {
|
debug!("sending message…");
|
||||||
debug!("sending message…");
|
|
||||||
|
|
||||||
// prepare the msg to be send
|
// prepare the msg to be send
|
||||||
let sendable = match msg.to_sendable_msg() {
|
let sendable = match msg.to_sendable_msg() {
|
||||||
Ok(sendable) => sendable,
|
Ok(sendable) => sendable,
|
||||||
// In general if an error occured, then this is normally
|
// In general if an error occured, then this is normally
|
||||||
// due to a missing value of a header. So let's give the
|
// due to a missing value of a header. So let's give the
|
||||||
// user another try and give him/her the chance to fix
|
// user another try and give him/her the chance to fix
|
||||||
// that :)
|
// that :)
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("{}", err);
|
println!("{}", err);
|
||||||
println!("Please reedit your msg to make it to a sendable message!");
|
println!("Please reedit your msg to make it to a sendable message!");
|
||||||
continue;
|
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."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
PostEditChoice::LocalDraft => break,
|
smtp.send(&sendable)?;
|
||||||
PostEditChoice::RemoteDraft => {
|
|
||||||
debug!("saving to draft…");
|
|
||||||
|
|
||||||
msg.flags.insert(Flag::Seen);
|
// TODO: Gmail sent mailboxes are called `[Gmail]/Sent`
|
||||||
|
// which creates a conflict, fix this!
|
||||||
|
|
||||||
let mbox = Mbox::from("Drafts");
|
// let the server know, that the user sent a msg
|
||||||
match imap.append_msg(&mbox, msg) {
|
msg.flags.insert(Flag::Seen);
|
||||||
Ok(_) => {
|
let mbox = Mbox::from("Sent");
|
||||||
msg::utils::remove_draft()?;
|
imap.append_msg(&mbox, msg)?;
|
||||||
output.print("Message successfully saved to Drafts")?;
|
|
||||||
}
|
// remove the draft, since we sent it
|
||||||
Err(err) => {
|
msg::utils::remove_draft()?;
|
||||||
output.print("Cannot save draft to the server")?;
|
output.print("Message successfully sent")?;
|
||||||
return Err(err.into());
|
break;
|
||||||
}
|
}
|
||||||
};
|
// edit the body of the msg
|
||||||
break;
|
PostEditChoice::Edit => {
|
||||||
}
|
Msg::parse_from_str(msg, &editor::open_editor_with_draft()?)?;
|
||||||
PostEditChoice::Discard => {
|
continue;
|
||||||
msg::utils::remove_draft()?;
|
}
|
||||||
break;
|
PostEditChoice::LocalDraft => break,
|
||||||
}
|
PostEditChoice::RemoteDraft => {
|
||||||
},
|
debug!("saving to draft…");
|
||||||
Err(err) => error!("{}", err),
|
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Forward the given message UID from the selected mailbox.
|
||||||
pub fn forward<ImapService: ImapServiceInterface, SmtpService: SmtpServiceInterface>(
|
pub fn forward<ImapService: ImapServiceInterface, SmtpService: SmtpServiceInterface>(
|
||||||
uid: &str,
|
uid: &str,
|
||||||
attachments_paths: Vec<&str>,
|
attachments_paths: Vec<&str>,
|
||||||
|
@ -195,14 +189,12 @@ pub fn forward<ImapService: ImapServiceInterface, SmtpService: SmtpServiceInterf
|
||||||
smtp: &mut SmtpService,
|
smtp: &mut SmtpService,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut msg = imap.get_msg(&uid)?;
|
let mut msg = imap.get_msg(&uid)?;
|
||||||
// prepare to forward it
|
|
||||||
msg.change_to_forwarding(&account);
|
msg.change_to_forwarding(&account);
|
||||||
attachments_paths
|
attachments_paths
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|path| msg.add_attachment(path));
|
.for_each(|path| msg.add_attachment(path));
|
||||||
debug!("found {} attachments", attachments_paths.len());
|
debug!("found {} attachments", attachments_paths.len());
|
||||||
trace!("attachments: {:?}", attachments_paths);
|
trace!("attachments: {:?}", attachments_paths);
|
||||||
// apply changes
|
|
||||||
msg_interaction(output, &mut msg, imap, smtp)?;
|
msg_interaction(output, &mut msg, imap, smtp)?;
|
||||||
imap.logout()?;
|
imap.logout()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue