Add message composing and piping to msmtp

Closes #16
embed
Manos Pitsidianakis 2018-07-21 17:29:29 +03:00
parent b35407bc7f
commit 00235fe814
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
5 changed files with 74 additions and 9 deletions

View File

@ -16,5 +16,5 @@ melib = { path = "melib", version = "*" }
ui = { path = "ui", version = "*" }
[profile.release]
#lto = true
debug = true
lto = true
#debug = true

View File

@ -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;

View File

@ -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;
},

View File

@ -173,3 +173,13 @@ fn clear_area(grid: &mut CellBuffer, area: Area) {
}
}
}
fn new_draft(context: &mut Context) -> Vec<u8> {
// 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()
}

View File

@ -79,6 +79,12 @@ impl From<RefreshEvent> 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<W: Write> {
grid: CellBuffer,
stdout: termion::screen::AlternateScreen<termion::raw::RawTerminal<W>>,
child: Option<std::process::Child>,
child: Option<ForkType>,
pub mode: UIMode,
sender: Sender<ThreadEvent>,
entities: Vec<Entity>,
@ -324,6 +331,28 @@ impl<W: Write> State<W> {
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<W: Write> State<W> {
}
pub fn try_wait_on_child(&mut self) -> Option<bool> {
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)