2022-06-09 19:58:16 +08:00
|
|
|
|
// Copyright (c) 2020 tickstep.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
package command
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2022-06-10 13:55:00 +08:00
|
|
|
|
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
2022-06-09 19:58:16 +08:00
|
|
|
|
"github.com/tickstep/aliyunpan/cmder"
|
|
|
|
|
"github.com/tickstep/aliyunpan/internal/config"
|
|
|
|
|
"github.com/tickstep/aliyunpan/internal/syncdrive"
|
|
|
|
|
"github.com/tickstep/aliyunpan/internal/utils"
|
2022-06-10 14:36:52 +08:00
|
|
|
|
"github.com/tickstep/library-go/converter"
|
2022-06-09 19:58:16 +08:00
|
|
|
|
"github.com/tickstep/library-go/logger"
|
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func CmdSync() cli.Command {
|
|
|
|
|
return cli.Command{
|
|
|
|
|
Name: "sync",
|
|
|
|
|
Usage: "同步备份功能(Beta)",
|
|
|
|
|
UsageText: cmder.App().Name + " sync",
|
|
|
|
|
Description: `
|
|
|
|
|
备份功能。指定本地目录和对应的一个网盘目录,以备份文件。
|
2022-06-10 22:39:54 +08:00
|
|
|
|
备份功能支持以下三种模式:
|
2022-06-09 20:05:30 +08:00
|
|
|
|
1. upload
|
|
|
|
|
备份本地文件,即上传本地文件到网盘,始终保持本地文件有一个完整的备份在网盘
|
|
|
|
|
2. download
|
|
|
|
|
备份云盘文件,即下载网盘文件到本地,始终保持网盘的文件有一个完整的备份在本地
|
|
|
|
|
3. sync
|
|
|
|
|
双向备份,保持网盘文件和本地文件严格一致
|
2022-06-09 19:58:16 +08:00
|
|
|
|
|
2022-06-10 22:39:54 +08:00
|
|
|
|
请输入以下命令查看如何配置和启动:
|
|
|
|
|
aliyunpan sync start -h
|
2022-06-09 19:58:16 +08:00
|
|
|
|
`,
|
|
|
|
|
Category: "阿里云盘",
|
|
|
|
|
Before: cmder.ReloadConfigFunc,
|
|
|
|
|
Action: func(c *cli.Context) error {
|
2022-06-10 22:39:54 +08:00
|
|
|
|
cli.ShowCommandHelp(c, c.Command.Name)
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
Subcommands: []cli.Command{
|
|
|
|
|
{
|
|
|
|
|
Name: "start",
|
|
|
|
|
Usage: "启动sync同步备份任务",
|
|
|
|
|
UsageText: cmder.App().Name + " sync start [arguments...]",
|
|
|
|
|
Description: `
|
|
|
|
|
使用备份配置文件启动sync同步备份任务。备份配置文件必须存在,不然启动失败。
|
|
|
|
|
同步备份任务的配置文件保存在:(配置目录)/sync_drive/sync_drive_config.json,样例如下:
|
|
|
|
|
{
|
|
|
|
|
"configVer": "1.0",
|
|
|
|
|
"syncTaskList": [
|
|
|
|
|
{
|
|
|
|
|
"name": "设计文档备份",
|
2022-06-12 08:03:14 +08:00
|
|
|
|
"localFolderPath": "D:/tickstep/Documents/设计文档",
|
2022-06-10 22:39:54 +08:00
|
|
|
|
"panFolderPath": "/sync_drive/我的文档",
|
|
|
|
|
"mode": "upload"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
相关字段说明如下:
|
|
|
|
|
name - 任务名称
|
|
|
|
|
localFolderPath - 本地目录
|
|
|
|
|
panFolderPath - 网盘目录
|
2022-06-12 08:03:14 +08:00
|
|
|
|
mode - 模式,支持三种: upload(备份本地文件到云盘),download(备份云盘文件到本地),sync(双向同步备份)
|
2022-06-10 13:55:00 +08:00
|
|
|
|
|
2022-06-10 22:39:54 +08:00
|
|
|
|
例子:
|
|
|
|
|
1. 查看帮助
|
|
|
|
|
aliyunpan sync start -h
|
2022-06-10 13:55:00 +08:00
|
|
|
|
|
2022-06-10 22:39:54 +08:00
|
|
|
|
2. 使用默认配置启动同步备份服务
|
|
|
|
|
aliyunpan sync start
|
2022-06-10 13:55:00 +08:00
|
|
|
|
|
2022-06-12 08:03:14 +08:00
|
|
|
|
3. 启动sync服务,并配置下载并发为2,上传并发为1,下载分片大小为256KB,上传分片大小为1MB
|
|
|
|
|
aliyunpan sync start -dp 2 -up 1 -dbs 256 -ubs 1024
|
2022-06-10 13:55:00 +08:00
|
|
|
|
|
2022-06-10 22:39:54 +08:00
|
|
|
|
`,
|
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
|
if config.Config.ActiveUser() == nil {
|
|
|
|
|
fmt.Println("未登录账号")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
dp := c.Int("dp")
|
|
|
|
|
if dp == 0 {
|
|
|
|
|
dp = config.Config.MaxDownloadParallel
|
|
|
|
|
}
|
|
|
|
|
if dp == 0 {
|
|
|
|
|
dp = 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
up := c.Int("up")
|
|
|
|
|
if up == 0 {
|
|
|
|
|
up = config.Config.MaxUploadParallel
|
|
|
|
|
}
|
|
|
|
|
if up == 0 {
|
|
|
|
|
up = 2
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-12 08:03:14 +08:00
|
|
|
|
downloadBlockSize := int64(c.Int("dbs") * 1024)
|
|
|
|
|
if downloadBlockSize == 0 {
|
|
|
|
|
downloadBlockSize = int64(config.Config.CacheSize)
|
|
|
|
|
}
|
2022-06-10 22:39:54 +08:00
|
|
|
|
if downloadBlockSize == 0 {
|
|
|
|
|
downloadBlockSize = int64(256 * 1024)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uploadBlockSize := int64(c.Int("ubs") * 1024)
|
|
|
|
|
if uploadBlockSize == 0 {
|
|
|
|
|
uploadBlockSize = aliyunpan.DefaultChunkSize
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RunSync(dp, up, downloadBlockSize, uploadBlockSize)
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
|
cli.IntFlag{
|
|
|
|
|
Name: "dp",
|
|
|
|
|
Usage: "download parallel, 下载并发数量,即可以同时并发下载多少个文件。0代表跟从配置文件设置(取值范围:1 ~ 10)",
|
|
|
|
|
Value: 0,
|
|
|
|
|
},
|
|
|
|
|
cli.IntFlag{
|
|
|
|
|
Name: "up",
|
|
|
|
|
Usage: "upload parallel, 上传并发数量,即可以同时并发上传多少个文件。0代表跟从配置文件设置(取值范围:1 ~ 10)",
|
|
|
|
|
Value: 0,
|
|
|
|
|
},
|
2022-06-12 08:03:14 +08:00
|
|
|
|
cli.IntFlag{
|
|
|
|
|
Name: "dbs",
|
|
|
|
|
Usage: "download block size,下载分片大小,单位KB。推荐值:1 ~ 256",
|
|
|
|
|
Value: 256,
|
|
|
|
|
},
|
2022-06-10 22:39:54 +08:00
|
|
|
|
cli.IntFlag{
|
|
|
|
|
Name: "ubs",
|
|
|
|
|
Usage: "upload block size,上传分片大小,单位KB。推荐值:1024 ~ 10240",
|
|
|
|
|
Value: 10240,
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-06-09 19:58:16 +08:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-10 13:55:00 +08:00
|
|
|
|
func RunSync(fileDownloadParallel, fileUploadParallel int, downloadBlockSize, uploadBlockSize int64) {
|
2022-06-10 14:36:52 +08:00
|
|
|
|
useInternalUrl := config.Config.TransferUrlType == 2
|
2022-06-09 19:58:16 +08:00
|
|
|
|
activeUser := GetActiveUser()
|
|
|
|
|
panClient := activeUser.PanClient()
|
|
|
|
|
|
|
|
|
|
// pan token expired checker
|
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
time.Sleep(time.Duration(1) * time.Minute)
|
|
|
|
|
if RefreshTokenInNeed(activeUser) {
|
|
|
|
|
logger.Verboseln("update access token for sync task")
|
|
|
|
|
panClient.UpdateToken(activeUser.WebToken)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
syncFolderRootPath := config.GetSyncDriveDir()
|
|
|
|
|
if b, e := utils.PathExists(syncFolderRootPath); e == nil {
|
|
|
|
|
if !b {
|
|
|
|
|
os.MkdirAll(syncFolderRootPath, 0600)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Println("启动同步备份进程")
|
2022-06-12 08:03:14 +08:00
|
|
|
|
typeUrlStr := "默认链接"
|
2022-06-10 14:36:52 +08:00
|
|
|
|
if useInternalUrl {
|
|
|
|
|
typeUrlStr = "阿里ECS内部链接"
|
|
|
|
|
}
|
2022-06-10 13:55:00 +08:00
|
|
|
|
syncMgr := syncdrive.NewSyncTaskManager(activeUser.DriveList.GetFileDriveId(), panClient, syncFolderRootPath,
|
2022-06-10 14:36:52 +08:00
|
|
|
|
fileDownloadParallel, fileUploadParallel, downloadBlockSize, uploadBlockSize, useInternalUrl)
|
2022-06-10 22:48:29 +08:00
|
|
|
|
fmt.Printf("备份配置文件:%s\n链接类型:%s\n下载并发:%d\n上传并发:%d\n下载分片大小:%s\n上传分片大小:%s\n",
|
|
|
|
|
syncMgr.ConfigFilePath(), typeUrlStr, fileDownloadParallel, fileUploadParallel, converter.ConvertFileSize(downloadBlockSize, 2),
|
|
|
|
|
converter.ConvertFileSize(uploadBlockSize, 2))
|
2022-06-09 19:58:16 +08:00
|
|
|
|
if _, e := syncMgr.Start(); e != nil {
|
|
|
|
|
fmt.Println("启动任务失败:", e)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c := ""
|
|
|
|
|
for strings.ToLower(c) != "y" {
|
|
|
|
|
fmt.Print("本命令不会退出,如需要结束同步备份进程请输入y,然后按Enter键进行停止:")
|
|
|
|
|
fmt.Scan(&c)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("正在停止同步备份任务,请稍等...")
|
|
|
|
|
syncMgr.Stop()
|
|
|
|
|
}
|