Try to save sent messages elsewhere if Sent folder fails
If Sent folder wasn't correctly configured, the sent message would be lost. With this change it tries these folders in this order: 1. Sent 2. Inbox 3. Any other normal folder The check is done by looking at the special usage metadata on each folder. If everything fails, the message is saved in a file in the tmpfs.embed
parent
ed248be031
commit
26e4d50b40
|
@ -616,6 +616,7 @@ impl Component for Composer {
|
|||
self.draft.to_string().unwrap().as_str().as_bytes(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
|
||||
// TODO: check exit status
|
||||
|
@ -773,47 +774,63 @@ pub fn send_draft(context: &mut Context, account_cursor: usize, draft: Draft) ->
|
|||
stdin
|
||||
.write_all(draft.as_bytes())
|
||||
.expect("Failed to write to stdin");
|
||||
if let Err(e) = context.accounts[account_cursor].save(
|
||||
draft.as_bytes(),
|
||||
&context.accounts[account_cursor].sent_folder(),
|
||||
Some(Flag::SEEN),
|
||||
) {
|
||||
debug!("{:?} could not save sent msg", e);
|
||||
for folder in &[
|
||||
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Sent),
|
||||
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Inbox),
|
||||
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Normal),
|
||||
] {
|
||||
if let Err(e) =
|
||||
context.accounts[account_cursor].save(draft.as_bytes(), folder, Some(Flag::SEEN))
|
||||
{
|
||||
debug!("{:?} could not save sent msg", e);
|
||||
context.replies.push_back(UIEvent::Notification(
|
||||
Some(format!("Could not save in '{}' folder.", folder)),
|
||||
e.into(),
|
||||
Some(NotificationType::ERROR),
|
||||
));
|
||||
} else {
|
||||
failure = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if failure {
|
||||
let file = create_temp_file(draft.as_bytes(), None, None, false);
|
||||
debug!("message saved in {}", file.path.display());
|
||||
context.replies.push_back(UIEvent::Notification(
|
||||
Some("Could not save in 'Sent' folder.".into()),
|
||||
e.into(),
|
||||
Some(NotificationType::ERROR),
|
||||
Some("Could not save in any folder".into()),
|
||||
format!(
|
||||
"Message was stored in {} so that you can restore it manually.",
|
||||
file.path.display()
|
||||
),
|
||||
Some(NotificationType::INFO),
|
||||
));
|
||||
} else {
|
||||
failure = false;
|
||||
}
|
||||
}
|
||||
if !failure {
|
||||
let output = msmtp.wait().expect("Failed to wait on mailer");
|
||||
if output.success() {
|
||||
context.replies.push_back(UIEvent::Notification(
|
||||
Some("Sent.".into()),
|
||||
String::new(),
|
||||
None,
|
||||
));
|
||||
let output = msmtp.wait().expect("Failed to wait on mailer");
|
||||
if output.success() {
|
||||
context.replies.push_back(UIEvent::Notification(
|
||||
Some("Sent.".into()),
|
||||
String::new(),
|
||||
None,
|
||||
));
|
||||
} else {
|
||||
if let Some(exit_code) = output.code() {
|
||||
log(
|
||||
format!(
|
||||
"Could not send e-mail using `{}`: Process exited with {}",
|
||||
cmd, exit_code
|
||||
),
|
||||
ERROR,
|
||||
);
|
||||
} else {
|
||||
if let Some(exit_code) = output.code() {
|
||||
log(
|
||||
format!(
|
||||
"Could not send e-mail using `{}`: Process exited with {}",
|
||||
cmd, exit_code
|
||||
),
|
||||
ERROR,
|
||||
);
|
||||
} else {
|
||||
log(
|
||||
format!(
|
||||
"Could not send e-mail using `{}`: Process was killed by signal",
|
||||
cmd
|
||||
),
|
||||
ERROR,
|
||||
);
|
||||
}
|
||||
log(
|
||||
format!(
|
||||
"Could not send e-mail using `{}`: Process was killed by signal",
|
||||
cmd
|
||||
),
|
||||
ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
!failure
|
||||
|
|
|
@ -785,6 +785,7 @@ impl Component for MailView {
|
|||
&decode(u, None),
|
||||
name.as_ref().map(|n| n.clone()),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
Command::new(&binary)
|
||||
.arg(p.path())
|
||||
|
|
|
@ -448,6 +448,7 @@ impl Component for EnvelopeView {
|
|||
&decode(u, None),
|
||||
name.as_ref().map(|n| n.clone()),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
Command::new(&binary)
|
||||
.arg(p.path())
|
||||
|
|
|
@ -134,7 +134,7 @@ impl Component for HtmlView {
|
|||
// scripts)
|
||||
let binary = query_default_app("text/html");
|
||||
if let Ok(binary) = binary {
|
||||
let p = create_temp_file(&self.bytes, None, None);
|
||||
let p = create_temp_file(&self.bytes, None, None, true);
|
||||
Command::new(&binary)
|
||||
.arg(p.path())
|
||||
.stdin(Stdio::piped())
|
||||
|
|
|
@ -771,6 +771,19 @@ impl Account {
|
|||
""
|
||||
}
|
||||
}
|
||||
|
||||
pub fn special_use_folder(&self, special_use: SpecialUseMailbox) -> &str {
|
||||
let ret = self
|
||||
.settings
|
||||
.folder_confs
|
||||
.iter()
|
||||
.find(|(_, f)| f.usage == Some(special_use));
|
||||
if let Some(ret) = ret.as_ref() {
|
||||
ret.0
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<FolderHash> for Account {
|
||||
|
|
|
@ -29,12 +29,15 @@ use uuid::Uuid;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct File {
|
||||
path: PathBuf,
|
||||
pub path: PathBuf,
|
||||
delete_on_drop: bool,
|
||||
}
|
||||
|
||||
impl Drop for File {
|
||||
fn drop(&mut self) {
|
||||
std::fs::remove_file(self.path()).unwrap_or_else(|_| {});
|
||||
if self.delete_on_drop {
|
||||
std::fs::remove_file(self.path()).unwrap_or_else(|_| {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,9 +64,14 @@ impl File {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returned `File` will be deleted when dropped, so make sure to add it on `context.temp_files`
|
||||
/// Returned `File` will be deleted when dropped if delete_on_drop is set, so make sure to add it on `context.temp_files`
|
||||
/// to reap it later.
|
||||
pub fn create_temp_file(bytes: &[u8], filename: Option<String>, path: Option<&PathBuf>) -> File {
|
||||
pub fn create_temp_file(
|
||||
bytes: &[u8],
|
||||
filename: Option<String>,
|
||||
path: Option<&PathBuf>,
|
||||
delete_on_drop: bool,
|
||||
) -> File {
|
||||
let mut dir = std::env::temp_dir();
|
||||
|
||||
let path = if let Some(p) = path {
|
||||
|
@ -87,5 +95,8 @@ pub fn create_temp_file(bytes: &[u8], filename: Option<String>, path: Option<&Pa
|
|||
|
||||
f.write_all(bytes).unwrap();
|
||||
f.flush().unwrap();
|
||||
File { path: path.clone() }
|
||||
File {
|
||||
path: path.clone(),
|
||||
delete_on_drop,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue