Browse Source

bin/tau: implement export/import

Dastan-glitch 4 years ago
parent
commit
8653ea7f2a
3 changed files with 103 additions and 2 deletions
  1. 25 0
      bin/tau/tau-cli/src/main.rs
  2. 20 0
      bin/tau/tau-cli/src/rpc.rs
  3. 58 2
      bin/tau/taud/src/jsonrpc.rs

+ 25 - 0
bin/tau/tau-cli/src/main.rs

@@ -21,6 +21,8 @@ use primitives::{task_from_cli, State, TaskEvent};
 use util::{desc_in_editor, due_as_timestamp};
 use util::{desc_in_editor, due_as_timestamp};
 use view::{comments_as_string, print_task_info, print_task_list};
 use view::{comments_as_string, print_task_info, print_task_list};
 
 
+const DEFAULT_PATH: &str = "~/tau_exported_tasks";
+
 #[derive(Parser)]
 #[derive(Parser)]
 #[clap(name = "tau", version)]
 #[clap(name = "tau", version)]
 struct Args {
 struct Args {
@@ -76,6 +78,12 @@ enum TauSubcommand {
         /// Tau workspace
         /// Tau workspace
         workspace: String,
         workspace: String,
     },
     },
+
+    /// Import tasks from a specified directory.
+    Import { path: Option<String> },
+
+    /// Export tasks to a specified directory.
+    Export { path: Option<String> },
 }
 }
 
 
 pub struct Tau {
 pub struct Tau {
@@ -153,6 +161,23 @@ async fn main() -> Result<()> {
                 tau.switch_ws(workspace).await?;
                 tau.switch_ws(workspace).await?;
                 Ok(())
                 Ok(())
             }
             }
+
+            TauSubcommand::Export { path } => {
+                if path.is_some() {
+                    tau.export_to(path.unwrap()).await?;
+                } else {
+                    tau.export_to(DEFAULT_PATH.into()).await?;
+                }
+                Ok(())
+            }
+            TauSubcommand::Import { path } => {
+                if path.is_some() {
+                    tau.import_from(path.unwrap()).await?;
+                } else {
+                    tau.import_from(DEFAULT_PATH.into()).await?;
+                }
+                Ok(())
+            }
         },
         },
         None => {
         None => {
             let task_ids = tau.get_ids().await?;
             let task_ids = tau.get_ids().await?;

+ 20 - 0
bin/tau/tau-cli/src/rpc.rs

@@ -79,4 +79,24 @@ impl Tau {
 
 
         Ok(())
         Ok(())
     }
     }
+
+    /// Export tasks.
+    pub async fn export_to(&self, path: String) -> Result<()> {
+        let req = JsonRequest::new("export", json!([path]));
+        let rep = self.rpc_client.request(req).await?;
+
+        debug!("Got reply: {:?}", rep);
+
+        Ok(())
+    }
+
+    /// Import tasks.
+    pub async fn import_from(&self, path: String) -> Result<()> {
+        let req = JsonRequest::new("import", json!([path]));
+        let rep = self.rpc_client.request(req).await?;
+
+        debug!("Got reply: {:?}", rep);
+
+        Ok(())
+    }
 }
 }

+ 58 - 2
bin/tau/taud/src/jsonrpc.rs

@@ -1,5 +1,5 @@
 use async_std::sync::{Arc, Mutex};
 use async_std::sync::{Arc, Mutex};
-use std::path::PathBuf;
+use std::{fs::create_dir_all, path::PathBuf};
 
 
 use async_trait::async_trait;
 use async_trait::async_trait;
 use fxhash::FxHashMap;
 use fxhash::FxHashMap;
@@ -12,7 +12,7 @@ use darkfi::{
         jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResult},
         jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResult},
         server::RequestHandler,
         server::RequestHandler,
     },
     },
-    util::Timestamp,
+    util::{expand_path, Timestamp},
     Error,
     Error,
 };
 };
 
 
@@ -58,6 +58,8 @@ impl RequestHandler for JsonRpcInterface {
             Some("set_comment") => self.set_comment(params).await,
             Some("set_comment") => self.set_comment(params).await,
             Some("get_task_by_id") => self.get_task_by_id(params).await,
             Some("get_task_by_id") => self.get_task_by_id(params).await,
             Some("switch_ws") => self.switch_ws(params).await,
             Some("switch_ws") => self.switch_ws(params).await,
+            Some("export") => self.export_to(params).await,
+            Some("import") => self.import_from(params).await,
             Some(_) | None => return JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
             Some(_) | None => return JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
         };
         };
 
 
@@ -235,6 +237,60 @@ impl JsonRpcInterface {
         Ok(json!(true))
         Ok(json!(true))
     }
     }
 
 
+    // RPCAPI:
+    // Export tasks.
+    // --> {"jsonrpc": "2.0", "method": "export_to", "params": [path], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": "true", "id": 1}
+    async fn export_to(&self, params: &[Value]) -> TaudResult<Value> {
+        debug!(target: "tau", "JsonRpc::export_to() params {:?}", params);
+
+        if params.len() != 1 {
+            return Err(TaudError::InvalidData("len of params should be 1".into()))
+        }
+
+        if !params[0].is_string() {
+            return Err(TaudError::InvalidData("Invalid path".into()))
+        }
+
+        let path = expand_path(params[0].as_str().unwrap())?.join("exported_tasks");
+        // mkdir datastore_path if not exists
+        create_dir_all(path.join("month")).map_err(Error::from)?;
+        create_dir_all(path.join("task")).map_err(Error::from)?;
+        let mt = MonthTasks::load_or_create(None, &self.dataset_path)?;
+        let tasks = mt.objects(&self.dataset_path)?;
+
+        for task in tasks {
+            task.save(&path)?;
+        }
+
+        Ok(json!(true))
+    }
+
+    // RPCAPI:
+    // Import tasks.
+    // --> {"jsonrpc": "2.0", "method": "import_from", "params": [path], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": "true", "id": 1}
+    async fn import_from(&self, params: &[Value]) -> TaudResult<Value> {
+        debug!(target: "tau", "JsonRpc::import_from() params {:?}", params);
+
+        if params.len() != 1 {
+            return Err(TaudError::InvalidData("len of params should be 1".into()))
+        }
+
+        if !params[0].is_string() {
+            return Err(TaudError::InvalidData("Invalid path".into()))
+        }
+
+        let path = expand_path(params[0].as_str().unwrap())?.join("exported_tasks");
+        let mt = MonthTasks::load_or_create(None, &path)?;
+        let tasks = mt.objects(&path)?;
+
+        for task in tasks {
+            self.notify_queue_sender.send(task).await.map_err(Error::from)?;
+        }
+        Ok(json!(true))
+    }
+
     fn load_task_by_id(&self, task_id: &Value, ws: String) -> TaudResult<TaskInfo> {
     fn load_task_by_id(&self, task_id: &Value, ws: String) -> TaudResult<TaskInfo> {
         let task_id: u64 = serde_json::from_value(task_id.clone())?;
         let task_id: u64 = serde_json::from_value(task_id.clone())?;
         let tasks = MonthTasks::load_current_open_tasks(&self.dataset_path, ws)?;
         let tasks = MonthTasks::load_current_open_tasks(&self.dataset_path, ws)?;