From 7ed707a3099720254115b6da36e7dae2e63730f0 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 22 Jul 2018 15:44:44 +0300 Subject: [PATCH] Print attachments of interest in the text body Concerns #2 --- melib/src/mailbox/email/attachments.rs | 61 ++++++++++++++++++-------- melib/src/mailbox/email/mod.rs | 6 +-- ui/src/components/mail/listing.rs | 4 +- ui/src/components/utilities.rs | 16 ++++--- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/melib/src/mailbox/email/attachments.rs b/melib/src/mailbox/email/attachments.rs index bfa0df48e..2830240d4 100644 --- a/melib/src/mailbox/email/attachments.rs +++ b/melib/src/mailbox/email/attachments.rs @@ -20,7 +20,7 @@ */ use mailbox::email::parser; -use std::fmt::{Display, Formatter, Result}; +use std::fmt::{Display, Formatter, Result as FmtResult}; /* * @@ -53,7 +53,7 @@ pub enum ContentType { } impl Display for ContentType { - fn fmt(&self, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match *self { ContentType::Text => write!(f, "text"), ContentType::Multipart { .. } => write!(f, "multipart"), @@ -67,7 +67,7 @@ pub enum ContentSubType { Other { tag: String }, } impl Display for ContentSubType { - fn fmt(&self, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match *self { ContentSubType::Plain => write!(f, "plain"), ContentSubType::Other { tag: ref t } => write!(f, "{}", t), @@ -271,11 +271,33 @@ pub struct Attachment { attachment_type: AttachmentType, } +impl Display for Attachment { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + match self.attachment_type { + AttachmentType::Data { .. } => { + write!(f, "Data attachment of type {}", self.tag()) + } + AttachmentType::Text { content: ref t } => { + write!(f, "Text attachment") + } + AttachmentType::Multipart { + of_type: ref multipart_type, + subattachments: ref sub_att_vec, + } => if *multipart_type == MultipartType::Alternative { + write!(f, "Multipart/alternative attachment with {} subs", sub_att_vec.len()) + } else { + write!(f, "Multipart attachment with {} subs", sub_att_vec.len()) + }, + } + + } +} + impl Attachment { fn get_text_recursive(&self, text: &mut String) { match self.attachment_type { AttachmentType::Data { .. } => { - text.push_str(&format!("Data attachment of type {}", self.tag())); + //text.push_str(&format!("Data attachment of type {}", self.tag())); } AttachmentType::Text { content: ref t } => { text.push_str(t); @@ -303,41 +325,44 @@ impl Attachment { self.get_text_recursive(&mut text); text } - pub fn description(&self) -> String { - unimplemented!() + pub fn description(&self) -> Vec { + self.attachments().iter().map(|a| a.text()).collect() } pub fn tag(&self) -> String { format!("{}/{}", self.content_type.0, self.content_type.1).to_string() } - pub fn count_attachments(&mut self) -> usize { - let mut counter = 0; - - fn count_recursive(att: &Attachment, counter: &mut usize) { + pub fn attachments(&self) -> Vec { + let mut ret = Vec::new(); + fn count_recursive(att: &Attachment, ret: &mut Vec) { match att.attachment_type { - AttachmentType::Data { .. } => { - *counter += 1; - } - AttachmentType::Text { .. } => { + AttachmentType::Data { .. } | AttachmentType::Text { .. } => { + ret.push(att.clone()) } AttachmentType::Multipart { of_type: ref multipart_type, subattachments: ref sub_att_vec, } => if *multipart_type != MultipartType::Alternative { + // TODO: Fix this, wrong count for a in sub_att_vec { - count_recursive(a, counter); + count_recursive(a, ret); } }, } } - count_recursive(&self, &mut counter); - counter + count_recursive(&self, &mut ret); + ret + + + } + pub fn count_attachments(&self) -> usize { + self.attachments().len() } } pub fn interpret_format_flowed(t: &str) -> String { - let mut n = String::with_capacity(t.len()); + //let mut n = String::with_capacity(t.len()); diff --git a/melib/src/mailbox/email/mod.rs b/melib/src/mailbox/email/mod.rs index da7039163..8bb770701 100644 --- a/melib/src/mailbox/email/mod.rs +++ b/melib/src/mailbox/email/mod.rs @@ -20,11 +20,11 @@ */ pub mod parser; -mod attachments; +pub mod attachments; use mailbox::backends::BackendOpGenerator; use self::attachments::*; -pub use self::attachments::interpret_format_flowed; +pub use self::attachments::*; use std::string::String; use std::sync::Arc; @@ -414,7 +414,7 @@ impl Envelope { }); } } - } + } pub fn references(&self) -> Vec<&MessageID> { match self.references { Some(ref s) => s.refs diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index 9f63cb09e..91813f4af 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -322,8 +322,8 @@ impl MailListing { s.push_str(&format!("{:.85}", envelope.subject())); } let attach_count = envelope.body().count_attachments(); - if attach_count > 0 { - s.push_str(&format!(" {}∞ ", attach_count)); + if attach_count > 1 { + s.push_str(&format!(" {}∞ ", attach_count-1)); } s } diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index cfa24c6f5..12bea00d4 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -3,6 +3,7 @@ use super::*; use melib::mailbox::email::interpret_format_flowed; +use melib::mailbox::email::Attachment; /// A horizontally split in half container. pub struct HSplit { @@ -168,13 +169,17 @@ impl Pager { text = String::from_utf8_lossy(&filter_child.wait_with_output().expect("Failed to wait on filter").stdout).to_string(); } - let lines: Vec<&str> = text.trim().split('\n').collect(); - let height = lines.len(); + let mut text = text.to_string(); + if envelope.body().count_attachments() > 1 { + eprintln!("text was {}", text); + text = envelope.body().attachments().iter().fold(text, |mut s, a| { s.push_str(&format!("{}\n", a)); s }); + eprintln!("text is {}", text); + } + let mut lines: Vec<&str> = text.trim().split('\n').collect(); + let height = lines.len() + 1; let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); let mut content = CellBuffer::new(width, height, Cell::with_char(' ')); - if false { - interpret_format_flowed(&text); - } + //interpret_format_flowed(&text); Pager::print_string(&mut content, &text); Pager { cursor_pos: 0, @@ -203,6 +208,7 @@ impl Pager { let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); if width > 0 { for (i, l) in lines.iter().enumerate() { + eprintln!("line: {:?}", l); write_string_to_grid(l, content, Color::Default,