189 lines
4.0 KiB
Go
189 lines
4.0 KiB
Go
// Copyright 2021 Vikunja and contriubtors. All rights reserved.
|
|
//
|
|
// This file is part of Vikunja.
|
|
//
|
|
// Vikunja is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Vikunja is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package models
|
|
|
|
import (
|
|
"archive/zip"
|
|
"code.vikunja.io/api/pkg/config"
|
|
"code.vikunja.io/api/pkg/db"
|
|
"code.vikunja.io/api/pkg/modules/dump"
|
|
"code.vikunja.io/api/pkg/user"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
"xorm.io/xorm"
|
|
)
|
|
|
|
func ExportUserData(u *user.User) (err error) {
|
|
exportDir := config.ServiceRootpath.GetString() + "/files/user-export-tmp/"
|
|
err = os.MkdirAll(exportDir, 0700)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Open zip
|
|
dumpFile, err := os.Create(exportDir + strconv.FormatInt(u.ID, 64) + "_" + time.Now().Format("2006-01-02_15-03-05") + ".zip")
|
|
if err != nil {
|
|
return fmt.Errorf("error opening dump file: %s", err)
|
|
}
|
|
defer dumpFile.Close()
|
|
|
|
dumpWriter := zip.NewWriter(dumpFile)
|
|
defer dumpWriter.Close()
|
|
|
|
// Get the data
|
|
s := db.NewSession()
|
|
defer s.Close()
|
|
|
|
err = exportListsAndTasks(s, u, dumpWriter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Task attachment files
|
|
err = exportTaskAttachments(s, u, dumpWriter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Saved filters
|
|
err = exportSavedFilters(s, u, dumpWriter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Subscription Status
|
|
// Background files
|
|
|
|
// Pack it in a zip file and save it
|
|
|
|
// Send a notification
|
|
|
|
return nil
|
|
}
|
|
|
|
func exportListsAndTasks(s *xorm.Session, u *user.User, wr *zip.Writer) (err error) {
|
|
namespaces := make(map[int64]*NamespaceWithLists)
|
|
_, err = getNamespacesWithLists(s, &namespaces, "", true, 0, -1, u.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
namespaceIDs, _ := getNamespaceOwnerIDs(namespaces)
|
|
|
|
if len(namespaceIDs) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Get all lists
|
|
lists, err := getListsForNamespaces(s, namespaceIDs, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tasks, _, _, err := getTasksForLists(s, lists, u, &taskOptions{
|
|
page: 0,
|
|
perPage: -1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
listMap := make(map[int64]*List)
|
|
listIDs := []int64{}
|
|
for _, n := range namespaces {
|
|
for _, l := range n.Lists {
|
|
listMap[l.ID] = l
|
|
listIDs = append(listIDs, l.ID)
|
|
}
|
|
}
|
|
|
|
for _, t := range tasks {
|
|
listMap[t.ListID].Tasks = append(listMap[t.ListID].Tasks, t)
|
|
}
|
|
|
|
buckets := []*Bucket{}
|
|
err = s.In("list_id", listIDs).Find(&buckets)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, b := range buckets {
|
|
listMap[b.ListID].Buckets = append(listMap[b.ListID].Buckets, b)
|
|
}
|
|
|
|
data, err := json.Marshal(namespaces)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return dump.WriteBytesToZip("data.json", data, wr)
|
|
}
|
|
|
|
func exportTaskAttachments(s *xorm.Session, u *user.User, wr *zip.Writer) (err error) {
|
|
lists, _, _, err := getRawListsForUser(
|
|
s,
|
|
&listOptions{
|
|
user: u,
|
|
page: -1,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tasks, _, _, err := getRawTasksForLists(s, lists, u, &taskOptions{page: -1})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
taskIDs := []int64{}
|
|
for _, t := range tasks {
|
|
taskIDs = append(taskIDs, t.ID)
|
|
}
|
|
|
|
tas, err := getTaskAttachmentsByTaskIDs(s, taskIDs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
files := make(map[int64]io.ReadCloser)
|
|
for _, ta := range tas {
|
|
if err := ta.File.LoadFileByID(); err != nil {
|
|
return err
|
|
}
|
|
files[ta.FileID] = ta.File.File
|
|
}
|
|
|
|
return dump.WriteFilesToZip(files, wr)
|
|
}
|
|
|
|
func exportSavedFilters(s *xorm.Session, u *user.User, wr *zip.Writer) (err error) {
|
|
filters, err := getSavedFilters(s, u)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
data, err := json.Marshal(filters)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return dump.WriteBytesToZip("filters.json", data, wr)
|
|
}
|