WIP for #3. Creation of entirely new tasks is possible and works as expected. The only remaining issue is the merging of existing tasks.
131 lines
3.7 KiB
Go
131 lines
3.7 KiB
Go
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 {
|
|
// TODO: apply required changes to the string for correct parsing
|
|
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}, ":")
|
|
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.Format(time.RFC3339)
|
|
// TODO: apply changes to the result
|
|
// go: 2023-10-10T19:57:22+02:00
|
|
// task: 20231010T195722Z
|
|
result = strings.Replace(result, "-", "", 2)
|
|
result = strings.Replace(result, ":", "", 2)
|
|
result = strings.ReplaceAll(result, "+02:00", "Z")
|
|
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()
|
|
}
|