fix(migration): use the proper authorization method for Todoist's api, fix issues with importing deleted items
This commit is contained in:
parent
31a1452839
commit
1971df7b84
@ -56,12 +56,22 @@ func DownloadFileWithHeaders(url string, headers http.Header) (buf *bytes.Buffer
|
|||||||
|
|
||||||
// DoPost makes a form encoded post request
|
// DoPost makes a form encoded post request
|
||||||
func DoPost(url string, form url.Values) (resp *http.Response, err error) {
|
func DoPost(url string, form url.Values) (resp *http.Response, err error) {
|
||||||
|
return DoPostWithHeaders(url, form, map[string]string{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoPostWithHeaders does an api request and allows to pass in arbitrary headers
|
||||||
|
func DoPostWithHeaders(url string, form url.Values, headers map[string]string) (resp *http.Response, err error) {
|
||||||
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, url, strings.NewReader(form.Encode()))
|
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, url, strings.NewReader(form.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
for key, value := range headers {
|
||||||
|
req.Header.Add(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
hc := http.Client{}
|
hc := http.Client{}
|
||||||
return hc.Do(req)
|
return hc.Do(req)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -76,7 +77,6 @@ type dueDate struct {
|
|||||||
|
|
||||||
type item struct {
|
type item struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
LegacyID string `json:"legacy_id"`
|
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
ProjectID string `json:"project_id"`
|
ProjectID string `json:"project_id"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
@ -310,6 +310,12 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range sync.Items {
|
for _, i := range sync.Items {
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
// This should never happen
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
task := &models.TaskWithComments{
|
task := &models.TaskWithComments{
|
||||||
Task: models.Task{
|
Task: models.Task{
|
||||||
Title: i.Content,
|
Title: i.Content,
|
||||||
@ -524,11 +530,14 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||||||
|
|
||||||
// Get everything with the sync api
|
// Get everything with the sync api
|
||||||
form := url.Values{
|
form := url.Values{
|
||||||
"token": []string{token},
|
|
||||||
"sync_token": []string{"*"},
|
"sync_token": []string{"*"},
|
||||||
"resource_types": []string{"[\"all\"]"},
|
"resource_types": []string{"[\"all\"]"},
|
||||||
}
|
}
|
||||||
resp, err := migration.DoPost("https://api.todoist.com/sync/v9/sync", form)
|
bearerHeader := map[string]string{
|
||||||
|
"Authorization": "Bearer " + token,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/sync", form, bearerHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -547,7 +556,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||||||
doneItems := make(map[string]*doneItem)
|
doneItems := make(map[string]*doneItem)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/completed/get_all?limit=200&offset="+strconv.Itoa(offset), form)
|
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/completed/get_all?limit=200&offset="+strconv.Itoa(offset), form, bearerHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -571,21 +580,26 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||||||
doneItems[i.TaskID] = i
|
doneItems[i.TaskID] = i
|
||||||
|
|
||||||
// need to get done item data
|
// need to get done item data
|
||||||
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/items/get", url.Values{
|
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/items/get", url.Values{
|
||||||
"token": []string{token},
|
|
||||||
"item_id": []string{i.TaskID},
|
"item_id": []string{i.TaskID},
|
||||||
})
|
}, bearerHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
// Done items of deleted projects may show up here but since the project is already deleted
|
||||||
|
// we can't show them individually and the api returns a 404.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
doneI := &itemWrapper{}
|
doneI := &itemWrapper{}
|
||||||
err = json.NewDecoder(resp.Body).Decode(doneI)
|
err = json.NewDecoder(resp.Body).Decode(doneI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("[Todoist Migration] Retrieved full task data for done task %s", i.TaskID)
|
log.Debugf("[Todoist Migration] Retrieved full task data for done task %s", i.ID)
|
||||||
syncResponse.Items = append(syncResponse.Items, doneI.Item)
|
syncResponse.Items = append(syncResponse.Items, doneI.Item)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +614,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||||||
log.Debugf("[Todoist Migration] Getting archived projects for user %d", u.ID)
|
log.Debugf("[Todoist Migration] Getting archived projects for user %d", u.ID)
|
||||||
|
|
||||||
// Get all archived projects
|
// Get all archived projects
|
||||||
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/projects/get_archived", form)
|
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/projects/get_archived", form, bearerHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -616,9 +630,9 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||||||
log.Debugf("[Todoist Migration] Got %d archived projects for user %d", len(archivedProjects), u.ID)
|
log.Debugf("[Todoist Migration] Got %d archived projects for user %d", len(archivedProjects), u.ID)
|
||||||
log.Debugf("[Todoist Migration] Getting data for archived projects for user %d", u.ID)
|
log.Debugf("[Todoist Migration] Getting data for archived projects for user %d", u.ID)
|
||||||
|
|
||||||
// Project data is not included in the regular sync for archived projects so we need to get all of those by hand
|
// Project data is not included in the regular sync for archived projects, so we need to get all of those by hand
|
||||||
for _, p := range archivedProjects {
|
for _, p := range archivedProjects {
|
||||||
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/projects/get_data?project_id="+p.ID, form)
|
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/projects/get_data?project_id="+p.ID, form, bearerHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user