[WIP] Add task editing

This commit is contained in:
Martin
2024-05-21 21:53:08 +02:00
parent fce35f0fc7
commit a23b76c3c9
4 changed files with 129 additions and 28 deletions

View File

@ -3,6 +3,7 @@ package taskwarrior
import (
"fmt"
"log/slog"
"math"
"strconv"
"strings"
"time"
@ -18,19 +19,21 @@ type Task struct {
Tags []string `json:"tags"`
Depends []string `json:"depends"`
Urgency float32 `json:"urgency"`
Parent string `json:"parent"`
Due string `json:"due"`
Wait string `json:"wait"`
Scheduled string `json:"scheduled"`
Until string `json:"until"`
Recur string `json:"recur"`
Start string `json:"start"`
End string `json:"end"`
Entry string `json:"entry"`
Modified string `json:"modified"`
Parent string `json:"parent"`
Recur string `json:"recur"`
}
func (t *Task) Get(field string) string {
func (t *Task) GetString(fieldWFormat string) string {
field, format, _ := strings.Cut(fieldWFormat, ".")
switch field {
case "id":
return strconv.FormatInt(t.Id, 10)
@ -49,30 +52,24 @@ func (t *Task) Get(field string) string {
case "urgency":
return fmt.Sprintf("%.2f", t.Urgency)
case "due":
return t.Due
return formatDate(t.Due, format)
case "wait":
return t.Wait
case "scheduled":
return t.Scheduled
return formatDate(t.Scheduled, format)
case "end":
return t.End
case "entry":
return t.Entry
return formatDate(t.Entry, format)
case "modified":
return t.Modified
case "start":
return formatDate(t.Start, format)
case "until":
return formatDate(t.Until, format)
// TODO: implement these fields
case "start.age":
return formatTime(t.Start)
case "depends":
return strings.Join(t.Depends, ", ")
case "entry.age":
return formatTime(t.Entry)
case "scheduled.countdown":
return formatTime(t.Scheduled)
case "until.remaining":
return formatTime(t.Until)
case "due.relative":
return formatTime(t.Due)
case "recur":
return t.Recur
default:
@ -104,15 +101,75 @@ type Report struct {
type Reports map[string]*Report
func formatTime(timeStr string) string {
if timeStr == "" {
func formatDate(date string, format string) string {
if date == "" {
return ""
}
format := "20060102T150405Z"
t, err := time.Parse(format, timeStr)
dtformat := "20060102T150405Z"
dt, err := time.Parse(dtformat, date)
if err != nil {
slog.Error("Failed to parse time:", err)
return timeStr
return ""
}
switch format {
case "formatted", "":
return dt.Format("2006-01-02 15:04")
// TODO: proper julian date formatting
case "julian":
return dt.Format("060102.1504")
case "epoch":
return strconv.FormatInt(dt.Unix(), 10)
case "iso":
return dt.Format("2006-01-02T150405Z")
case "age":
return parseDurationVague(time.Since(dt))
case "relative":
return parseDurationVague(time.Until(dt))
// TODO: implement remaining
case "remaining":
return ""
case "countdown":
return parseCountdown(time.Since(dt))
default:
slog.Error(fmt.Sprintf("Date format not implemented: %s", format))
return ""
}
return t.Format("2006-01-02 15:04")
}
func parseDurationVague(d time.Duration) string {
dur := d.Round(time.Second).Abs()
days := dur.Hours() / 24
var formatted string
if dur >= time.Hour*24*365 {
formatted = fmt.Sprintf("%.1fy", days/365)
} else if dur >= time.Hour*24*90 {
formatted = strconv.Itoa(int(math.Round(days/30))) + "mo"
} else if dur >= time.Hour*24*7 {
formatted = strconv.Itoa(int(math.Round(days/7))) + "w"
} else if dur >= time.Hour*24 {
formatted = strconv.Itoa(int(days)) + "d"
} else if dur >= time.Hour {
formatted = strconv.Itoa(int(dur.Round(time.Hour).Hours())) + "h"
} else if dur >= time.Minute {
formatted = strconv.Itoa(int(dur.Round(time.Minute).Minutes())) + "min"
} else if dur >= time.Second {
formatted = strconv.Itoa(int(dur.Round(time.Second).Seconds())) + "s"
}
if d < 0 {
formatted = "-" + formatted
}
return formatted
}
func parseCountdown(d time.Duration) string {
hours := int(d.Hours())
minutes := int(d.Minutes()) % 60
seconds := int(d.Seconds()) % 60
return fmt.Sprintf("%d:%02d:%02d", hours, minutes, seconds)
}