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(),
|
self.draft.to_string().unwrap().as_str().as_bytes(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: check exit status
|
// TODO: check exit status
|
||||||
|
@ -773,47 +774,63 @@ pub fn send_draft(context: &mut Context, account_cursor: usize, draft: Draft) ->
|
||||||
stdin
|
stdin
|
||||||
.write_all(draft.as_bytes())
|
.write_all(draft.as_bytes())
|
||||||
.expect("Failed to write to stdin");
|
.expect("Failed to write to stdin");
|
||||||
if let Err(e) = context.accounts[account_cursor].save(
|
for folder in &[
|
||||||
draft.as_bytes(),
|
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Sent),
|
||||||
&context.accounts[account_cursor].sent_folder(),
|
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Inbox),
|
||||||
Some(Flag::SEEN),
|
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Normal),
|
||||||
) {
|
] {
|
||||||
debug!("{:?} could not save sent msg", e);
|
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(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not save in 'Sent' folder.".into()),
|
Some("Could not save in any folder".into()),
|
||||||
e.into(),
|
format!(
|
||||||
Some(NotificationType::ERROR),
|
"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");
|
||||||
let output = msmtp.wait().expect("Failed to wait on mailer");
|
if output.success() {
|
||||||
if output.success() {
|
context.replies.push_back(UIEvent::Notification(
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Some("Sent.".into()),
|
||||||
Some("Sent.".into()),
|
String::new(),
|
||||||
String::new(),
|
None,
|
||||||
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 {
|
} else {
|
||||||
if let Some(exit_code) = output.code() {
|
log(
|
||||||
log(
|
format!(
|
||||||
format!(
|
"Could not send e-mail using `{}`: Process was killed by signal",
|
||||||
"Could not send e-mail using `{}`: Process exited with {}",
|
cmd
|
||||||
cmd, exit_code
|
),
|
||||||
),
|
ERROR,
|
||||||
ERROR,
|
);
|
||||||
);
|
|
||||||
} else {
|
|
||||||
log(
|
|
||||||
format!(
|
|
||||||
"Could not send e-mail using `{}`: Process was killed by signal",
|
|
||||||
cmd
|
|
||||||
),
|
|
||||||
ERROR,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
!failure
|
!failure
|
||||||
|
|
|
@ -785,6 +785,7 @@ impl Component for MailView {
|
||||||
&decode(u, None),
|
&decode(u, None),
|
||||||
name.as_ref().map(|n| n.clone()),
|
name.as_ref().map(|n| n.clone()),
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
Command::new(&binary)
|
Command::new(&binary)
|
||||||
.arg(p.path())
|
.arg(p.path())
|
||||||
|
|
|
@ -448,6 +448,7 @@ impl Component for EnvelopeView {
|
||||||
&decode(u, None),
|
&decode(u, None),
|
||||||
name.as_ref().map(|n| n.clone()),
|
name.as_ref().map(|n| n.clone()),
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
Command::new(&binary)
|
Command::new(&binary)
|
||||||
.arg(p.path())
|
.arg(p.path())
|
||||||
|
|
|
@ -134,7 +134,7 @@ impl Component for HtmlView {
|
||||||
// scripts)
|
// scripts)
|
||||||
let binary = query_default_app("text/html");
|
let binary = query_default_app("text/html");
|
||||||
if let Ok(binary) = binary {
|
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)
|
Command::new(&binary)
|
||||||
.arg(p.path())
|
.arg(p.path())
|
||||||
.stdin(Stdio::piped())
|
.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 {
|
impl Index<FolderHash> for Account {
|
||||||
|
|
|
@ -29,12 +29,15 @@ use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
path: PathBuf,
|
pub path: PathBuf,
|
||||||
|
delete_on_drop: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for File {
|
impl Drop for File {
|
||||||
fn drop(&mut self) {
|
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.
|
/// 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 mut dir = std::env::temp_dir();
|
||||||
|
|
||||||
let path = if let Some(p) = path {
|
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.write_all(bytes).unwrap();
|
||||||
f.flush().unwrap();
|
f.flush().unwrap();
|
||||||
File { path: path.clone() }
|
File {
|
||||||
|
path: path.clone(),
|
||||||
|
delete_on_drop,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue