From 5e40f4ec89a96f1326dfaf8efd1218d48c265c32 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 9 Oct 2022 19:03:00 +0200 Subject: [PATCH] fix(migration): properly parse duration --- pkg/modules/migration/ticktick/ticktick.go | 34 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/pkg/modules/migration/ticktick/ticktick.go b/pkg/modules/migration/ticktick/ticktick.go index 0de11317d4..e67bf28cc1 100644 --- a/pkg/modules/migration/ticktick/ticktick.go +++ b/pkg/modules/migration/ticktick/ticktick.go @@ -19,6 +19,7 @@ package ticktick import ( "encoding/csv" "io" + "regexp" "sort" "strconv" "strings" @@ -54,6 +55,32 @@ type tickTickTask struct { ParentID int64 } +// Copied from https://stackoverflow.com/a/57617885 +var durationRegex = regexp.MustCompile(`P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`) + +// ParseDuration converts a ISO8601 duration into a time.Duration +func parseDuration(str string) time.Duration { + matches := durationRegex.FindStringSubmatch(str) + + years := parseDurationPart(matches[1], time.Hour*24*365) + months := parseDurationPart(matches[2], time.Hour*24*30) + days := parseDurationPart(matches[3], time.Hour*24) + hours := parseDurationPart(matches[4], time.Hour) + minutes := parseDurationPart(matches[5], time.Second*60) + seconds := parseDurationPart(matches[6], time.Second) + + return time.Duration(years + months + days + hours + minutes + seconds) +} + +func parseDurationPart(value string, unit time.Duration) time.Duration { + if len(value) != 0 { + if parsed, err := strconv.ParseFloat(value[:len(value)-1], 64); err == nil { + return time.Duration(float64(unit) * parsed) + } + } + return 0 +} + func convertTickTickToVikunja(tasks []*tickTickTask) (result []*models.NamespaceWithListsAndTasks) { namespace := &models.NamespaceWithListsAndTasks{ Namespace: models.Namespace{ @@ -163,11 +190,6 @@ func (m *Migrator) Migrate(user *user.User, file io.ReaderAt, size int64) error if err != nil { return err } - // TODO: parse properly - reminder, err := time.ParseDuration(record[8]) - if err != nil { - return err - } priority, err := strconv.Atoi(record[10]) if err != nil { return err @@ -193,6 +215,8 @@ func (m *Migrator) Migrate(user *user.User, file io.ReaderAt, size int64) error return err } + reminder := parseDuration(record[8]) + allTasks = append(allTasks, &tickTickTask{ ListName: record[1], Title: record[2],