diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 72ec77e1..92121e76 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -13,4 +13,5 @@ notify-rust = "^3" nom = "3.2.0" chan-signal = "0.3.1" +uuid = { version = "0.6", features = ["serde", "v4"] } linkify = "0.3.1" diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index 205db111..9046c720 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -430,29 +430,23 @@ impl Component for MailListing { let tx = context.input_thread(); tx.send(true); } - let mut dir = std::env::temp_dir(); - dir.push("meli"); - std::fs::DirBuilder::new().recursive(true).create(&dir).unwrap(); - dir.push("foo.txt"); - let mut f = Box::new(std::fs::File::create(&dir).unwrap()); - f.write(&new_draft(context)); - f.flush(); - + let mut f = create_temp_file(&new_draft(context), None); + //let mut f = Box::new(std::fs::File::create(&dir).unwrap()); // TODO: check exit status let mut output = Command::new("vim") .arg("+/^$") - .arg(&dir) + .arg(&f.path()) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .spawn() - .expect("failed to execute process") ; + .expect("failed to execute process"); /* * Main loop will wait on children and when they reap them the loop spawns a new * input-thread */ - context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::Fork(ForkType::NewDraft(dir,output)) }); + context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::Fork(ForkType::NewDraft(f, output)) }); context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::ChangeMode(UIMode::Fork) }); return; }, diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index f0d47c87..2d601003 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -177,11 +177,33 @@ impl Component for MailView { } }, UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => { //TODO:this should be an Action - match self.mode { - ViewMode::Url => { self.cmd_buf.push(c); - return; }, - _ => {}, - } + self.cmd_buf.push(c); + }, + UIEventType::Input(Key::Char('a')) if self.cmd_buf.len() > 0 && self.mode == ViewMode::Normal => { //TODO:this should be an Action + let lidx = self.cmd_buf.parse::().unwrap(); + self.cmd_buf.clear(); + + + let url = { + let threaded = context.accounts[self.coordinates.0].runtime_settings.threaded; + let mailbox = &mut context.accounts[self.coordinates.0][self.coordinates.1].as_ref().unwrap().as_ref().unwrap(); + let envelope_idx: usize = if threaded { + mailbox.threaded_mail(self.coordinates.2) + } else { + self.coordinates.2 + }; + + let envelope: &Envelope = &mailbox.collection[envelope_idx]; + if let Some(u) = envelope.body().attachments().get(lidx) { + eprintln!("{:?}", u); + + } else { + context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::StatusNotification(format!("Attachment `{}` not found.", lidx)) }); + return; + } + }; + + }, UIEventType::Input(Key::Char('g')) if self.cmd_buf.len() > 0 && self.mode == ViewMode::Url => { //TODO:this should be an Action diff --git a/ui/src/helpers.rs b/ui/src/helpers.rs new file mode 100644 index 00000000..a276178c --- /dev/null +++ b/ui/src/helpers.rs @@ -0,0 +1,46 @@ +use std; +use std::path::PathBuf; +use std::io::Write; +use std::ops::{Deref, DerefMut}; + + +use std::fs; +use uuid::Uuid; + +#[derive(Debug)] +pub struct File { + path: PathBuf, +} + + +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 create_temp_file(bytes: &[u8], filename: Option<&PathBuf>) -> File { + let mut dir = std::env::temp_dir(); + + let path = if let Some(p) = filename { + p + } else { + dir.push("meli"); + std::fs::DirBuilder::new().recursive(true).create(&dir).unwrap(); + let u = Uuid::new_v4(); + dir.push(u.hyphenated().to_string()); + &dir + }; + + let mut f = std::fs::File::create(path).unwrap(); + f.write(bytes).unwrap(); + f.flush().unwrap(); + File { + path: path.clone(), + } +} + diff --git a/ui/src/lib.rs b/ui/src/lib.rs index cb76078f..f470fc67 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -33,6 +33,9 @@ mod position; mod cells; pub mod components; +mod helpers; +pub use helpers::*; + #[macro_use] mod execute; use execute::goto; @@ -46,6 +49,7 @@ extern crate notify_rust; extern crate chan; extern crate chan_signal; extern crate linkify; +extern crate uuid; use melib::*; use std::io::{Write, }; @@ -88,7 +92,7 @@ impl From for ThreadEvent { #[derive(Debug)] pub enum ForkType { Generic(std::process::Child), - NewDraft(std::path::PathBuf, std::process::Child), + NewDraft(File, std::process::Child), } @@ -105,7 +109,7 @@ pub enum UIEventType { ChangeMode(UIMode), Command(String), Notification(String), - EditDraft(std::path::PathBuf), + EditDraft(File), Action(Action), StatusNotification(String), } @@ -359,7 +363,7 @@ impl State { self.flush(); return; }, - UIEventType::EditDraft(dir) => { + UIEventType::EditDraft(mut file) => { use std::process::{Command, Stdio}; use std::io::Read; let mut output = Command::new("msmtp") @@ -371,10 +375,11 @@ impl State { { let mut in_pipe = output.stdin.as_mut().unwrap(); let mut buf = Vec::new(); - let mut f = std::fs::File::open(&dir).unwrap(); + let mut f = file.file(); f.read_to_end(&mut buf).unwrap(); in_pipe.write(&buf).unwrap(); + std::fs::remove_file(file.path()).unwrap(); } let output = output.wait_with_output().expect("Failed to read stdout");