avoid removal of recurrent task due to TW-638 bug of taskwarrior
[ptask.git] / src / tw.c
index e48ab59..3049c0b 100644 (file)
--- a/src/tw.c
+++ b/src/tw.c
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
+#define _GNU_SOURCE
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <time.h>
 
-#include <json/json.h>
+#include <json.h>
 
-#include <list.h>
 #include <log.h>
 #include "note.h"
 #include <pstr.h>
 #include "tw.h"
 
+struct tm *parse_time(const char *t)
+{
+       struct tm *tm;
+
+       tm = malloc(sizeof(struct tm));
+       memset(tm, 0, sizeof(struct tm));
+       strptime(t, "%Y%m%dT%H%M%S%Z", tm);
+
+       return tm;
+}
+
 static char *task_exec(char *opts)
 {
        FILE *f;
@@ -96,7 +108,9 @@ static int task_check_version()
 
        log_debug("task version: %s", ver);
 
-       if (!strcmp(ver, "2.2.0") || !strcmp(ver, "2.0.0"))
+       if (!strcmp(ver, "2.2.0")
+           || !strcmp(ver, "2.0.0")
+           || !strcmp(ver, "2.3.0"))
                return 1;
        else
                return 0;
@@ -141,6 +155,9 @@ static struct json_object *task_exec_json(const char *opts)
 
        free(cmd);
 
+       if (o && is_error(o))
+               return NULL;
+
        return o;
 }
 
@@ -206,6 +223,29 @@ struct task **tw_get_all_tasks(const char *status)
                        tasks[i]->urgency = NULL;
 
                tasks[i]->note = note_get(tasks[i]->uuid);
+
+               json = json_object_object_get(jtask, "entry");
+               tasks[i]->entry = parse_time(json_object_get_string(json));
+
+               json = json_object_object_get(jtask, "due");
+               if (json)
+                       tasks[i]->due
+                               = parse_time(json_object_get_string(json));
+               else
+                       tasks[i]->due = NULL;
+
+               json = json_object_object_get(jtask, "start");
+               if (json)
+                       tasks[i]->start
+                               = parse_time(json_object_get_string(json));
+               else
+                       tasks[i]->start = NULL;
+
+               json = json_object_object_get(jtask, "recur");
+               if (json)
+                       tasks[i]->recur = strdup(json_object_get_string(json));
+               else
+                       tasks[i]->recur = NULL;
        }
 
        tasks[n] = NULL;
@@ -352,7 +392,7 @@ void tw_add(const char *newdesc, const char *prj, const char *prio)
        log_fct_exit();
 }
 
-void tw_done(const char *uuid)
+void tw_task_done(const char *uuid)
 {
        char *opts;
 
@@ -367,6 +407,36 @@ void tw_done(const char *uuid)
        free(opts);
 }
 
+void tw_task_start(const char *uuid)
+{
+       char *opts;
+
+       opts = malloc(1
+                     + strlen(uuid)
+                     + strlen(" start")
+                     + 1);
+       sprintf(opts, " %s start", uuid);
+
+       tw_exec(opts);
+
+       free(opts);
+}
+
+void tw_task_stop(const char *uuid)
+{
+       char *opts;
+
+       opts = malloc(1
+                     + strlen(uuid)
+                     + strlen(" stop")
+                     + 1);
+       sprintf(opts, " %s stop", uuid);
+
+       tw_exec(opts);
+
+       free(opts);
+}
+
 void tw_task_remove(const char *uuid)
 {
        char *opts;
@@ -394,6 +464,10 @@ static void task_free(struct task *task)
        free(task->project);
        free(task->priority);
        free(task->urgency);
+       free(task->entry);
+       free(task->due);
+       free(task->start);
+       free(task->recur);
 
        free(task);
 }
@@ -456,6 +530,41 @@ static struct project *project_new(const char *name, int count)
        return prj;
 }
 
+static int projects_length(struct project **list)
+{
+       int n;
+
+       if (!list)
+               return 0;
+
+       n = 0;
+       while (*list) {
+               n++;
+               list++;
+       }
+
+       return n;
+}
+
+static struct project **projects_add(struct project **list, void *item)
+{
+       int n;
+       struct project **result;
+
+       n = projects_length(list);
+
+       result = (struct project **)malloc
+               ((n + 1 + 1) * sizeof(struct project *));
+
+       if (list)
+               memcpy(result, list, n * sizeof(struct project *));
+
+       result[n] = item;
+       result[n + 1] = NULL;
+
+       return result;
+}
+
 struct project **tw_get_projects(struct task **tasks)
 {
        struct task **t_cur;
@@ -476,7 +585,7 @@ struct project **tw_get_projects(struct task **tasks)
                } else {
                        prj = project_new(prj_name, 1);
 
-                       tmp = (struct project **)list_add((void **)prjs, prj);
+                       tmp = projects_add(prjs, prj);
 
                        free(prjs);
                        prjs = tmp;