add data export to cli
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
clis "github.com/mayswind/lab/pkg/cli"
|
||||
"github.com/mayswind/lab/pkg/log"
|
||||
"github.com/mayswind/lab/pkg/utils"
|
||||
)
|
||||
|
||||
// UserData represents the data command
|
||||
@@ -24,6 +27,23 @@ var UserData = &cli.Command{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "export",
|
||||
Usage: "Export user all transactions to csv file",
|
||||
Action: exportUserTransaction,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "username",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Specific user name",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "file",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "Specific exported file path (e.g. transaction.csv)",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -55,3 +75,53 @@ func checkUserTransactionAndAccount(c *cli.Context) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func exportUserTransaction(c *cli.Context) error {
|
||||
_, err := initializeSystem(c)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userName := c.String("username")
|
||||
uid, err := clis.UserData.GetUserIdByUsername(c, userName)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.exportUserTransaction] error occurs when getting user id by user name")
|
||||
return err
|
||||
}
|
||||
|
||||
filePath := c.String("file")
|
||||
|
||||
if filePath == "" {
|
||||
log.BootErrorf("[user_data.exportUserTransaction] export file path is not specified")
|
||||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
fileExists, err := utils.IsExists(filePath)
|
||||
|
||||
if fileExists {
|
||||
log.BootErrorf("[user_data.exportUserTransaction] specified file path already exists")
|
||||
return os.ErrExist
|
||||
}
|
||||
|
||||
log.BootInfof("[user_data.exportUserTransaction] starting exporting user \"%s\" data", userName)
|
||||
|
||||
content, err := clis.UserData.ExportTransaction(c, uid)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.exportUserTransaction] error occurs when exporting user data")
|
||||
return err
|
||||
}
|
||||
|
||||
err = utils.WriteFile(filePath, content)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.exportUserTransaction] failed to write to %s", filePath)
|
||||
return err
|
||||
}
|
||||
|
||||
log.BootInfof("[user_data.exportUserTransaction] user transactions have been exported to %s", filePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,15 +4,18 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/mayswind/lab/pkg/errs"
|
||||
"github.com/mayswind/lab/pkg/exporters"
|
||||
"github.com/mayswind/lab/pkg/log"
|
||||
"github.com/mayswind/lab/pkg/models"
|
||||
"github.com/mayswind/lab/pkg/services"
|
||||
)
|
||||
|
||||
const pageCountForGettingTransactions = 1000
|
||||
const pageCountForDataExport = 1000
|
||||
|
||||
// UserDataCli represents user data cli
|
||||
type UserDataCli struct {
|
||||
csvExporter *exporters.CSVFileExporter
|
||||
accounts *services.AccountService
|
||||
transactions *services.TransactionService
|
||||
categories *services.TransactionCategoryService
|
||||
@@ -23,6 +26,7 @@ type UserDataCli struct {
|
||||
// Initialize an user data cli singleton instance
|
||||
var (
|
||||
UserData = &UserDataCli{
|
||||
csvExporter: &exporters.CSVFileExporter{},
|
||||
accounts: services.Accounts,
|
||||
transactions: services.Transactions,
|
||||
users: services.Users,
|
||||
@@ -139,6 +143,32 @@ func (a *UserDataCli) CheckTransactionAndAccount(c *cli.Context, uid int64) (boo
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ExportTransaction returns csv file content according user all transactions
|
||||
func (a *UserDataCli) ExportTransaction(c *cli.Context, uid int64) ([]byte, error) {
|
||||
accountMap, categoryMap, tagMap, tagIndexs, err := a.getUserEssentialData(uid)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.ExportTransaction] failed to get essential data for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allTransactions, err := a.transactions.GetAllTransactions(uid, pageCountForDataExport, true)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.ExportTransaction] failed to all transactions for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := a.csvExporter.GetOutputContent(uid, allTransactions, accountMap, categoryMap, tagMap, tagIndexs)
|
||||
|
||||
if err != nil {
|
||||
log.BootErrorf("[user_data.ExportTransaction] failed to get csv format exported data for \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetUserIdByUsername returns user id by user name
|
||||
func (a *UserDataCli) GetUserIdByUsername(c *cli.Context, username string) (int64, error) {
|
||||
if username == "" {
|
||||
|
||||
+38
-1
@@ -1,6 +1,43 @@
|
||||
package utils
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// IsExists returns whether specified file or directory path exits
|
||||
func IsExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// WriteFile would write file according to specified content
|
||||
func WriteFile(path string, data []byte) error {
|
||||
file, err := os.Create(path)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
n, err := file.Write(data)
|
||||
|
||||
if err == nil && n < len(data) {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// IdentReader returns the original io reader
|
||||
func IdentReader(encoding string, input io.Reader) (io.Reader, error) {
|
||||
|
||||
Reference in New Issue
Block a user