From 954329d848a5b3e73fca50ed1db9859118bed6dd Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Tue, 30 May 2023 21:36:24 +0300 Subject: [PATCH] Set file extensions to temp files, use `open` in macos If html_filter fails, meli unwraps it. Also, if it can't find an xdg default app it also fails. So use xdg-open and open as failsaifes. But that requires `open` to know it's an html file, so implemented setting temp file extensions as well. --- src/components/mail/compose.rs | 5 +++-- src/components/mail/view.rs | 19 +++++++------------ src/components/mail/view/envelope.rs | 1 + src/components/mail/view/html.rs | 9 ++++++++- src/conf/accounts.rs | 5 +++-- src/mailcap.rs | 9 +++++++-- src/types/helpers.rs | 10 +++++++--- 7 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/components/mail/compose.rs b/src/components/mail/compose.rs index 3fd14e97..f5cca6b4 100644 --- a/src/components/mail/compose.rs +++ b/src/components/mail/compose.rs @@ -1774,6 +1774,7 @@ impl Component for Composer { self.draft.to_edit_string().as_str().as_bytes(), None, None, + Some("eml"), true, ); @@ -1867,7 +1868,7 @@ impl Component for Composer { )); return false; } - let f = create_temp_file(&[], None, None, true); + let f = create_temp_file(&[], None, None, None, true); match Command::new("sh") .args(["-c", command]) .stdin(Stdio::null()) @@ -2409,7 +2410,7 @@ pub fn send_draft_async( )))) .unwrap(); } else if !store_sent_mail && is_ok { - let f = create_temp_file(message.as_bytes(), None, None, false); + let f = create_temp_file(message.as_bytes(), None, None, Some("eml"), false); log::info!( "store_sent_mail is false; stored sent mail to {}", f.path().display() diff --git a/src/components/mail/view.rs b/src/components/mail/view.rs index 77b022b0..78e94a63 100644 --- a/src/components/mail/view.rs +++ b/src/components/mail/view.rs @@ -796,7 +796,11 @@ impl MailView { .args(["-c", filter_invocation]) .stdin(Stdio::piped()) .stdout(Stdio::piped()) - .spawn(); + .spawn() + .and_then(|mut cmd| { + cmd.stdin.as_mut().unwrap().write_all(&bytes)?; + Ok(String::from_utf8_lossy(&cmd.wait_with_output()?.stdout).to_string()) + }); match command_obj { Err(err) => { context.replies.push_back(UIEvent::Notification( @@ -819,21 +823,11 @@ impl MailView { text, }); } - Ok(mut html_filter) => { - html_filter - .stdin - .as_mut() - .unwrap() - .write_all(&bytes) - .expect("Failed to write to stdin"); + Ok(text) => { let comment = Some(format!( "Text piped through `{}`. Press `v` to open in web browser. \n\n", filter_invocation )); - let text = String::from_utf8_lossy( - &html_filter.wait_with_output().unwrap().stdout, - ) - .to_string(); acc.push(AttachmentDisplay::InlineText { inner: Box::new(a.clone()), comment, @@ -2306,6 +2300,7 @@ impl Component for MailView { &attachment.decode(Default::default()), filename.as_deref(), None, + None, true, ); let exec_cmd = desktop_exec_to_command( diff --git a/src/components/mail/view/envelope.rs b/src/components/mail/view/envelope.rs index d37dd32a..061a6c9c 100644 --- a/src/components/mail/view/envelope.rs +++ b/src/components/mail/view/envelope.rs @@ -443,6 +443,7 @@ impl Component for EnvelopeView { &u.decode(Default::default()), filename.as_deref(), None, + None, true, ); let exec_cmd = super::desktop_exec_to_command( diff --git a/src/components/mail/view/html.rs b/src/components/mail/view/html.rs index b319ee8c..dfea704d 100644 --- a/src/components/mail/view/html.rs +++ b/src/components/mail/view/html.rs @@ -152,8 +152,15 @@ impl Component for HtmlView { } else { query_default_app("text/html").ok() }; + let command = if cfg!(target_os = "macos") { + command.or_else(|| Some("open".into())) + } else if cfg!(target_os = "linux") { + command.or_else(|| Some("xdg-open".into())) + } else { + command + }; if let Some(command) = command { - let p = create_temp_file(&self.bytes, None, None, true); + let p = create_temp_file(&self.bytes, None, None, Some("html"), true); let exec_cmd = super::desktop_exec_to_command(&command, p.path.display().to_string(), false); match Command::new("sh") diff --git a/src/conf/accounts.rs b/src/conf/accounts.rs index b120df92..27802575 100644 --- a/src/conf/accounts.rs +++ b/src/conf/accounts.rs @@ -1231,7 +1231,7 @@ impl Account { if let Some(mailbox_hash) = saved_at { Ok(mailbox_hash) } else { - let file = crate::types::create_temp_file(bytes, None, None, false); + let file = crate::types::create_temp_file(bytes, None, None, Some("eml"), false); debug!("message saved in {}", file.path.display()); log::info!( "Message was stored in {} so that you can restore it manually.", @@ -1873,7 +1873,8 @@ impl Account { } => { if let Ok(Some(Err(err))) = handle.chan.try_recv() { log::error!("Could not save message: {err}"); - let file = crate::types::create_temp_file(bytes, None, None, false); + let file = + crate::types::create_temp_file(bytes, None, None, Some("eml"), false); log::debug!("message saved in {}", file.path.display()); log::info!( "Message was stored in {} so that you can restore it manually.", diff --git a/src/mailcap.rs b/src/mailcap.rs index 31955128..27c52718 100644 --- a/src/mailcap.rs +++ b/src/mailcap.rs @@ -165,8 +165,13 @@ impl MailcapEntry { .map(|arg| match *arg { "%s" => { needs_stdin = false; - let _f = - create_temp_file(&a.decode(Default::default()), None, None, true); + let _f = create_temp_file( + &a.decode(Default::default()), + None, + None, + None, + true, + ); let p = _f.path().display().to_string(); f = Some(_f); p diff --git a/src/types/helpers.rs b/src/types/helpers.rs index 1d411dff..2775f0a8 100644 --- a/src/types/helpers.rs +++ b/src/types/helpers.rs @@ -72,7 +72,8 @@ impl File { pub fn create_temp_file( bytes: &[u8], filename: Option<&str>, - path: Option<&PathBuf>, + path: Option<&mut PathBuf>, + extension: Option<&str>, delete_on_drop: bool, ) -> File { let mut dir = std::env::temp_dir(); @@ -89,10 +90,13 @@ pub fn create_temp_file( let u = Uuid::new_v4(); dir.push(u.as_hyphenated().to_string()); } - &dir + &mut dir }); + if let Some(ext) = extension { + path.set_extension(ext); + } - let mut f = std::fs::File::create(path).unwrap(); + let mut f = std::fs::File::create(&path).unwrap(); let metadata = f.metadata().unwrap(); let mut permissions = metadata.permissions();