summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2018-08-08 19:06:00 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-06-10 19:40:27 +0300
commit14d65838b7938a24e85a13396991f10730984573 (patch)
tree4a3452185464ea3fb0e82a57cd901da0086d2187 /ui
parent93b36a99412f91344dc8767c7317386fcc9eaaaf (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.rs124
-rw-r--r--ui/src/execute/actions.rs13
-rw-r--r--ui/src/state.rs6
-rw-r--r--ui/src/types/helpers.rs4
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
}
}