diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2018-08-08 19:06:00 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-06-10 19:40:27 +0300 |
commit | 14d65838b7938a24e85a13396991f10730984573 (patch) | |
tree | 4a3452185464ea3fb0e82a57cd901da0086d2187 /ui | |
parent | 93b36a99412f91344dc8767c7317386fcc9eaaaf (diff) |
Fix proper viewing for multipart alternatives, html view and quoted printable soft breaks
Diffstat (limited to 'ui')
-rw-r--r-- | ui/src/components/mail/view.rs | 124 | ||||
-rw-r--r-- | ui/src/execute/actions.rs | 13 | ||||
-rw-r--r-- | ui/src/state.rs | 6 | ||||
-rw-r--r-- | ui/src/types/helpers.rs | 4 |
4 files changed, 77 insertions, 70 deletions
diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index 0a723afb..71018a6f 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -70,6 +70,78 @@ impl MailView { cmd_buf: String::with_capacity(4), } } + + /// Returns the string to be displayed in the Viewer + fn attachment_to_text(&self, envelope: &Envelope) -> String { + let finder = LinkFinder::new(); + let body = envelope.body(); + let body_text = if body.content_type().0.is_text() && body.content_type().1.is_html() { + String::from_utf8_lossy(&decode(&body, Some(Box::new(|a: &Attachment| { + use std::io::Write; + use std::process::{Command, Stdio}; + + let raw = decode(a, None); + 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(&raw).expect("Failed to write to w3m stdin"); + html_filter.wait_with_output().unwrap().stdout + })))).into_owned() + } else { + String::from_utf8_lossy(&decode_rec(&body, None)).into() + }; + match self.mode { + ViewMode::Normal => { + let mut t = body_text.to_string(); + if body.count_attachments() > 1 { + t = body.attachments().iter().enumerate().fold( + t, + |mut s, (idx, a)| { + s.push_str(&format!("[{}] {}\n\n", idx, a)); + s + }, + ); + } + t + } + ViewMode::Raw => String::from_utf8_lossy(&envelope.bytes()).into_owned(), + ViewMode::Url => { + let mut t = body_text.to_string(); + for (lidx, l) in finder.links(&body.text()).enumerate() { + let offset = if lidx < 10 { + lidx * 3 + } else if lidx < 100 { + 26 + (lidx - 9) * 4 + } else if lidx < 1000 { + 385 + (lidx - 99) * 5 + } else { + panic!("BUG: Message body with more than 100 urls"); + }; + t.insert_str(l.start() + offset, &format!("[{}]", lidx)); + } + if body.count_attachments() > 1 { + t = body.attachments().iter().enumerate().fold( + t, + |mut s, (idx, a)| { + s.push_str(&format!("[{}] {}\n\n", idx, a)); + s + }, + ); + } + t + } + ViewMode::Attachment(aidx) => { + let attachments = body.attachments(); + let mut ret = "Viewing attachment. Press `r` to return \n".to_string(); + ret.push_str(&attachments[aidx].text()); + ret + } + } + } } impl Component for MailView { @@ -177,61 +249,15 @@ impl Component for MailView { .as_ref() .unwrap(); let envelope: &Envelope = &mailbox.collection[envelope_idx]; + let text = self.attachment_to_text(envelope); - let finder = LinkFinder::new(); - let mut text = match self.mode { - ViewMode::Normal => { - let mut t = envelope.body().text().to_string(); - if envelope.body().count_attachments() > 1 { - t = envelope.body().attachments().iter().enumerate().fold( - t, - |mut s, (idx, a)| { - s.push_str(&format!("[{}] {}\n\n", idx, a)); - s - }, - ); - } - t - } - ViewMode::Raw => String::from_utf8_lossy(&envelope.bytes()).into_owned(), - ViewMode::Url => { - let mut t = envelope.body().text().to_string(); - for (lidx, l) in finder.links(&envelope.body().text()).enumerate() { - let offset = if lidx < 10 { - lidx * 3 - } else if lidx < 100 { - 26 + (lidx - 9) * 4 - } else if lidx < 1000 { - 385 + (lidx - 99) * 5 - } else { - panic!("BUG: Message body with more than 100 urls"); - }; - t.insert_str(l.start() + offset, &format!("[{}]", lidx)); - } - if envelope.body().count_attachments() > 1 { - t = envelope.body().attachments().iter().enumerate().fold( - t, - |mut s, (idx, a)| { - s.push_str(&format!("[{}] {}\n\n", idx, a)); - s - }, - ); - } - t - } - ViewMode::Attachment(aidx) => { - let attachments = envelope.body().attachments(); - let mut ret = "Viewing attachment. Press `r` to return \n".to_string(); - ret.push_str(&attachments[aidx].text()); - ret - } - }; let mut buf = CellBuffer::from(&text); if self.mode == ViewMode::Url { // URL indexes must be colored (ugh..) let lines: Vec<&str> = text.split('\n').map(|l| l.trim_right()).collect(); let mut shift = 0; let mut lidx_total = 0; + let finder = LinkFinder::new(); for r in &lines { for l in finder.links(&r) { let offset = if lidx_total < 10 { @@ -331,7 +357,7 @@ impl Component for MailView { let attachment_type = u.mime_type(); let binary = query_default_app(&attachment_type); if let Ok(binary) = binary { - let mut p = create_temp_file(&decode(u), None); + let mut p = create_temp_file(&decode(u, None), None); Command::new(&binary) .arg(p.path()) .stdin(Stdio::piped()) diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index 105fa532..021473ae 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -45,18 +45,6 @@ pub enum SortField { impl FromStr for SortField { type Err = (); fn from_str(s: &str) -> Result<Self, Self::Err> { - eprintln!("sortfield from_str {}", s); - match s.trim() { - "subject" | "s" | "sub" | "sbj" | "subj" => { - eprintln!("parsed: subject"); - } - "date" | "d" => { - eprintln!("parsed date"); - } - _ => { - eprintln!("error in parse"); - } - } match s.trim() { "subject" | "s" | "sub" | "sbj" | "subj" => Ok(SortField::Subject), "date" | "d" => Ok(SortField::Date), @@ -68,7 +56,6 @@ impl FromStr for SortField { impl FromStr for SortOrder { type Err = (); fn from_str(s: &str) -> Result<Self, Self::Err> { - eprintln!("sortoder from_str {}", s); match s.trim() { "asc" => Ok(SortOrder::Asc), "desc" => Ok(SortOrder::Desc), diff --git a/ui/src/state.rs b/ui/src/state.rs index c41c9549..520a97c3 100644 --- a/ui/src/state.rs +++ b/ui/src/state.rs @@ -184,10 +184,6 @@ impl State<std::io::Stdout> { sender.send(ThreadEvent::from(r)); }))); } - for (k, v) in &s.context.mailbox_hashes { - eprintln!("{:x} -> {:?}", k, v); - - } s } pub fn hash_to_folder(&self, hash: u64) { @@ -348,9 +344,7 @@ impl<W: Write> State<W> { } /// Convert user commands to actions/method calls. fn parse_command(&mut self, cmd: &str) { - eprintln!("cmd is {}", cmd); let result = parse_command(&cmd.as_bytes()).to_full_result(); - eprintln!("rseult is {:?}", result); if let Ok(v) = result { self.rcv_event(UIEvent { diff --git a/ui/src/types/helpers.rs b/ui/src/types/helpers.rs index ab083055..d28027c0 100644 --- a/ui/src/types/helpers.rs +++ b/ui/src/types/helpers.rs @@ -40,8 +40,8 @@ impl File { pub fn file(&mut self) -> std::fs::File { std::fs::File::create(&self.path).unwrap() } - pub fn path(&mut self) -> &mut PathBuf { - &mut self.path + pub fn path(&self) -> &PathBuf { + &self.path } } |