package main import ( "bufio" sdk "code.vikunja.io/go-sdk" "context" "log" "os" "strings" ) func main() { const listID = 19 client := sdk.NewAPIClient(&sdk.Configuration{ BasePath: "http://localhost:8080/api/v1", DefaultHeader: make(map[string]string), UserAgent: "Go client", }) token, _, err := client.UserApi.LoginPost(context.Background(), sdk.ModelsUserLogin{ Username: os.Getenv("VIKUNJA_USERNAME"), Password: os.Getenv("VIKUNJA_PASSWORD"), }) if err != nil { log.Fatal("Error auth", err) } log.Println("Auth succeeded, token is ", token.Token) auth := context.WithValue(context.Background(), sdk.ContextAPIKey, sdk.APIKey{ Key: token.Token, Prefix: "Bearer", }) // Read the md file lines, err := scanLines("../api/Featurecreep.md") if err != nil { log.Fatal("Error reading file: ", err) } tasks := make([]*sdk.ModelsTask, 0, len(lines)) var lastHeadline string var notApplicable []string var lastTask *sdk.ModelsTask var taskRelations []*sdk.ModelsTaskRelation for in, l := range lines { if l == "" { continue } if strings.HasPrefix(l, "#") { lastHeadline = strings.TrimSpace(strings.ReplaceAll(l, "#", "")) continue } // Only add tasks to the list if strings.HasPrefix(l, "* [") { t := &sdk.ModelsTask{ Text: l[5:], Done: strings.HasPrefix(l, "* [x]"), Labels: []sdk.ModelsLabel{ { Title: lastHeadline, }, }, } *t, _, err = client.TaskApi.ListsIdPut(auth, listID, *t) if err != nil { log.Fatal("Error creating task: ", err) } log.Printf("Created task %d of %d with ID %d", in, len(lines), t.Id) // Subtask handling lastTask = t tasks = append(tasks, t) continue } // Subtask handling // If we have a line starting with two spaces and then task, we have a subtask of the last task if strings.HasPrefix(l, " * [") { subtask := &sdk.ModelsTask{ Text: l[7:], Done: strings.HasPrefix(l, " * [x]"), Labels: []sdk.ModelsLabel{ { Title: lastHeadline, }, }, } *subtask, _, err = client.TaskApi.ListsIdPut(auth, listID, *subtask) if err != nil { log.Fatal("Error creating task: ", err) } log.Printf("Created task %d of %d with ID %d", in, len(lines), subtask.Id) tasks = append(tasks, subtask) taskRelations = append(taskRelations, &sdk.ModelsTaskRelation{ TaskId: lastTask.Id, OtherTaskId: subtask.Id, RelationKind: "subtask", }) continue } // If we had a last task, every line which follows now is not a subtask but additional description, so we put it in as description if lastTask != nil { lastTask.Description = lastTask.Description + l + "\n" continue } notApplicable = append(notApplicable, l) } log.Println("Done migrating tasks.") // Update all tasks which have a description for _, t := range tasks { if t.Description == "" { continue } *t, _, err = client.TaskApi.TasksIdPost(auth, t.Id, *t) if err != nil { log.Fatal("Error updating task description: ", err) } log.Printf("Updated description of task %d", t.Id) } // TODO: update all labels afterwards // TODO: create all relations afterwards log.Println("Done.") } func scanLines(path string) ([]string, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) var lines []string for scanner.Scan() { lines = append(lines, scanner.Text()) } return lines, nil }