diff --git a/pkg/modules/migration/ticktick/ticktick.go b/pkg/modules/migration/ticktick/ticktick.go index e67bf28cc1..b86594568d 100644 --- a/pkg/modules/migration/ticktick/ticktick.go +++ b/pkg/modules/migration/ticktick/ticktick.go @@ -18,6 +18,7 @@ package ticktick import ( "encoding/csv" + "errors" "io" "regexp" "sort" @@ -25,6 +26,8 @@ import ( "strings" "time" + "code.vikunja.io/api/pkg/log" + "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/migration" "code.vikunja.io/api/pkg/user" @@ -62,6 +65,10 @@ var durationRegex = regexp.MustCompile(`P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d func parseDuration(str string) time.Duration { matches := durationRegex.FindStringSubmatch(str) + if len(matches) == 0 { + return 0 + } + years := parseDurationPart(matches[1], time.Hour*24*365) months := parseDurationPart(matches[2], time.Hour*24*30) days := parseDurationPart(matches[3], time.Hour*24) @@ -69,7 +76,7 @@ func parseDuration(str string) time.Duration { minutes := parseDurationPart(matches[5], time.Second*60) seconds := parseDurationPart(matches[6], time.Second) - return time.Duration(years + months + days + hours + minutes + seconds) + return years + months + days + hours + minutes + seconds } func parseDurationPart(value string, unit time.Duration) time.Duration { @@ -170,38 +177,30 @@ func (m *Migrator) Name() string { // @Failure 500 {object} models.Message "Internal server error" // @Router /migration/ticktick/migrate [post] func (m *Migrator) Migrate(user *user.User, file io.ReaderAt, size int64) error { - fr := io.NewSectionReader(file, 0, 0) + fr := io.NewSectionReader(file, 0, size) r := csv.NewReader(fr) - records, err := r.ReadAll() - if err != nil { - return err - } - allTasks := make([]*tickTickTask, 0, len(records)) - for line, record := range records { - if line <= 3 { + allTasks := []*tickTickTask{} + line := 0 + for { + + record, err := r.Read() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + log.Debugf("[TickTick Migration] CSV parse error: %s", err) + } + + line++ + if line <= 4 { continue } - startDate, err := time.Parse(timeISO, record[6]) - if err != nil { - return err - } - dueDate, err := time.Parse(timeISO, record[7]) - if err != nil { - return err - } + priority, err := strconv.Atoi(record[10]) if err != nil { return err } - createdTime, err := time.Parse(timeISO, record[12]) - if err != nil { - return err - } - completedTime, err := time.Parse(timeISO, record[13]) - if err != nil { - return err - } order, err := strconv.ParseFloat(record[14], 64) if err != nil { return err @@ -217,24 +216,47 @@ func (m *Migrator) Migrate(user *user.User, file io.ReaderAt, size int64) error reminder := parseDuration(record[8]) - allTasks = append(allTasks, &tickTickTask{ - ListName: record[1], - Title: record[2], - Tags: strings.Split(record[3], ", "), - Content: record[4], - IsChecklist: record[5] == "Y", - StartDate: startDate, - DueDate: dueDate, - Reminder: reminder, - Repeat: record[9], - Priority: priority, - Status: record[11], - CreatedTime: createdTime, - CompletedTime: completedTime, - Order: order, - TaskID: taskID, - ParentID: parentID, - }) + t := &tickTickTask{ + ListName: record[1], + Title: record[2], + Tags: strings.Split(record[3], ", "), + Content: record[4], + IsChecklist: record[5] == "Y", + Reminder: reminder, + Repeat: record[9], + Priority: priority, + Status: record[11], + Order: order, + TaskID: taskID, + ParentID: parentID, + } + + if record[6] != "" { + t.StartDate, err = time.Parse(timeISO, record[6]) + if err != nil { + return err + } + } + if record[7] != "" { + t.DueDate, err = time.Parse(timeISO, record[7]) + if err != nil { + return err + } + } + if record[12] != "" { + t.StartDate, err = time.Parse(timeISO, record[12]) + if err != nil { + return err + } + } + if record[13] != "" { + t.CompletedTime, err = time.Parse(timeISO, record[13]) + if err != nil { + return err + } + } + + allTasks = append(allTasks, t) } vikunjaTasks := convertTickTickToVikunja(allTasks) diff --git a/pkg/routes/api/v1/info.go b/pkg/routes/api/v1/info.go index 63d822e21c..37f63b7f76 100644 --- a/pkg/routes/api/v1/info.go +++ b/pkg/routes/api/v1/info.go @@ -17,22 +17,19 @@ package v1 import ( - "code.vikunja.io/api/pkg/modules/migration/ticktick" "net/http" - vikunja_file "code.vikunja.io/api/pkg/modules/migration/vikunja-file" - - microsofttodo "code.vikunja.io/api/pkg/modules/migration/microsoft-todo" - - "code.vikunja.io/api/pkg/modules/migration/trello" - - "code.vikunja.io/api/pkg/log" - "code.vikunja.io/api/pkg/config" + "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/modules/auth/openid" + microsofttodo "code.vikunja.io/api/pkg/modules/migration/microsoft-todo" + "code.vikunja.io/api/pkg/modules/migration/ticktick" "code.vikunja.io/api/pkg/modules/migration/todoist" + "code.vikunja.io/api/pkg/modules/migration/trello" + vikunja_file "code.vikunja.io/api/pkg/modules/migration/vikunja-file" "code.vikunja.io/api/pkg/modules/migration/wunderlist" "code.vikunja.io/api/pkg/version" + "github.com/labstack/echo/v4" ) diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index ee85e2265d..1f98a9fd63 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -47,19 +47,12 @@ package routes import ( - "code.vikunja.io/api/pkg/modules/migration/ticktick" "errors" "fmt" "net/url" "strings" "time" - "code.vikunja.io/api/pkg/modules/migration/ticktick" - - "github.com/ulule/limiter/v3" - - vikunja_file "code.vikunja.io/api/pkg/modules/migration/vikunja-file" - "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/log" @@ -73,8 +66,10 @@ import ( "code.vikunja.io/api/pkg/modules/migration" migrationHandler "code.vikunja.io/api/pkg/modules/migration/handler" microsofttodo "code.vikunja.io/api/pkg/modules/migration/microsoft-todo" + "code.vikunja.io/api/pkg/modules/migration/ticktick" "code.vikunja.io/api/pkg/modules/migration/todoist" "code.vikunja.io/api/pkg/modules/migration/trello" + vikunja_file "code.vikunja.io/api/pkg/modules/migration/vikunja-file" "code.vikunja.io/api/pkg/modules/migration/wunderlist" apiv1 "code.vikunja.io/api/pkg/routes/api/v1" "code.vikunja.io/api/pkg/routes/caldav" @@ -89,6 +84,7 @@ import ( "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" elog "github.com/labstack/gommon/log" + "github.com/ulule/limiter/v3" ) // NewEcho registers a new Echo instance