Add docs for file based migrator
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
parent
273b0654cd
commit
f708a39bf1
|
@ -31,10 +31,10 @@ menu:
|
||||||
url: https://vikunja.io/en/
|
url: https://vikunja.io/en/
|
||||||
weight: 10
|
weight: 10
|
||||||
- name: Features
|
- name: Features
|
||||||
url: https://vikunja.io/en/features
|
url: https://vikunja.io/features
|
||||||
weight: 20
|
weight: 20
|
||||||
- name: Download
|
- name: Download
|
||||||
url: https://vikunja.io/en/download
|
url: https://vikunja.io/download
|
||||||
weight: 30
|
weight: 30
|
||||||
- name: Docs
|
- name: Docs
|
||||||
url: https://vikunja.io/docs
|
url: https://vikunja.io/docs
|
||||||
|
|
|
@ -14,7 +14,17 @@ It is possible to migrate data from other to-do services to Vikunja.
|
||||||
To make this easier, we have put together a few helpers which are documented on this page.
|
To make this easier, we have put together a few helpers which are documented on this page.
|
||||||
|
|
||||||
In general, each migrator implements a migrator interface which is then called from a client.
|
In general, each migrator implements a migrator interface which is then called from a client.
|
||||||
The interface makes it possible to use helper methods which handle http an focus only on the implementation of the migrator itself.
|
The interface makes it possible to use helper methods which handle http and focus only on the implementation of the migrator itself.
|
||||||
|
|
||||||
|
There are two ways of migrating data from another service:
|
||||||
|
1. Through the auth-based flow where the user gives you access to their data at the third-party service through an
|
||||||
|
oauth flow. You can then call the service's api on behalf of your user to get all the data.
|
||||||
|
The Todoist, Trello and Microsoft To-Do Migrators use this pattern.
|
||||||
|
2. A file migration where the user uploads a file obtained from some third-party service. In your migrator, you need
|
||||||
|
to parse the file and create the lists, tasks etc.
|
||||||
|
The Vikunja File Import uses this pattern.
|
||||||
|
|
||||||
|
To differentiate the two, there are two different interfaces you must implement.
|
||||||
|
|
||||||
{{< table_of_contents >}}
|
{{< table_of_contents >}}
|
||||||
|
|
||||||
|
@ -23,13 +33,16 @@ The interface makes it possible to use helper methods which handle http an focus
|
||||||
All migrator implementations live in their own package in `pkg/modules/migration/<name-of-the-service>`.
|
All migrator implementations live in their own package in `pkg/modules/migration/<name-of-the-service>`.
|
||||||
When creating a new migrator, you should place all related code inside that module.
|
When creating a new migrator, you should place all related code inside that module.
|
||||||
|
|
||||||
## Migrator interface
|
## Migrator Interface
|
||||||
|
|
||||||
The migrator interface is defined as follows:
|
The migrator interface is defined as follows:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Migrator is the basic migrator interface which is shared among all migrators
|
// Migrator is the basic migrator interface which is shared among all migrators
|
||||||
type Migrator interface {
|
type Migrator interface {
|
||||||
|
// Name holds the name of the migration.
|
||||||
|
// This is used to show the name to users and to keep track of users who already migrated.
|
||||||
|
Name() string
|
||||||
// Migrate is the interface used to migrate a user's tasks from another platform to vikunja.
|
// Migrate is the interface used to migrate a user's tasks from another platform to vikunja.
|
||||||
// The user object is the user who's tasks will be migrated.
|
// The user object is the user who's tasks will be migrated.
|
||||||
Migrate(user *models.User) error
|
Migrate(user *models.User) error
|
||||||
|
@ -37,9 +50,20 @@ type Migrator interface {
|
||||||
// The use case for this are Oauth flows, where the server token should remain hidden and not
|
// The use case for this are Oauth flows, where the server token should remain hidden and not
|
||||||
// known to the frontend.
|
// known to the frontend.
|
||||||
AuthURL() string
|
AuthURL() string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Migrator Interface
|
||||||
|
|
||||||
|
```go
|
||||||
|
// FileMigrator handles importing Vikunja data from a file. The implementation of it determines the format.
|
||||||
|
type FileMigrator interface {
|
||||||
// Name holds the name of the migration.
|
// Name holds the name of the migration.
|
||||||
// This is used to show the name to users and to keep track of users who already migrated.
|
// This is used to show the name to users and to keep track of users who already migrated.
|
||||||
Name() string
|
Name() string
|
||||||
|
// Migrate is the interface used to migrate a user's tasks, list and other things from a file to vikunja.
|
||||||
|
// The user object is the user who's tasks will be migrated.
|
||||||
|
Migrate(user *user.User, file io.ReaderAt, size int64) error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -54,15 +78,26 @@ authUrl, Status and Migrate methods.
|
||||||
```go
|
```go
|
||||||
// This is an example for the Wunderlist migrator
|
// This is an example for the Wunderlist migrator
|
||||||
if config.MigrationWunderlistEnable.GetBool() {
|
if config.MigrationWunderlistEnable.GetBool() {
|
||||||
wunderlistMigrationHandler := &migrationHandler.MigrationWeb{
|
wunderlistMigrationHandler := &migrationHandler.MigrationWeb{
|
||||||
MigrationStruct: func() migration.Migrator {
|
MigrationStruct: func() migration.Migrator {
|
||||||
return &wunderlist.Migration{}
|
return &wunderlist.Migration{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
wunderlistMigrationHandler.RegisterRoutes(m)
|
wunderlistMigrationHandler.RegisterRoutes(m)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
And for the file migrator:
|
||||||
|
|
||||||
|
```go
|
||||||
|
vikunjaFileMigrationHandler := &migrationHandler.FileMigratorWeb{
|
||||||
|
MigrationStruct: func() migration.FileMigrator {
|
||||||
|
return &vikunja_file.FileMigrator{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
vikunjaFileMigrationHandler.RegisterRoutes(m)
|
||||||
|
```
|
||||||
|
|
||||||
You should also document the routes with [swagger annotations]({{< ref "swagger-docs.md" >}}).
|
You should also document the routes with [swagger annotations]({{< ref "swagger-docs.md" >}}).
|
||||||
|
|
||||||
## Insertion helper method
|
## Insertion helper method
|
||||||
|
@ -70,7 +105,8 @@ You should also document the routes with [swagger annotations]({{< ref "swagger-
|
||||||
There is a method available in the `migration` package which takes a fully nested Vikunja structure and creates it with all relations.
|
There is a method available in the `migration` package which takes a fully nested Vikunja structure and creates it with all relations.
|
||||||
This means you start by adding a namespace, then add lists inside of that namespace, then tasks in the lists and so on.
|
This means you start by adding a namespace, then add lists inside of that namespace, then tasks in the lists and so on.
|
||||||
|
|
||||||
The root structure must be present as `[]*models.NamespaceWithLists`.
|
The root structure must be present as `[]*models.NamespaceWithListsAndTasks`. It allows to represent all of Vikunja's
|
||||||
|
hierachie as a single data structure.
|
||||||
|
|
||||||
Then call the method like so:
|
Then call the method like so:
|
||||||
|
|
||||||
|
@ -85,14 +121,16 @@ err = migration.InsertFromStructure(fullVikunjaHierachie, user)
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
You should add at least an option to enable or disable the migration.
|
If your migrator is an oauth-based one, you should add at least an option to enable or disable it.
|
||||||
Chances are, you'll need some more options for things like client ID and secret
|
Chances are, you'll need some more options for things like client ID and secret
|
||||||
(if the other service uses oAuth as an authentication flow).
|
(if the other service uses oAuth as an authentication flow).
|
||||||
|
|
||||||
The easiest way to implement an on/off switch is to check whether your migration service is enabled or not when
|
The easiest way to implement an on/off switch is to check whether your migration service is enabled or not when
|
||||||
registering the routes, and then simply don't registering the routes in the case it is disabled.
|
registering the routes, and then simply don't registering the routes in case it is disabled.
|
||||||
|
|
||||||
|
File based migrators can always be enabled.
|
||||||
|
|
||||||
### Making the migrator public in `/info`
|
### Making the migrator public in `/info`
|
||||||
|
|
||||||
You should make your migrator available in the `/info` endpoint so that frontends can display options to enable them or not.
|
You should make your migrator available in the `/info` endpoint so that frontends can display options to enable them or not.
|
||||||
To do this, add an entry to `pkg/routes/api/v1/info.go`.
|
To do this, add an entry to the `AvailableMigrators` field in `pkg/routes/api/v1/info.go`.
|
||||||
|
|
Loading…
Reference in New Issue