bin/taud: update 'list' function & add update rpc function

This commit is contained in:
ghassmo
2022-03-14 01:44:24 +04:00
parent a4f0904e46
commit 6027d98136
2 changed files with 195 additions and 32 deletions

View File

@@ -44,6 +44,7 @@ impl RequestHandler for JsonRpcInterface {
match req.method.as_str() {
Some("add") => return self.add(req.id, req.params).await,
Some("list") => return self.list(req.id, req.params).await,
Some("update") => return self.update(req.id, req.params).await,
Some(_) | None => return JsonResult::Err(jsonerr(MethodNotFound, None, req.id)),
}
}
@@ -102,16 +103,26 @@ impl JsonRpcInterface {
let assign = args[2].as_array();
if assign.is_some() && assign.unwrap().len() > 0 {
for a in assign.unwrap() {
task.assign(a.as_str().unwrap());
}
task.set_assign(
&assign
.unwrap()
.into_iter()
.filter(|a| a.as_str().is_some())
.map(|a| a.as_str().unwrap().to_string())
.collect(),
);
}
let project = args[3].as_array();
if project.is_some() && project.unwrap().len() > 0 {
for p in project.unwrap() {
task.project(p.as_str().unwrap());
}
task.set_project(
&project
.unwrap()
.into_iter()
.filter(|p| p.as_str().is_some())
.map(|p| p.as_str().unwrap().to_string())
.collect(),
);
}
let result = || -> Result<()> {
@@ -128,16 +139,152 @@ impl JsonRpcInterface {
// RPCAPI:
// List tasks
// --> {"jsonrpc": "2.0", "method": "list", "params": [], "id": 1}
// --> {"jsonrpc": "2.0", "method": "list", "params": [month_date], "id": 1}
// <-- {"jsonrpc": "2.0", "result": [task, ...], "id": 1}
async fn list(&self, id: Value, _params: Value) -> JsonResult {
let tasks: Result<Vec<TaskInfo>> = MonthTasks::load_current_open_tasks(&self.settings);
async fn list(&self, id: Value, params: Value) -> JsonResult {
let args = params.as_array().unwrap();
match tasks {
if args.len() != 1 {
return JsonResult::Err(jsonerr(InvalidParams, None, id))
}
let result = || -> Result<Vec<TaskInfo>> {
let tasks: Vec<TaskInfo>;
if args[0].is_i64() {
tasks = MonthTasks::load_or_create(
&Timestamp(args[0].as_i64().unwrap()),
&self.settings,
)?
.objects()?;
} else {
tasks = MonthTasks::load_current_open_tasks(&self.settings)?;
}
Ok(tasks)
};
match result() {
Ok(tks) => JsonResult::Resp(jsonresp(json!(tks), id)),
Err(e) => JsonResult::Err(jsonerr(ServerError(-32603), Some(e.to_string()), id)),
}
}
// RPCAPI:
// Update task returns `true` upon success.
// --> {"jsonrpc": "2.0", "method": "id", "params": [task_id, {"title": "new title"} ], "id": 1}
// <-- {"jsonrpc": "2.0", "result": true, "id": 1}
async fn update(&self, id: Value, params: Value) -> JsonResult {
let args = params.as_array().unwrap();
if args.len() != 2 {
return JsonResult::Err(jsonerr(InvalidParams, None, id))
}
let tasks: Vec<TaskInfo>;
if !args[0].is_u64() {
return JsonResult::Err(jsonerr(InvalidParams, Some("invalid id".into()), id))
}
if !args[1].is_object() {
return JsonResult::Err(jsonerr(InvalidParams, Some("invalid update data".into()), id))
}
let task_id = args[0].as_u64().unwrap();
let data = args[0].as_object().unwrap();
match MonthTasks::load_current_open_tasks(&self.settings) {
Ok(tks) => tasks = tks,
Err(_) => return JsonResult::Err(jsonerr(InvalidParams, None, id)),
}
let task = tasks.into_iter().find(|t| (t.get_id() as u64) == task_id);
if task.is_none() {
return JsonResult::Err(jsonerr(
InvalidRequest,
Some("Didn't find a task with the provided id".into()),
id,
))
}
let mut task = task.unwrap();
let mut result = || -> std::result::Result<(), &str> {
if data.contains_key("title") {
let title = data
.get("title")
.ok_or("error parsing title")?
.as_str()
.ok_or("invalid value for title")?;
task.set_title(title);
}
if data.contains_key("description") {
let description = data
.get("description")
.ok_or("error parsing description")?
.as_str()
.ok_or("invalid value for description")?;
task.set_desc(description);
}
if data.contains_key("rank") {
let rank = data
.get("rank")
.ok_or("error parsing rank")?
.as_u64()
.ok_or("invalid value for rank")?;
task.set_rank(rank as u32);
}
if data.contains_key("due") {
let due = Some(Timestamp(
data.get("due")
.ok_or("error parsing rank")?
.as_i64()
.ok_or("invalid value for rank")?,
));
task.set_due(due);
}
if data.contains_key("assign") {
task.set_assign(
&data
.get("assign")
.ok_or("error parsing assign")?
.as_array()
.ok_or("invalid value for assign")?
.into_iter()
.filter(|a| a.as_str().is_some())
.map(|a| a.as_str().unwrap().to_string())
.collect(),
);
}
if data.contains_key("project") {
task.set_project(
&data
.get("project")
.ok_or("error parsing project")?
.as_array()
.ok_or("invalid value for project")?
.into_iter()
.filter(|p| p.as_str().is_some())
.map(|p| p.as_str().unwrap().to_string())
.collect(),
);
}
Ok(())
};
match result() {
Ok(()) => JsonResult::Resp(jsonresp(json!(true), id)),
Err(e) => JsonResult::Err(jsonerr(InvalidParams, Some(e.to_string()), id)),
}
}
}
async fn start(config: TauConfig, executor: Arc<Executor<'_>>) -> Result<()> {

View File

@@ -87,18 +87,6 @@ impl TaskInfo {
})
}
pub fn assign(&mut self, n: &str) {
self.assign.push(n.into());
}
pub fn project(&mut self, p: &str) {
self.project.push(p.into());
}
pub fn set_comment(&mut self, c: Comment) {
self.comments.push(c);
}
pub fn load(ref_id: &str, settings: &Settings) -> Result<Self> {
let mut task = crate::util::load::<Self>(&Self::get_path(ref_id, settings))?;
task.set_settings(settings);
@@ -109,6 +97,12 @@ impl TaskInfo {
crate::util::save::<Self>(&Self::get_path(&self.ref_id, &self.settings), self)
}
pub fn activate(&self) -> Result<()> {
let mut mt = MonthTasks::load_or_create(&self.created_at, &self.settings)?;
mt.add(&self.ref_id);
mt.save()
}
pub fn get_state(&self) -> String {
if let Some(ev) = self.events.last() {
return ev.action.clone()
@@ -117,20 +111,14 @@ impl TaskInfo {
}
}
pub fn activate(&self) -> Result<()> {
let mut mt = MonthTasks::load_or_create(&self.created_at, &self.settings)?;
mt.add(&self.ref_id);
mt.save()
}
pub fn set_settings(&mut self, settings: &Settings) {
self.settings = settings.clone();
}
fn get_path(ref_id: &str, settings: &Settings) -> PathBuf {
settings.dataset_path.join("task").join(ref_id)
}
pub fn get_id(&self) -> u32 {
self.id.clone()
}
pub fn get_ref_id(&self) -> String {
self.ref_id.clone()
}
@@ -139,6 +127,34 @@ impl TaskInfo {
self.title = title.into();
}
pub fn set_desc(&mut self, desc: &str) {
self.desc = desc.into();
}
pub fn set_assign(&mut self, assign: &Vec<String>) {
self.assign = assign.clone();
}
pub fn set_project(&mut self, project: &Vec<String>) {
self.project = project.clone();
}
pub fn set_comment(&mut self, c: Comment) {
self.comments.push(c);
}
pub fn set_rank(&mut self, r: u32) {
self.rank = r;
}
pub fn set_due(&mut self, d: Option<Timestamp>) {
self.due = d;
}
pub fn set_settings(&mut self, settings: &Settings) {
self.settings = settings.clone();
}
pub fn set_state(&mut self, action: &str) {
if self.get_state() == action {
return