From 00235fe814d2fe4ca3fb0745f9721cf43eb983e1 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 21 Jul 2018 17:29:29 +0300 Subject: [PATCH] Add message composing and piping to msmtp Closes #16 --- Cargo.toml | 4 +-- src/bin.rs | 2 +- ui/src/components/mail/listing.rs | 13 +++++++- ui/src/components/mod.rs | 10 ++++++ ui/src/lib.rs | 54 ++++++++++++++++++++++++++++--- 5 files changed, 74 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ca31553e..1bdd573d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,5 @@ melib = { path = "melib", version = "*" } ui = { path = "ui", version = "*" } [profile.release] -#lto = true -debug = true +lto = true +#debug = true diff --git a/src/bin.rs b/src/bin.rs index 22462314..8340ab2e 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -193,7 +193,7 @@ fn main() { Some(false) => { use std::{thread, time}; - let ten_millis = time::Duration::from_millis(500); + let ten_millis = time::Duration::from_millis(1500); thread::sleep(ten_millis); continue 'reap; diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index df337977..2e5ba93e 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -498,8 +498,19 @@ 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(); + + // TODO: check exit status let mut output = Command::new("vim") + .arg("+/^$") + .arg(&dir) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .spawn() @@ -509,7 +520,7 @@ impl Component for MailListing { * 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(output) }); + 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::ChangeMode(UIMode::Fork) }); return; }, diff --git a/ui/src/components/mod.rs b/ui/src/components/mod.rs index a4df6768..498be780 100644 --- a/ui/src/components/mod.rs +++ b/ui/src/components/mod.rs @@ -173,3 +173,13 @@ fn clear_area(grid: &mut CellBuffer, area: Area) { } } } + +fn new_draft(context: &mut Context) -> Vec { + // TODO: Generate proper message-id https://www.jwz.org/doc/mid.html + let mut v = String::with_capacity(500); + v.push_str("From: \n"); + v.push_str("To: \n"); + v.push_str("Subject: \n"); + v.push_str("Message-Id: \n\n"); + v.into_bytes() +} diff --git a/ui/src/lib.rs b/ui/src/lib.rs index c4cdcd46..0eeb3e52 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -79,6 +79,12 @@ impl From for ThreadEvent { } } +#[derive(Debug)] +pub enum ForkType { + Generic(std::process::Child), + NewDraft(std::path::PathBuf, std::process::Child), +} + #[derive(Debug)] pub enum UIEventType { @@ -88,11 +94,12 @@ pub enum UIEventType { //Quit? Resize, /// Force redraw. - Fork(std::process::Child), + Fork(ForkType), ChangeMailbox(usize), ChangeMode(UIMode), Command(String), Notification(String), + EditDraft(std::path::PathBuf), } @@ -160,7 +167,7 @@ pub struct State { grid: CellBuffer, stdout: termion::screen::AlternateScreen>, - child: Option, + child: Option, pub mode: UIMode, sender: Sender, entities: Vec, @@ -324,6 +331,28 @@ impl State { self.stdout.flush().unwrap(); return; }, + UIEventType::EditDraft(dir) => { + use std::process::{Command, Stdio}; + use std::io::Read; + let mut output = Command::new("msmtp") + .arg("-t") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to execute process") ; + { + let mut in_pipe = output.stdin.as_mut().unwrap(); + let mut buf = Vec::new(); + let mut f = std::fs::File::open(&dir).unwrap(); + + f.read_to_end(&mut buf).unwrap(); + in_pipe.write(&buf).unwrap(); + } + let output = output.wait_with_output().expect("Failed to read stdout"); + eprintln!("{}",String::from_utf8_lossy(&output.stdout)); + + return; + } _ => {}, } /* inform each entity */ @@ -348,19 +377,34 @@ impl State { } pub fn try_wait_on_child(&mut self) -> Option { if { - if let Some(ref mut c) = self.child { + match self.child { + Some(ForkType::NewDraft(_,ref mut c)) => { let mut w = c.try_wait(); match w { Ok(Some(_)) => { true }, Ok(None) => { false }, Err(_) => { return None; }, } - } else { + }, + Some(ForkType::Generic(ref mut c)) => { + let mut w = c.try_wait(); + match w { + Ok(Some(_)) => { true }, + Ok(None) => { false }, + Err(_) => { return None; }, + } + }, + + _ => { return None; } } + } { - self.child = None; + if let Some(ForkType::NewDraft(f, _)) = std::mem::replace(&mut self.child, None) { + self.rcv_event(UIEvent { id: 0, event_type: UIEventType::EditDraft(f) }); + + } return Some(true); } Some(false)