diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-04-06 00:30:06 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-06-10 19:40:43 +0300 |
commit | cfb7dcec645cd02b437f9f46e70ce7f7750a7fd3 (patch) | |
tree | 2339f744b37e62502810ceb979b0e47d4ef6fd97 /ui/src/components | |
parent | 92f42ad8faebf8d07b73d3a5b14ceac6b651dc95 (diff) |
ui: make html filter optional in config
closes #92
Diffstat (limited to 'ui/src/components')
-rw-r--r-- | ui/src/components/mail/view.rs | 106 | ||||
-rw-r--r-- | ui/src/components/mail/view/envelope.rs | 77 | ||||
-rw-r--r-- | ui/src/components/mail/view/html.rs | 107 |
3 files changed, 209 insertions, 81 deletions
diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index d2549330..b73056fb 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -116,31 +116,52 @@ impl MailView { } /// Returns the string to be displayed in the Viewer - fn attachment_to_text(&self, body: &Attachment) -> String { + fn attachment_to_text<'closure, 's: 'closure, 'context: 's>( + &'s self, + body: &'context Attachment, + context: &'context mut Context, + ) -> String { let finder = LinkFinder::new(); let body_text = String::from_utf8_lossy(&decode_rec( - &body, - Some(Box::new(|a: &Attachment, v: &mut Vec<u8>| { + body, + Some(Box::new(move |a: &'closure Attachment, v: &mut Vec<u8>| { if a.content_type().is_text_html() { use std::io::Write; use std::process::{Command, Stdio}; + let settings = context.accounts[self.coordinates.0].runtime_settings.conf(); + if let Some(filter_invocation) = settings.html_filter() { + let parts = split_command!(filter_invocation); + let (cmd, args) = (parts[0], &parts[1..]); + let command_obj = Command::new(cmd) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn(); + if command_obj.is_err() { + context.replies.push_back(UIEvent { + id: 0, + event_type: UIEventType::Notification( + Some(format!( + "Failed to start html filter process: {}", + filter_invocation, + )), + String::new(), + ), + }); + return; + } - let mut html_filter = Command::new("w3m") - .args(&["-I", "utf-8", "-T", "text/html"]) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("Failed to start html filter process"); - - html_filter - .stdin - .as_mut() - .unwrap() - .write_all(&v) - .expect("Failed to write to w3m stdin"); - *v = b"Text piped through `w3m`. Press `v` to open in web browser. \n\n" - .to_vec(); - v.extend(html_filter.wait_with_output().unwrap().stdout); + let mut html_filter = command_obj.unwrap(); + html_filter + .stdin + .as_mut() + .unwrap() + .write_all(&v) + .expect("Failed to write to stdin"); + *v = format!("Text piped through `{}`. Press `v` to open in web browser. \n\n", + filter_invocation).into_bytes(); + v.extend(html_filter.wait_with_output().unwrap().stdout); + } } })), )) @@ -326,35 +347,42 @@ impl Component for MailView { }; if self.dirty { - let mailbox_idx = self.coordinates; // coordinates are mailbox idxs - let mailbox = &context.accounts[mailbox_idx.0][mailbox_idx.1] - .as_ref() - .unwrap(); - let envelope: &Envelope = &mailbox.collection[&mailbox_idx.2]; - let op = context.accounts[mailbox_idx.0] - .backend - .operation(envelope.hash(), mailbox.folder.hash()); - let body = envelope.body(op); + let body = { + let mailbox_idx = self.coordinates; // coordinates are mailbox idxs + let mailbox = &context.accounts[mailbox_idx.0][mailbox_idx.1] + .as_ref() + .unwrap(); + let envelope: &Envelope = &mailbox.collection[&mailbox_idx.2]; + let op = context.accounts[mailbox_idx.0] + .backend + .operation(envelope.hash(), mailbox.folder.hash()); + envelope.body(op) + }; match self.mode { ViewMode::Attachment(aidx) if body.attachments()[aidx].is_html() => { self.pager = None; - self.subview = Some(Box::new(HtmlView::new(decode( - &body.attachments()[aidx], - None, - )))); + let attachment = &body.attachments()[aidx]; + self.subview = Some(Box::new(HtmlView::new( + decode(&attachment, None), + context, + self.coordinates.0, + ))); self.mode = ViewMode::Subview; } ViewMode::Normal if body.is_html() => { - self.subview = Some(Box::new(HtmlView::new(decode(&body, None)))); + self.subview = Some(Box::new(HtmlView::new( + decode(&body, None), + context, + self.coordinates.0, + ))); self.pager = None; self.mode = ViewMode::Subview; } ViewMode::Subview | ViewMode::ContactSelector(_) => {} _ => { let text = { - self.attachment_to_text(&body) + self.attachment_to_text(&body, context) /* - let text = self.attachment_to_text(&body); // URL indexes must be colored (ugh..) MailView::plain_text_to_buf(&text, self.mode == ViewMode::Url) */ @@ -530,8 +558,12 @@ impl Component for MailView { self.mode = ViewMode::Subview; match EnvelopeWrapper::new(u.bytes().to_vec()) { Ok(wrapper) => { - self.subview = - Some(Box::new(EnvelopeView::new(wrapper, None, None))); + self.subview = Some(Box::new(EnvelopeView::new( + wrapper, + None, + None, + self.coordinates.0, + ))); } Err(e) => { context.replies.push_back(UIEvent { diff --git a/ui/src/components/mail/view/envelope.rs b/ui/src/components/mail/view/envelope.rs index 9f028195..5c490579 100644 --- a/ui/src/components/mail/view/envelope.rs +++ b/ui/src/components/mail/view/envelope.rs @@ -53,6 +53,7 @@ pub struct EnvelopeView { mode: ViewMode, wrapper: EnvelopeWrapper, + account_pos: usize, cmd_buf: String, } @@ -68,6 +69,7 @@ impl EnvelopeView { wrapper: EnvelopeWrapper, pager: Option<Pager>, subview: Option<Box<Component>>, + account_pos: usize, ) -> Self { EnvelopeView { pager, @@ -75,13 +77,17 @@ impl EnvelopeView { dirty: true, mode: ViewMode::Normal, wrapper, - + account_pos, cmd_buf: String::with_capacity(4), } } /// Returns the string to be displayed in the Viewer - fn attachment_to_text(&self, body: &Attachment) -> String { + fn attachment_to_text<'closure, 's: 'closure, 'context: 's>( + &'s self, + body: &'context Attachment, + context: &'context mut Context, + ) -> String { let finder = LinkFinder::new(); let body_text = String::from_utf8_lossy(&decode_rec( &body, @@ -89,23 +95,40 @@ impl EnvelopeView { if a.content_type().is_text_html() { use std::io::Write; use std::process::{Command, Stdio}; + let settings = context.accounts[self.account_pos].runtime_settings.conf(); + if let Some(filter_invocation) = settings.html_filter() { + let parts = split_command!(filter_invocation); + let (cmd, args) = (parts[0], &parts[1..]); + let command_obj = Command::new(cmd) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn(); + if command_obj.is_err() { + context.replies.push_back(UIEvent { + id: 0, + event_type: UIEventType::Notification( + Some(format!( + "Failed to start html filter process: {}", + filter_invocation, + )), + String::new(), + ), + }); + return; + } - let mut html_filter = Command::new("w3m") - .args(&["-I", "utf-8", "-T", "text/html"]) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("Failed to start html filter process"); - - html_filter - .stdin - .as_mut() - .unwrap() - .write_all(&v) - .expect("Failed to write to w3m stdin"); - *v = b"Text piped through `w3m`. Press `v` to open in web browser. \n\n" - .to_vec(); - v.extend(html_filter.wait_with_output().unwrap().stdout); + let mut html_filter = command_obj.unwrap(); + html_filter + .stdin + .as_mut() + .unwrap() + .write_all(&v) + .expect("Failed to write to stdin"); + *v = format!("Text piped through `{}`. Press `v` to open in web browser. \n\n", + filter_invocation).into_bytes(); + v.extend(html_filter.wait_with_output().unwrap().stdout); + } } })), )) @@ -288,18 +311,24 @@ impl Component for EnvelopeView { let body = self.wrapper.body_bytes(self.wrapper.buffer()); match self.mode { ViewMode::Attachment(aidx) if body.attachments()[aidx].is_html() => { - self.subview = Some(Box::new(HtmlView::new(decode( - &body.attachments()[aidx], - None, - )))); + let attachment = &body.attachments()[aidx]; + self.subview = Some(Box::new(HtmlView::new( + decode(&attachment, None), + context, + self.account_pos, + ))); } ViewMode::Normal if body.is_html() => { - self.subview = Some(Box::new(HtmlView::new(decode(&body, None)))); + self.subview = Some(Box::new(HtmlView::new( + decode(&body, None), + context, + self.account_pos, + ))); self.mode = ViewMode::Subview; } _ => { let text = { - self.attachment_to_text(&body) + self.attachment_to_text(&body, context) /* let text = self.attachment_to_text(&body); // URL indexes must be colored (ugh..) diff --git a/ui/src/components/mail/view/html.rs b/ui/src/components/mail/view/html.rs index 4eb4f2bc..b4ca9f55 100644 --- a/ui/src/components/mail/view/html.rs +++ b/ui/src/components/mail/view/html.rs @@ -30,27 +30,94 @@ pub struct HtmlView { } impl HtmlView { - pub fn new(bytes: Vec<u8>) -> Self { - let mut html_filter = Command::new("w3m") - .args(&["-I", "utf-8", "-T", "text/html"]) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("Failed to start html filter process"); - html_filter - .stdin - .as_mut() - .unwrap() - .write_all(&bytes) - .expect("Failed to write to w3m stdin"); - let mut display_text = - String::from("Text piped through `w3m`. Press `v` to open in web browser. \n\n"); - display_text.push_str(&String::from_utf8_lossy( - &html_filter.wait_with_output().unwrap().stdout, - )); + pub fn new(bytes: Vec<u8>, context: &mut Context, account_pos: usize) -> Self { + let settings = context.accounts[account_pos].runtime_settings.conf(); + if let Some(filter_invocation) = settings.html_filter() { + let parts = split_command!(filter_invocation); + let (cmd, args) = (parts[0], &parts[1..]); + let command_obj = Command::new(cmd) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn(); + if command_obj.is_err() { + context.replies.push_back(UIEvent { + id: 0, + event_type: UIEventType::Notification( + Some(format!( + "Failed to start html filter process: {}", + filter_invocation + )), + String::new(), + ), + }); + let pager = Pager::from_string( + String::from_utf8_lossy(&bytes).to_string(), + None, + None, + None, + ); + HtmlView { pager, bytes } + } else { + let mut html_filter = command_obj.unwrap(); + html_filter + .stdin + .as_mut() + .unwrap() + .write_all(&bytes) + .expect("Failed to write to html filter stdin"); + let mut display_text = format!( + "Text piped through `{}`. Press `v` to open in web browser. \n\n", + filter_invocation + ); + display_text.push_str(&String::from_utf8_lossy( + &html_filter.wait_with_output().unwrap().stdout, + )); + + let pager = Pager::from_string(display_text, None, None, None); + HtmlView { pager, bytes } + } + } else { + if let Ok(mut html_filter) = Command::new("w3m") + .args(&["-I", "utf-8", "-T", "text/html"]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + { + html_filter + .stdin + .as_mut() + .unwrap() + .write_all(&bytes) + .expect("Failed to write to html filter stdin"); + let mut display_text = String::from( + "Text piped through `w3m`. Press `v` to open in web browser. \n\n", + ); + display_text.push_str(&String::from_utf8_lossy( + &html_filter.wait_with_output().unwrap().stdout, + )); - let pager = Pager::from_string(display_text, None, None, None); - HtmlView { pager, bytes } + let pager = Pager::from_string(display_text, None, None, None); + HtmlView { pager, bytes } + } else { + context.replies.push_back(UIEvent { + id: 0, + event_type: UIEventType::Notification( + Some(format!( + "Failed to find any application to use as html filter" + )), + String::new(), + ), + }); + let pager = Pager::from_string( + String::from_utf8_lossy(&bytes).to_string(), + None, + None, + None, + ); + HtmlView { pager, bytes } + } + } } } |