diff --git a/bin/tau/taud/src/main.rs b/bin/tau/taud/src/main.rs index cc72579d3..d98b33646 100644 --- a/bin/tau/taud/src/main.rs +++ b/bin/tau/taud/src/main.rs @@ -16,15 +16,17 @@ * along with this program. If not, see . */ +use async_std::sync::{Arc, Mutex}; +use libc::mkfifo; use std::{ collections::HashMap, env, + ffi::CString, fs::{create_dir_all, remove_dir_all}, - io::stdin, + io::{stdin, Write}, path::Path, }; -use async_std::sync::{Arc, Mutex}; use crypto_box::{ aead::{Aead, AeadCore}, rand_core::OsRng, @@ -63,6 +65,7 @@ use crate::{ jsonrpc::JsonRpcInterface, settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS}, task_info::TaskInfo, + util::pipe_write, }; fn get_workspaces(settings: &Args) -> Result> { @@ -146,6 +149,7 @@ async fn start_sync_loop( workspaces: HashMap, datastore_path: std::path::PathBuf, missed_events: Arc>>>, + piped: bool, p2p: P2pPtr, ) -> TaudResult<()> { loop { @@ -176,7 +180,7 @@ async fn start_sync_loop( missed_events.lock().await.push(event.clone()); - on_receive_task(&event.action, &datastore_path, &workspaces) + on_receive_task(&event.action, &datastore_path, &workspaces, piped) .await?; } } @@ -187,6 +191,7 @@ async fn on_receive_task( task: &EncryptedTask, datastore_path: &Path, workspaces: &HashMap, + piped: bool, ) -> TaudResult<()> { for (workspace, salsa_box) in workspaces.iter() { let task = decrypt_task(task, salsa_box); @@ -198,6 +203,33 @@ async fn on_receive_task( let mut task = task.unwrap(); info!(target: "tau", "Save the task: ref: {}", task.ref_id); task.workspace = workspace.clone(); + if piped { + // if we can't load tha task then it's a new task. + // otherwise it's a modification. + if TaskInfo::load(&task.ref_id, datastore_path).is_err() { + let file = "/tmp/tau_pipe"; + let mut pipe_write = pipe_write(file).unwrap(); + let buf = format!( + "{{ \"action\": \"add_task\", \"owner\": \"{}\", \"content\": \"{}\" }}", + task.owner.clone(), + task.title.clone() + ); + pipe_write.write_all(buf.as_bytes()).unwrap(); + } else { + match task.events.0.last() { + Some(ev) => { + let file = "/tmp/tau_pipe"; + let mut pipe_write = pipe_write(file).unwrap(); + let buf = format!( + "{{ \"action\": \"{}\", \"author\": \"{}\", \"content\": \"{}\" }}", + ev.action, ev.author, ev.content + ); + pipe_write.write_all(buf.as_bytes()).unwrap(); + } + None => todo!(), + } + } + } task.save(datastore_path)?; } Ok(()) @@ -233,6 +265,12 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<( return Ok(()) } + if settings.piped { + let file = "/tmp/tau_pipe"; + let path = CString::new(file).unwrap(); + unsafe { mkfifo(path.as_ptr(), 0o644) }; + } + // mkdir datastore_path if not exists create_dir_all(datastore_path.clone())?; create_dir_all(datastore_path.join("month"))?; @@ -330,6 +368,7 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<( workspaces.clone(), datastore_path.clone(), missed_events, + settings.piped, p2p.clone(), )) .detach(); diff --git a/bin/tau/taud/src/settings.rs b/bin/tau/taud/src/settings.rs index 00420d833..c118ceea0 100644 --- a/bin/tau/taud/src/settings.rs +++ b/bin/tau/taud/src/settings.rs @@ -58,4 +58,7 @@ pub struct Args { /// Current display name #[structopt(long)] pub nickname: Option, + // Whether to pipe notifications or not + #[structopt(long)] + pub piped: bool, } diff --git a/bin/tau/taud/src/task_info.rs b/bin/tau/taud/src/task_info.rs index 8dbfbe729..9a4306f67 100644 --- a/bin/tau/taud/src/task_info.rs +++ b/bin/tau/taud/src/task_info.rs @@ -38,10 +38,10 @@ use crate::{ #[derive(Clone, Debug, Serialize, Deserialize, SerialEncodable, SerialDecodable, PartialEq, Eq)] pub struct TaskEvent { - action: String, - author: String, - content: String, - timestamp: Timestamp, + pub action: String, + pub author: String, + pub content: String, + pub timestamp: Timestamp, } impl TaskEvent { @@ -83,10 +83,10 @@ pub struct TaskInfo { pub(crate) ref_id: String, pub(crate) workspace: String, pub(crate) id: u32, - title: String, + pub(crate) title: String, tags: TaskTags, desc: String, - owner: String, + pub(crate) owner: String, assign: TaskAssigns, project: TaskProjects, due: Option, diff --git a/bin/tau/taud/src/util.rs b/bin/tau/taud/src/util.rs index e7b93c47c..a185b1816 100644 --- a/bin/tau/taud/src/util.rs +++ b/bin/tau/taud/src/util.rs @@ -16,8 +16,16 @@ * along with this program. If not, see . */ +use std::{ + fs::{File, OpenOptions}, + os::unix::prelude::OpenOptionsExt, + path::Path, +}; + use log::debug; +use darkfi::{Error, Result}; + use crate::task_info::{TaskEvent, TaskInfo}; pub fn find_free_id(task_ids: &[u32]) -> u32 { @@ -36,6 +44,15 @@ pub fn set_event(task_info: &mut TaskInfo, action: &str, author: &str, content: } } +pub fn pipe_write>(path: P) -> Result { + OpenOptions::new() + .write(true) + .append(true) + .custom_flags(libc::O_NONBLOCK) + .open(path) + .map_err(Error::from) +} + #[cfg(test)] mod tests { use super::*;