mirror of
https://gitee.com/zhangsken/aliyunpan.git
synced 2026-10-16 10:29:42 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c81855f9c2 | |||
| 65b7f28aa6 | |||
| 8afdb8f701 | |||
| ead6ecc218 | |||
| a42f14f013 | |||
| 54fff27fbe | |||
| b0a1ea8591 | |||
| 1b78dff61e | |||
| f838ebfe24 | |||
| 7f5e19812e | |||
| 6a7da9f180 | |||
| 06184249d0 | |||
| b983d4c335 |
@@ -1,5 +1,5 @@
|
||||
# 关于
|
||||
阿里云盘CLI。仿 Linux shell 文件处理命令的阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能。
|
||||
阿里云盘CLI。仿 Linux shell 文件处理命令的阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能,支持相册批量下载。
|
||||
|
||||
# 特色
|
||||
1. 多平台支持, 支持 Windows, macOS, linux(x86/x64/arm), android, iOS 等
|
||||
@@ -11,6 +11,7 @@
|
||||
7. 命令和文件路径输入支持Tab键自动补全,路径支持通配符匹配模式
|
||||
8. 支持阿里云ECS环境下使用内网链接上传/下载,速度更快(只支持阿里经典网络,最高可达100MB/s),还可以节省公网带宽流量(配置transfer_url_type=2即可)
|
||||
9. 支持[JavaScript插件](docs/manual.md#JavaScript插件),你可以按照自己的需要定制上传/下载中关键步骤的行为,最大程度满足自己的个性化需求
|
||||
10. 支持个人相册的相关操作,支持批量下载相册所有照片、视频文件到本地
|
||||
|
||||
# 目录
|
||||
- [关于](#关于)
|
||||
@@ -30,6 +31,7 @@
|
||||
- [启动程序](#启动程序)
|
||||
- [查看帮助](#查看帮助)
|
||||
- [登录](#登录)
|
||||
- [切换网盘](#切换网盘)
|
||||
- [查看文件列表](#查看文件列表)
|
||||
- [下载文件](#下载文件)
|
||||
- [上传文件](#上传文件)
|
||||
@@ -59,9 +61,9 @@
|
||||
|
||||
参考例子:
|
||||
```shell
|
||||
wget https://github.com/tickstep/aliyunpan/releases/download/v0.2.8/aliyunpan-v0.2.8-linux-amd64.zip
|
||||
unzip aliyunpan-v0.2.8-linux-amd64.zip
|
||||
cd aliyunpan-v0.2.8-linux-amd64
|
||||
wget https://github.com/tickstep/aliyunpan/releases/download/v0.2.9/aliyunpan-v0.2.9-linux-amd64.zip
|
||||
unzip aliyunpan-v0.2.9-linux-amd64.zip
|
||||
cd aliyunpan-v0.2.9-linux-amd64
|
||||
./aliyunpan
|
||||
```
|
||||
|
||||
@@ -112,7 +114,7 @@ winget install tickstep.aliyunpan --silent
|
||||
2. 备份云盘文件,即下载网盘文件到本地,始终保持网盘的文件有一个完整的备份在本地
|
||||
3. 双向备份,保持网盘文件和本地文件严格一致
|
||||
```
|
||||
docker run -d --name=aliyunpan-sync --restart=always -v "<your local dir>:/home/app/data" -e TZ="Asia/Shanghai" -e ALIYUNPAN_REFRESH_TOKEN="<your refreshToken>" -e ALIYUNPAN_PAN_DIR="<your drive pan dir>" -e ALIYUNPAN_SYNC_MODE="upload" -e ALIYUNPAN_TASK_STEP="sync" tickstep/aliyunpan-sync:v0.2.8
|
||||
docker run -d --name=aliyunpan-sync --restart=always -v "<your local dir>:/home/app/data" -e TZ="Asia/Shanghai" -e ALIYUNPAN_REFRESH_TOKEN="<your refreshToken>" -e ALIYUNPAN_PAN_DIR="<your drive pan dir>" -e ALIYUNPAN_SYNC_MODE="upload" -e ALIYUNPAN_TASK_STEP="sync" tickstep/aliyunpan-sync:v0.2.9
|
||||
|
||||
|
||||
<your local dir>:本地目录绝对路径,例如:/tickstep/Documents/设计文档
|
||||
@@ -193,6 +195,20 @@ aliyunpan > login -RefreshToken=32994cd2c43...4d505fa79
|
||||
aliyunpan:/ tickstep$
|
||||
```
|
||||
|
||||
### 切换网盘
|
||||
支持切换备份盘、资源库,默认工作在备份盘下。
|
||||
```shell
|
||||
aliyunpan:/ tickstep(备份盘)$ drive
|
||||
# DRIVE ID 网盘名称
|
||||
1 11519221 备份盘
|
||||
2 1311893110 资源库
|
||||
3 61104421 相册
|
||||
|
||||
输入要切换的网盘 # 值 > 2
|
||||
切换到网盘:资源库
|
||||
aliyunpan:/ tickstep(资源库)$
|
||||
```
|
||||
|
||||
### 查看文件列表
|
||||
```shell
|
||||
aliyunpan:/ tickstep$ ls
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<assemblyIdentity version="0.2.8.0" processorArchitecture="*" name="com.tickstep.aliyunpan" type="win32"/>
|
||||
<assemblyIdentity version="0.2.9.0" processorArchitecture="*" name="com.tickstep.aliyunpan" type="win32"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
|
||||
@@ -239,6 +239,7 @@ aliyunpan d <网盘文件或目录的路径1> <文件或目录2> <文件或目
|
||||
### 可选参数
|
||||
```
|
||||
--ow overwrite, 覆盖已存在的文件
|
||||
--skip skip same name, 跳过已存在的同名文件,即使文件内容不一致(不检查SHA1)
|
||||
--status 输出所有线程的工作状态
|
||||
--save 将下载的文件直接保存到当前工作目录
|
||||
--saveto value 将下载的文件直接保存到指定的目录
|
||||
|
||||
@@ -13,9 +13,9 @@ require (
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190618033246-cc27d85e17ce
|
||||
github.com/peterh/liner v1.2.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/tickstep/aliyunpan-api v0.1.7
|
||||
github.com/tickstep/aliyunpan-api v0.1.8
|
||||
github.com/tickstep/bolt v1.3.4
|
||||
github.com/tickstep/library-go v0.1.0
|
||||
github.com/tickstep/library-go v0.1.1
|
||||
github.com/urfave/cli v1.21.1-0.20190817182405-23c83030263f
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
|
||||
@@ -98,12 +98,13 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tickstep/aliyunpan-api v0.1.7 h1:YaKDT7AnYR7f0YM8zC4QE7sL6xljBFRz7BOjkIaGfNY=
|
||||
github.com/tickstep/aliyunpan-api v0.1.7/go.mod h1:SN+N5Vh3lLq3dVimlxKxviCl50gLGXZO96nHHc3qd2o=
|
||||
github.com/tickstep/aliyunpan-api v0.1.8 h1:heK04T2F1K5eDSHDqHJ2yHA6RSBqyN/4yqYjHClbJvI=
|
||||
github.com/tickstep/aliyunpan-api v0.1.8/go.mod h1:SN+N5Vh3lLq3dVimlxKxviCl50gLGXZO96nHHc3qd2o=
|
||||
github.com/tickstep/bolt v1.3.4 h1:UN1txRsauOfR8a5mUWm5So0ng233PsIMVR5/+3WowCE=
|
||||
github.com/tickstep/bolt v1.3.4/go.mod h1:Y24RwCywbOsKAyHiVcJ4K2QQfED+q67x7PEOH9OG7Q4=
|
||||
github.com/tickstep/library-go v0.1.0 h1:lzz6wpYCeliSzmVISa7rp9bGB4r+uIa9/VUTtk87DFU=
|
||||
github.com/tickstep/library-go v0.1.0/go.mod h1:uAHeNOIpoywCzlaeLrWmmRSupn03m9kJVZKOEmuarmA=
|
||||
github.com/tickstep/library-go v0.1.1 h1:xPAyddCJkZy5S3qUxCg0hoEG9PR8/rdIQiLMrt2OtWI=
|
||||
github.com/tickstep/library-go v0.1.1/go.mod h1:uAHeNOIpoywCzlaeLrWmmRSupn03m9kJVZKOEmuarmA=
|
||||
github.com/urfave/cli v1.21.1-0.20190817182405-23c83030263f h1:xKDKjIsL76VUyHcA0G4Qe1cIAUB/nrq6Pt8D411bd1g=
|
||||
github.com/urfave/cli v1.21.1-0.20190817182405-23c83030263f/go.mod h1:qXyCeJubPqsgeiLd3kvHOGHHSrQcNdjZ2ScXIcVZK/I=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// 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
|
||||
// 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,
|
||||
@@ -226,6 +226,9 @@ func CmdConfig() cli.Command {
|
||||
if c.IsSet("local_addrs") {
|
||||
config.Config.SetLocalAddrs(c.String("local_addrs"))
|
||||
}
|
||||
if c.IsSet("ip_type") {
|
||||
config.Config.SetPreferIPType(c.String("ip_type"))
|
||||
}
|
||||
if c.IsSet("file_record_config") {
|
||||
config.Config.SetFileRecorderConfig(c.String("file_record_config"))
|
||||
}
|
||||
@@ -282,6 +285,10 @@ func CmdConfig() cli.Command {
|
||||
Name: "local_addrs",
|
||||
Usage: "设置本地网卡地址, 多个地址用逗号隔开",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ip_type",
|
||||
Usage: "设置域名解析IP优先类型",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "file_record_config",
|
||||
Usage: "设置是否开启上传、下载、同步文件的结果记录功能",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// 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
|
||||
// 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,
|
||||
@@ -75,12 +75,9 @@ func CmdDownload() cli.Command {
|
||||
UsageText: cmder.App().Name + " download <文件/目录路径1> <文件/目录2> <文件/目录3> ...",
|
||||
Description: `
|
||||
下载的文件默认保存到, 程序所在目录的 download/ 目录。支持软链接文件,包括Linux/macOS(ln命令)和Windows(mklink命令)创建的符号链接文件。
|
||||
通过 aliyunpan config set -savedir <savedir>, 自定义保存的目录。
|
||||
支持多个文件或目录下载.
|
||||
自动跳过下载重名的文件!
|
||||
通过 aliyunpan config set -savedir <savedir>, 自定义保存的目录。支持多个文件或目录下载,支持自动跳过下载重名的文件!
|
||||
|
||||
示例:
|
||||
|
||||
设置保存目录, 保存到 D:\Downloads
|
||||
注意区别反斜杠 "\" 和 斜杠 "/" !!!
|
||||
aliyunpan config set -savedir D:\\Downloads
|
||||
@@ -302,7 +299,7 @@ func RunDownload(paths []string, options *DownloadOptions) {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n[*] 注意:由于阿里云盘接口的限制,当前不支持>100M单个文件的下载。")
|
||||
fmt.Printf("\n[0] 当前文件下载最大并发量为: %d, 下载缓存为: %s\n\n", options.Parallel, converter.ConvertFileSize(int64(cfg.CacheSize), 2))
|
||||
|
||||
var (
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// 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
|
||||
// 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,
|
||||
@@ -117,10 +117,9 @@ func CmdLogout() cli.Command {
|
||||
}
|
||||
|
||||
// 云端注销登录
|
||||
if _, e := activeUser.PanClient().DeviceLogout(); e != nil {
|
||||
fmt.Printf("登出设备失败,请稍后重试: %s\n", e.String())
|
||||
return nil
|
||||
}
|
||||
//if _, e := activeUser.PanClient().DeviceLogout(); e != nil {
|
||||
// fmt.Printf("登出设备失败,请手动在网页端进行登出: %s\n", e.String())
|
||||
//}
|
||||
|
||||
// 删除用户信息
|
||||
deletedUser, err := config.Config.DeleteUser(activeUser.UserId)
|
||||
|
||||
+26
-34
@@ -4,7 +4,7 @@
|
||||
// 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
|
||||
// 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,
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CmdRecycle() cli.Command {
|
||||
@@ -218,39 +219,30 @@ func RunRecycleDelete(driveId string, fidStrList ...string) {
|
||||
func RunRecycleClear(driveId string) {
|
||||
panClient := GetActivePanClient()
|
||||
|
||||
for {
|
||||
// get file list
|
||||
fdl, err := panClient.RecycleBinFileListGetAll(&aliyunpan.RecycleBinFileListParam{
|
||||
DriveId: driveId,
|
||||
Limit: 100,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Verboseln(err)
|
||||
break
|
||||
}
|
||||
if fdl == nil || len(fdl) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// delete
|
||||
deleteFileList := []*aliyunpan.FileBatchActionParam{}
|
||||
for _, f := range fdl {
|
||||
deleteFileList = append(deleteFileList, &aliyunpan.FileBatchActionParam{
|
||||
DriveId: driveId,
|
||||
FileId: f.FileId,
|
||||
})
|
||||
}
|
||||
|
||||
if len(deleteFileList) == 0 {
|
||||
logger.Verboseln("没有需要删除的文件")
|
||||
break
|
||||
}
|
||||
|
||||
rbfr, err := panClient.RecycleBinFileDelete(deleteFileList)
|
||||
if rbfr != nil && len(rbfr) > 0 {
|
||||
logger.Verboseln("彻底删除文件成功")
|
||||
}
|
||||
// 提交清空回收站异步任务
|
||||
r, err := panClient.RecycleBinFileClear(&aliyunpan.RecycleBinFileClearParam{
|
||||
DriveId: driveId,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Verboseln(err)
|
||||
fmt.Printf("当前无法清空回收站,请稍后重试\n")
|
||||
}
|
||||
|
||||
fmt.Printf("清空回收站成功\n")
|
||||
for i := 0; i < 10; i++ {
|
||||
ar, err1 := panClient.AsyncTaskQueryStatus(&aliyunpan.AsyncTaskQueryStatusParam{
|
||||
AsyncTaskId: r.AsyncTaskId,
|
||||
})
|
||||
if err1 != nil {
|
||||
logger.Verboseln(err1)
|
||||
time.Sleep(2 * time.Second)
|
||||
continue
|
||||
}
|
||||
if ar.Status == "Succeed" {
|
||||
fmt.Printf("清空回收站成功\n")
|
||||
return
|
||||
} else {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
fmt.Printf("清空回收站失败,请稍后重试\n")
|
||||
}
|
||||
|
||||
+20
-10
@@ -62,6 +62,7 @@ type (
|
||||
NoRapidUpload bool
|
||||
ShowProgress bool
|
||||
IsOverwrite bool // 覆盖已存在的文件,如果同名文件已存在则移到回收站里
|
||||
IsSkipSameName bool // 跳过已存在的文件,即使文件内容不一致(不检查SHA1)
|
||||
DriveId string
|
||||
ExcludeNames []string // 排除的文件名,包括文件夹和文件。即这些文件/文件夹不进行上传,支持正则表达式
|
||||
BlockSize int64 // 分片大小
|
||||
@@ -92,6 +93,10 @@ var UploadFlags = []cli.Flag{
|
||||
Name: "ow",
|
||||
Usage: "overwrite, 覆盖已存在的同名文件,注意已存在的文件会被移到回收站",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip",
|
||||
Usage: "skip same name, 跳过已存在的同名文件,即使文件内容不一致(不检查SHA1)",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "norapid",
|
||||
Usage: "不检测秒传。跳过费时的SHA1计算直接上传",
|
||||
@@ -151,6 +156,9 @@ func CmdUpload() cli.Command {
|
||||
9. 将本地的 C:\Users\Administrator\Video 整个目录上传到网盘 /视频 目录,但是排除所有的 @eadir 文件夹
|
||||
aliyunpan upload -exn "^@eadir$" C:/Users/Administrator/Video /视频
|
||||
|
||||
10. 跳过已存在的同名文件,即使文件内容不一致(不检查SHA1)
|
||||
aliyunpan upload -skip 1.mp4 /视频
|
||||
|
||||
参考:
|
||||
以下是典型的排除特定文件或者文件夹的例子,注意:参数值必须是正则表达式。在正则表达式中,^表示匹配开头,$表示匹配结尾。
|
||||
1)排除@eadir文件或者文件夹:-exn "^@eadir$"
|
||||
@@ -186,16 +194,17 @@ func CmdUpload() cli.Command {
|
||||
//}
|
||||
|
||||
RunUpload(subArgs[:c.NArg()-1], subArgs[c.NArg()-1], &UploadOptions{
|
||||
AllParallel: c.Int("p"), // 多文件上传的时候,允许同时并行上传的文件数量
|
||||
Parallel: 1, // 一个文件同时多少个线程并发上传的数量。阿里云盘只支持单线程按顺序进行文件part数据上传,所以只能是1
|
||||
MaxRetry: c.Int("retry"),
|
||||
MaxTimeoutSec: timeout,
|
||||
NoRapidUpload: c.Bool("norapid"),
|
||||
ShowProgress: !c.Bool("np"),
|
||||
IsOverwrite: c.Bool("ow"),
|
||||
DriveId: parseDriveId(c),
|
||||
ExcludeNames: c.StringSlice("exn"),
|
||||
BlockSize: int64(c.Int("bs") * 1024),
|
||||
AllParallel: c.Int("p"), // 多文件上传的时候,允许同时并行上传的文件数量
|
||||
Parallel: 1, // 一个文件同时多少个线程并发上传的数量。阿里云盘只支持单线程按顺序进行文件part数据上传,所以只能是1
|
||||
MaxRetry: c.Int("retry"),
|
||||
MaxTimeoutSec: timeout,
|
||||
NoRapidUpload: c.Bool("norapid"),
|
||||
ShowProgress: !c.Bool("np"),
|
||||
IsOverwrite: c.Bool("ow"),
|
||||
IsSkipSameName: c.Bool("skip"),
|
||||
DriveId: parseDriveId(c),
|
||||
ExcludeNames: c.StringSlice("exn"),
|
||||
BlockSize: int64(c.Int("bs") * 1024),
|
||||
})
|
||||
|
||||
// 释放文件锁
|
||||
@@ -441,6 +450,7 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
|
||||
UploadStatistic: statistic,
|
||||
ShowProgress: opt.ShowProgress,
|
||||
IsOverwrite: opt.IsOverwrite,
|
||||
IsSkipSameName: opt.IsSkipSameName,
|
||||
UseInternalUrl: opt.UseInternalUrl,
|
||||
GlobalSpeedsStat: globalSpeedsStat,
|
||||
FileRecorder: fileRecorder,
|
||||
|
||||
@@ -99,8 +99,9 @@ type PanConfig struct {
|
||||
|
||||
SaveDir string `json:"saveDir"` // 下载储存路径
|
||||
|
||||
Proxy string `json:"proxy"` // 代理
|
||||
LocalAddrs string `json:"localAddrs"` // 本地网卡地址
|
||||
Proxy string `json:"proxy"` // 代理
|
||||
LocalAddrs string `json:"localAddrs"` // 本地网卡地址
|
||||
PreferIPType string `json:"preferIPType"` // 优先IP类型,IPv4或者IPv6
|
||||
UpdateCheckInfo UpdateCheckInfo `json:"updateCheckInfo"`
|
||||
|
||||
VideoFileExtensions string `json:"videoFileExtensions"`
|
||||
@@ -201,6 +202,15 @@ func (c *PanConfig) init() error {
|
||||
requester.SetLocalTCPAddrList(strings.Split(c.LocalAddrs, ",")...)
|
||||
}
|
||||
|
||||
// 设置域名解析策略 IPv4 or IPv6
|
||||
t := requester.IPAny
|
||||
if strings.ToLower(c.PreferIPType) == "ipv4" {
|
||||
t = requester.IPv4
|
||||
} else if strings.ToLower(c.PreferIPType) == "ipv6" {
|
||||
t = requester.IPv6
|
||||
}
|
||||
requester.SetPreferIPType(t)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -285,6 +295,7 @@ func (c *PanConfig) initDefaultConfig() {
|
||||
c.DeviceId = RandomDeviceId() // 生成默认客户端ID
|
||||
c.DeviceName = DefaultDeviceName
|
||||
c.FileRecordConfig = "1" // 默认开启
|
||||
c.PreferIPType = "ipv4" // 默认优先IPv4
|
||||
}
|
||||
|
||||
// GetConfigDir 获取配置路径
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// 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
|
||||
// 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,
|
||||
@@ -36,6 +36,17 @@ func (c *PanConfig) SetLocalAddrs(localAddrs string) {
|
||||
requester.SetLocalTCPAddrList(strings.Split(localAddrs, ",")...)
|
||||
}
|
||||
|
||||
func (c *PanConfig) SetPreferIPType(ipType string) {
|
||||
c.PreferIPType = ipType
|
||||
t := requester.IPAny
|
||||
if strings.ToLower(ipType) == "ipv4" {
|
||||
t = requester.IPv4
|
||||
} else if strings.ToLower(ipType) == "ipv6" {
|
||||
t = requester.IPv6
|
||||
}
|
||||
requester.SetPreferIPType(t)
|
||||
}
|
||||
|
||||
// SetCacheSizeByStr 设置cache_size
|
||||
func (c *PanConfig) SetCacheSizeByStr(sizeStr string) error {
|
||||
size, err := converter.ParseFileSizeStr(sizeStr)
|
||||
@@ -103,6 +114,7 @@ func (c *PanConfig) PrintTable() {
|
||||
[]string{"savedir", c.SaveDir, "", "下载文件的储存目录"},
|
||||
[]string{"proxy", c.Proxy, "", "设置代理, 支持 http/socks5 代理,例如: http://127.0.0.1:8888 或者 socks5://127.0.0.1:8889"},
|
||||
[]string{"local_addrs", c.LocalAddrs, "", "设置本地网卡地址, 多个地址用逗号隔开,例如: 127.0.0.1,192.168.100.126"},
|
||||
[]string{"ip_type", c.PreferIPType, "ipv4-优先IPv4,ipv6-优先IPv6", "设置域名解析IP优先类型。修改后需要重启应用生效"},
|
||||
[]string{"file_record_config", fileRecorderLabel, "1-开启,2-禁用", "设置是否开启上传、下载、同步文件的结果记录,开启后会把结果记录到CSV文件方便后期查看"},
|
||||
[]string{"device_id", c.DeviceId, "", "客户端ID,用于标识登录客户端,阿里单个账号最多允许10个客户端同时在线。修改后需要重启应用生效"},
|
||||
})
|
||||
|
||||
@@ -64,8 +64,9 @@ type (
|
||||
panFile string
|
||||
state *uploader.InstanceState
|
||||
|
||||
ShowProgress bool
|
||||
IsOverwrite bool // 覆盖已存在的文件,如果同名文件已存在则移到回收站里
|
||||
ShowProgress bool
|
||||
IsOverwrite bool // 覆盖已存在的文件,如果同名文件已存在则移到回收站里
|
||||
IsSkipSameName bool // 跳过已存在的文件,即使文件内容不一致(不检查SHA1)
|
||||
|
||||
// 是否使用内置链接
|
||||
UseInternalUrl bool
|
||||
@@ -327,6 +328,7 @@ func (utu *UploadTaskUnit) Run() (result *taskframework.TaskUnitRunResult) {
|
||||
|
||||
var apierr *apierror.ApiError
|
||||
var rs *aliyunpan.MkdirResult
|
||||
var efi *aliyunpan.FileEntity
|
||||
var appCreateUploadFileParam *aliyunpan.CreateFileUploadParam
|
||||
var sha1Str string
|
||||
var contentHashName string
|
||||
@@ -398,6 +400,23 @@ StepUploadPrepareUpload:
|
||||
proofCode = ""
|
||||
contentHashName = "sha1"
|
||||
checkNameMode = "auto_rename"
|
||||
// 如果启用了 覆盖/跳过 已存在的文件,则需要提前检查文件是否存在
|
||||
if utu.IsOverwrite || utu.IsSkipSameName {
|
||||
efi, apierr = utu.PanClient.FileInfoByPath(utu.DriveId, utu.SavePath)
|
||||
if apierr != nil && apierr.Code != apierror.ApiCodeFileNotFoundCode {
|
||||
result.Err = apierr
|
||||
result.ResultMessage = "检测同名文件失败"
|
||||
return
|
||||
}
|
||||
}
|
||||
if utu.IsSkipSameName {
|
||||
if efi != nil && efi.FileId != "" {
|
||||
result.Succeed = true
|
||||
result.Extra = efi
|
||||
fmt.Printf("[%s] %s 检测到同名文件,跳过上传: %s\n", utu.taskInfo.Id(), time.Now().Format("2006-01-02 15:04:06"), utu.SavePath)
|
||||
return
|
||||
}
|
||||
}
|
||||
if !utu.NoRapidUpload {
|
||||
// 计算文件SHA1
|
||||
fmt.Printf("[%s] %s 正在计算文件SHA1: %s\n", utu.taskInfo.Id(), time.Now().Format("2006-01-02 15:04:06"), utu.LocalFileChecksum.Path.LogicPath)
|
||||
@@ -421,12 +440,6 @@ StepUploadPrepareUpload:
|
||||
if utu.IsOverwrite {
|
||||
// 标记覆盖旧同名文件
|
||||
// 检查同名文件是否存在
|
||||
efi, apierr := utu.PanClient.FileInfoByPath(utu.DriveId, utu.SavePath)
|
||||
if apierr != nil && apierr.Code != apierror.ApiCodeFileNotFoundCode {
|
||||
result.Err = apierr
|
||||
result.ResultMessage = "检测同名文件失败"
|
||||
return
|
||||
}
|
||||
if efi != nil && efi.FileId != "" {
|
||||
if strings.ToUpper(efi.ContentHash) == strings.ToUpper(sha1Str) {
|
||||
result.Succeed = true
|
||||
@@ -444,7 +457,7 @@ StepUploadPrepareUpload:
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Duration(500) * time.Millisecond)
|
||||
fmt.Printf("[%s] %s 检测到同名文件,已移动到回收站: %s\n", utu.taskInfo.Id(), time.Now().Format("2006-01-02 15:04:06"), utu.SavePath)
|
||||
fmt.Printf("[%s] %s 检测到同名文件,文件内容不一致,已将旧文件移动到回收站: %s\n", utu.taskInfo.Id(), time.Now().Format("2006-01-02 15:04:06"), utu.SavePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ const (
|
||||
|
||||
var (
|
||||
// Version 版本号
|
||||
Version = "v0.2.8"
|
||||
Version = "v0.2.9"
|
||||
|
||||
// 命令历史文件
|
||||
historyFilePath = filepath.Join(config.GetConfigDir(), "aliyunpan_command_history.txt")
|
||||
@@ -110,7 +110,7 @@ func main() {
|
||||
app.Name = "aliyunpan"
|
||||
app.Version = Version
|
||||
app.Author = "tickstep/aliyunpan: https://github.com/tickstep/aliyunpan"
|
||||
app.Copyright = "(c) 2021-2023 tickstep."
|
||||
app.Copyright = "(c) 2021-2024 tickstep."
|
||||
app.Usage = "阿里云盘客户端 for " + runtime.GOOS + "/" + runtime.GOARCH
|
||||
app.Description = `aliyunpan 是一款阿里云盘命令行客户端工具, 为操作阿里云盘, 提供实用功能。
|
||||
支持同步备份功能,支持备份本地文件到云盘,备份云盘文件到本地,双向同步备份。
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+5
-5
@@ -3,13 +3,13 @@
|
||||
"FileVersion": {
|
||||
"Major": 0,
|
||||
"Minor": 2,
|
||||
"Patch": 8,
|
||||
"Patch": 9,
|
||||
"Build": 0
|
||||
},
|
||||
"ProductVersion": {
|
||||
"Major": 0,
|
||||
"Minor": 2,
|
||||
"Patch": 8,
|
||||
"Patch": 9,
|
||||
"Build": 0
|
||||
},
|
||||
"FileFlagsMask": "3f",
|
||||
@@ -22,14 +22,14 @@
|
||||
"Comments": "",
|
||||
"CompanyName": "tickstep",
|
||||
"FileDescription": "阿里云盘客户端",
|
||||
"FileVersion": "v0.2.8",
|
||||
"FileVersion": "v0.2.9",
|
||||
"InternalName": "",
|
||||
"LegalCopyright": "© 2021-2023 tickstep.",
|
||||
"LegalCopyright": "© 2021-2024 tickstep.",
|
||||
"LegalTrademarks": "",
|
||||
"OriginalFilename": "",
|
||||
"PrivateBuild": "",
|
||||
"ProductName": "aliyunpan",
|
||||
"ProductVersion": "v0.2.8",
|
||||
"ProductVersion": "v0.2.9",
|
||||
"SpecialBuild": ""
|
||||
},
|
||||
"VarFileInfo": {
|
||||
|
||||
Reference in New Issue
Block a user