From 60494497332d5f16aae02873d351db6a049ec3c3 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 25 Jul 2018 19:05:42 +0300 Subject: [PATCH] Add attachment view for application/* mime concerns #2 left: multipart text and pgp. --- melib/src/mailbox/email/attachments.rs | 62 ++++++++++++++++++++++++-- ui/Cargo.toml | 1 + ui/src/components/mail/view.rs | 15 ++++++- ui/src/helpers.rs | 1 + ui/src/lib.rs | 1 + 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/melib/src/mailbox/email/attachments.rs b/melib/src/mailbox/email/attachments.rs index 8b57ada61..b890ee792 100644 --- a/melib/src/mailbox/email/attachments.rs +++ b/melib/src/mailbox/email/attachments.rs @@ -39,6 +39,28 @@ pub enum MultipartType { Digest, Unsupported { tag: String }, } + + +impl Display for MultipartType { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + match self { + MultipartType::Mixed => { + write!(f, "multipart/mixed") + }, + MultipartType::Alternative => { + write!(f, "multipart/alternative") + }, + MultipartType::Digest => { + write!(f, "multipart/digest") + }, + MultipartType::Unsupported { tag: ref t } => { + write!(f, "multipart/{}", t) + }, + } + } +} + + #[derive(Clone, Debug)] pub enum AttachmentType { Data { tag: String }, @@ -47,6 +69,31 @@ pub enum AttachmentType { of_type: MultipartType, subattachments: Vec, }, +} + + +impl Display for AttachmentType { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + match self { + AttachmentType::Data { tag: ref t } => { + write!(f, "{}", t) + }, + AttachmentType::Text { content: ref c } => { + write!(f, "{}", c) + }, + AttachmentType::Multipart { of_type: ref t, .. } => { + write!(f, "{}", t) + + }, + + + } + + + } + + + } #[derive(Clone, Debug)] pub enum ContentType { @@ -278,7 +325,7 @@ 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()) + write!(f, "Data attachment of type {}", self.mime_type()) } AttachmentType::Text { .. } => { write!(f, "Text attachment") @@ -303,7 +350,7 @@ 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.mime_type())); } AttachmentType::Text { content: ref t } => { text.push_str(t); @@ -334,7 +381,7 @@ impl Attachment { pub fn description(&self) -> Vec { self.attachments().iter().map(|a| a.text()).collect() } - pub fn tag(&self) -> String { + pub fn mime_type(&self) -> String { format!("{}/{}", self.content_type.0, self.content_type.1).to_string() } pub fn attachments(&self) -> Vec { @@ -364,6 +411,15 @@ impl Attachment { pub fn count_attachments(&self) -> usize { self.attachments().len() } + pub fn attachment_type(&self) -> &AttachmentType { + &self.attachment_type + } + pub fn content_type(&self) -> &(ContentType, ContentSubType) { + &self.content_type + } + pub fn content_transfer_encoding(&self) -> &ContentTransferEncoding { + &self.content_transfer_encoding + } } diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 92121e769..972fe4424 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -12,6 +12,7 @@ notify = "4.0.1" notify-rust = "^3" nom = "3.2.0" chan-signal = "0.3.1" +mime_apps = { path = "../../mime_apps", version = "*" } uuid = { version = "0.6", features = ["serde", "v4"] } linkify = "0.3.1" diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index 0015faa07..1b9e5401b 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -2,6 +2,8 @@ use super::*; use linkify::{LinkFinder, Link}; use std::process::{Command, Stdio}; +use mime_apps::query_default_app; + #[derive(PartialEq, Debug)] enum ViewMode { @@ -194,8 +196,17 @@ impl Component for MailView { let envelope: &Envelope = &mailbox.collection[envelope_idx]; if let Some(u) = envelope.body().attachments().get(lidx) { - let p = create_temp_file(&decode(u), None); - eprintln!("{:?}", p); + let mut p = create_temp_file(&decode(u), None); + let attachment_type = u.mime_type(); + eprintln!("attachment type {}", attachment_type); + let binary = query_default_app(attachment_type); + eprintln!("{:?}, binary = {:?}", p, binary); + Command::new(binary.unwrap()) + .arg(p.path()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to start xdg_open"); } else { context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::StatusNotification(format!("Attachment `{}` not found.", lidx)) }); diff --git a/ui/src/helpers.rs b/ui/src/helpers.rs index 83bb3fa9d..c79168554 100644 --- a/ui/src/helpers.rs +++ b/ui/src/helpers.rs @@ -20,6 +20,7 @@ impl File { } +//TODO: add temp files to a list to reap them when dropped pub fn create_temp_file(bytes: &[u8], filename: Option<&PathBuf>) -> File { let mut dir = std::env::temp_dir(); diff --git a/ui/src/lib.rs b/ui/src/lib.rs index a96f9f716..87c3e53a5 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -44,6 +44,7 @@ use self::cells::*; pub use self::components::*; extern crate melib; +extern crate mime_apps; extern crate notify_rust; #[macro_use] extern crate chan;