package taskwarrior import ( "bytes" "encoding/json" "fmt" "os" "os/exec" "strings" "time" ) /// A task with an Id of 0 is either `completed` or `deleted` which is also /// mentioned in the Status field type Task struct { Id uint `json:"id,omitempty"` Git_id float32 `json:"git_id,omitempty"` // uda Git_type string `json:"git_type,omitempty"` // uda Project string `json:"project,omitempty"` Tags []string `json:"tags,omitempty"` Description string `json:"description,omitempty"` Annotations []Annotation `json:"annotations,omitempty"` Status string `json:"status,omitempty"` Depends []string `json:"depends,omitempty"` Due string `json:"due,omitempty"` Entry string `json:"entry,omitempty"` Modified string `json:"modified,omitempty"` End string `json:"end,omitempty"` Last_gitw_update string `json:"last_gitw_update,omitempty"` // uda Uuid string `json:"uuid,omitempty"` Urgency float32 `json:"urgency,omitempty"` } type Annotation struct { Description string `json:"description,omitempty"` Entry string `json:"entry,omitempty"` } func (task *Task) AppendComment(description string, time time.Time) { annotation := Annotation{ Description: description, Entry: GoTimeToTaskTime(time), } task.Annotations = append(task.Annotations, annotation) } func NewTask(description string, project string, git_id uint, git_type Type, tags ...string) Task { // TODO: update task struct to include the new user defined value, which shall // also be provided as an argument return Task{ Project: project, Description: description, Git_id: float32(git_id), Git_type: string(git_type), Last_gitw_update: GoTimeToTaskTime(time.Now()), Tags: tags, } } func TaskTimeToGoTime(t string) time.Time { splits := strings.Split(t, "T") if len(t) == 0 { return time.UnixMicro(0) } if len(splits) != 2 { fmt.Fprintf(os.Stderr, "Expected exactly 2 splits") os.Exit(-1) } date := splits[0] first := date[0:4] second := date[4:6] third := date[6:] date = strings.Join([]string{first, second, third}, "-") timestamp := splits[1] first = timestamp[0:2] second = timestamp[2:4] third = timestamp[4 : len(timestamp)-1] timestamp = strings.Join([]string{first, second, third}, ":") // TODO: identify current timezone and use correct format string (works for Europe/Berlin) value := fmt.Sprintf("%sT%s+02:00", date, timestamp) result, err := time.Parse(time.RFC3339, value) if err != nil { fmt.Fprint(os.Stderr, err) os.Exit(-1) } return result } func GoTimeToTaskTime(t time.Time) string { result := t.In(time.UTC).Format(time.RFC3339) result = strings.Replace(result, "-", "", 2) result = strings.Replace(result, ":", "", 2) return result } func GetTasks(filter Filter) ([]Task, error) { filter.filter = append(filter.filter, "export") cmd := exec.Command("task", filter.filter...) out, err := cmd.Output() if err != nil { return nil, err } var tasks []Task decoder := json.NewDecoder(bytes.NewBuffer(out)) decoder.DisallowUnknownFields() if err = decoder.Decode(&tasks); err != nil { return nil, err } return tasks, nil } func UpdateTasks(tasks []Task) error { cmd := exec.Command("task", "import") value, err := json.Marshal(tasks) if err != nil { return err } var buffer bytes.Buffer _, err = buffer.Write(value) if err != nil { return err } cmd.Stdin = &buffer return cmd.Run() }