Print attachments of interest in the text body

Concerns #2
embed
Manos Pitsidianakis 2018-07-22 15:44:44 +03:00
parent bf0eb66b02
commit 7ed707a309
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 59 additions and 28 deletions

View File

@ -20,7 +20,7 @@
*/ */
use mailbox::email::parser; 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 { impl Display for ContentType {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> FmtResult {
match *self { match *self {
ContentType::Text => write!(f, "text"), ContentType::Text => write!(f, "text"),
ContentType::Multipart { .. } => write!(f, "multipart"), ContentType::Multipart { .. } => write!(f, "multipart"),
@ -67,7 +67,7 @@ pub enum ContentSubType {
Other { tag: String }, Other { tag: String },
} }
impl Display for ContentSubType { impl Display for ContentSubType {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> FmtResult {
match *self { match *self {
ContentSubType::Plain => write!(f, "plain"), ContentSubType::Plain => write!(f, "plain"),
ContentSubType::Other { tag: ref t } => write!(f, "{}", t), ContentSubType::Other { tag: ref t } => write!(f, "{}", t),
@ -271,11 +271,33 @@ pub struct Attachment {
attachment_type: AttachmentType, 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 { impl Attachment {
fn get_text_recursive(&self, text: &mut String) { fn get_text_recursive(&self, text: &mut String) {
match self.attachment_type { match self.attachment_type {
AttachmentType::Data { .. } => { 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 } => { AttachmentType::Text { content: ref t } => {
text.push_str(t); text.push_str(t);
@ -303,41 +325,44 @@ impl Attachment {
self.get_text_recursive(&mut text); self.get_text_recursive(&mut text);
text text
} }
pub fn description(&self) -> String { pub fn description(&self) -> Vec<String> {
unimplemented!() self.attachments().iter().map(|a| a.text()).collect()
} }
pub fn tag(&self) -> String { pub fn tag(&self) -> String {
format!("{}/{}", self.content_type.0, self.content_type.1).to_string() format!("{}/{}", self.content_type.0, self.content_type.1).to_string()
} }
pub fn count_attachments(&mut self) -> usize { pub fn attachments(&self) -> Vec<Attachment> {
let mut counter = 0; let mut ret = Vec::new();
fn count_recursive(att: &Attachment, ret: &mut Vec<Attachment>) {
fn count_recursive(att: &Attachment, counter: &mut usize) {
match att.attachment_type { match att.attachment_type {
AttachmentType::Data { .. } => { AttachmentType::Data { .. } | AttachmentType::Text { .. } => {
*counter += 1; ret.push(att.clone())
}
AttachmentType::Text { .. } => {
} }
AttachmentType::Multipart { AttachmentType::Multipart {
of_type: ref multipart_type, of_type: ref multipart_type,
subattachments: ref sub_att_vec, subattachments: ref sub_att_vec,
} => if *multipart_type != MultipartType::Alternative { } => if *multipart_type != MultipartType::Alternative {
// TODO: Fix this, wrong count
for a in sub_att_vec { for a in sub_att_vec {
count_recursive(a, counter); count_recursive(a, ret);
} }
}, },
} }
} }
count_recursive(&self, &mut counter); count_recursive(&self, &mut ret);
counter ret
}
pub fn count_attachments(&self) -> usize {
self.attachments().len()
} }
} }
pub fn interpret_format_flowed(t: &str) -> String { pub fn interpret_format_flowed(t: &str) -> String {
let mut n = String::with_capacity(t.len()); //let mut n = String::with_capacity(t.len());

View File

@ -20,11 +20,11 @@
*/ */
pub mod parser; pub mod parser;
mod attachments; pub mod attachments;
use mailbox::backends::BackendOpGenerator; use mailbox::backends::BackendOpGenerator;
use self::attachments::*; use self::attachments::*;
pub use self::attachments::interpret_format_flowed; pub use self::attachments::*;
use std::string::String; use std::string::String;
use std::sync::Arc; use std::sync::Arc;

View File

@ -322,8 +322,8 @@ impl MailListing {
s.push_str(&format!("{:.85}", envelope.subject())); s.push_str(&format!("{:.85}", envelope.subject()));
} }
let attach_count = envelope.body().count_attachments(); let attach_count = envelope.body().count_attachments();
if attach_count > 0 { if attach_count > 1 {
s.push_str(&format!(" {}", attach_count)); s.push_str(&format!(" {}", attach_count-1));
} }
s s
} }

View File

@ -3,6 +3,7 @@
use super::*; use super::*;
use melib::mailbox::email::interpret_format_flowed; use melib::mailbox::email::interpret_format_flowed;
use melib::mailbox::email::Attachment;
/// A horizontally split in half container. /// A horizontally split in half container.
pub struct HSplit { 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(); 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 mut text = text.to_string();
let height = lines.len(); 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 width = lines.iter().map(|l| l.len()).max().unwrap_or(0);
let mut content = CellBuffer::new(width, height, Cell::with_char(' ')); 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::print_string(&mut content, &text);
Pager { Pager {
cursor_pos: 0, cursor_pos: 0,
@ -203,6 +208,7 @@ impl Pager {
let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); let width = lines.iter().map(|l| l.len()).max().unwrap_or(0);
if width > 0 { if width > 0 {
for (i, l) in lines.iter().enumerate() { for (i, l) in lines.iter().enumerate() {
eprintln!("line: {:?}", l);
write_string_to_grid(l, write_string_to_grid(l,
content, content,
Color::Default, Color::Default,