diff --git a/internal/command/download.go b/internal/command/download.go index 27917ac..e39895b 100644 --- a/internal/command/download.go +++ b/internal/command/download.go @@ -47,7 +47,8 @@ type ( NoCheck bool ShowProgress bool DriveId string - UseInternalUrl bool // 是否使用内置链接 + UseInternalUrl bool // 是否使用内置链接 + ExcludeNames []string // 排除的文件名,包括文件夹和文件。即这些文件/文件夹不进行下载,支持正则表达式 } // LocateDownloadOption 获取下载链接可选参数 @@ -93,8 +94,19 @@ func CmdDownload() cli.Command { 下载 /我的资源 整个目录!! aliyunpan download /我的资源 - 下载 /我的资源/1.mp4 并保存下载的文件到本地的 d:/panfile + 下载 /我的资源 整个目录,但是排除所有的jpg文件 + aliyunpan download -exn "\.jpg$" /我的资源 + + 下载 /我的资源/1.mp4 并保存下载的文件到本地的 d:/panfile aliyunpan download --saveto d:/panfile /我的资源/1.mp4 + + 参考: + 以下是典型的排除特定文件或者文件夹的例子,注意:参数值必须是正则表达式。在正则表达式中,^表示匹配开头,$表示匹配结尾。 + 1)排除@eadir文件或者文件夹:-exn "^@eadir$" + 2)排除.jpg文件:-exn "\.jpg$" + 3)排除.号开头的文件:-exn "^\." + 4)排除~号开头的文件:-exn "^~" + 5)排除 myfile.txt 文件:-exn "^myfile.txt$" `, Category: "阿里云盘", Before: cmder.ReloadConfigFunc, @@ -127,6 +139,7 @@ func CmdDownload() cli.Command { NoCheck: c.Bool("nocheck"), ShowProgress: !c.Bool("np"), DriveId: parseDriveId(c), + ExcludeNames: c.StringSlice("exn"), } RunDownload(c.Args(), do) @@ -175,6 +188,11 @@ func CmdDownload() cli.Command { Usage: "网盘ID", Value: "", }, + cli.StringSliceFlag{ + Name: "exn", + Usage: "exclude name,指定排除的文件夹或者文件的名称,被排除的文件不会进行下载,只支持正则表达式。支持同时排除多个名称,每一个名称就是一个exn参数", + Value: nil, + }, }, } } @@ -224,6 +242,7 @@ func RunDownload(paths []string, options *DownloadOptions) { InstanceStateStorageFormat: downloader.InstanceStateStorageFormatJSON, ShowProgress: options.ShowProgress, UseInternalUrl: config.Config.TransferUrlType == 2, + ExcludeNames: options.ExcludeNames, } if cfg.CacheSize == 0 { cfg.CacheSize = int(DownloadCacheSize) @@ -297,8 +316,15 @@ func RunDownload(paths []string, options *DownloadOptions) { continue } for _, f := range fileList { - // 匹配的文件 newCfg := *cfg + + // 是否排除下载 + if utils.IsExcludeFile(f.Path, &newCfg.ExcludeNames) { + fmt.Printf("排除文件: %s\n", f.Path) + continue + } + + // 匹配的文件 unit := pandownload.DownloadTaskUnit{ Cfg: &newCfg, // 复制一份新的cfg PanClient: panClient, diff --git a/internal/command/upload.go b/internal/command/upload.go index e5808d4..8ef57b8 100644 --- a/internal/command/upload.go +++ b/internal/command/upload.go @@ -337,7 +337,7 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) { localPathDir := filepath.Dir(curPath) // 是否排除上传 - if isExcludeFile(curPath, &opt.ExcludeNames) { + if utils.IsExcludeFile(curPath, &opt.ExcludeNames) { fmt.Printf("排除文件: %s\n", curPath) continue } @@ -359,7 +359,7 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) { } // 是否排除上传 - if isExcludeFile(file.LogicPath, &opt.ExcludeNames) { + if utils.IsExcludeFile(file.LogicPath, &opt.ExcludeNames) { fmt.Printf("排除文件: %s\n", file.LogicPath) return filepath.SkipDir } diff --git a/internal/command/utils.go b/internal/command/utils.go index 7a8b047..405db94 100644 --- a/internal/command/utils.go +++ b/internal/command/utils.go @@ -22,7 +22,6 @@ import ( "net/url" "path" "path/filepath" - "regexp" "strings" "time" ) @@ -166,19 +165,3 @@ func isIncludeFile(pattern string, fileName string) bool { func isMatchWildcardPattern(name string) bool { return strings.ContainsAny(name, "*") || strings.ContainsAny(name, "?") || strings.ContainsAny(name, "[") } - -// 是否是指定排除的文件 -func isExcludeFile(filePath string, excludeNames *[]string) bool { - if excludeNames == nil || len(*excludeNames) == 0 { - return false - } - - for _, pattern := range *excludeNames { - fileName := path.Base(strings.ReplaceAll(filePath, "\\", "/")) - m, _ := regexp.MatchString(pattern, fileName) - if m { - return true - } - } - return false -} diff --git a/internal/file/downloader/config.go b/internal/file/downloader/config.go index 474b346..0e43463 100644 --- a/internal/file/downloader/config.go +++ b/internal/file/downloader/config.go @@ -41,7 +41,8 @@ type Config struct { InstanceStatePath string // 断点续传信息路径 TryHTTP bool // 是否尝试使用 http 连接 ShowProgress bool // 是否展示下载进度条 - UseInternalUrl bool // 是否使用内置链接 + UseInternalUrl bool // 是否使用内置链接 + ExcludeNames []string // 排除的文件名,包括文件夹和文件。即这些文件/文件夹不进行下载,支持正则表达式 } //NewConfig 返回默认配置 diff --git a/internal/functions/pandownload/download_task_unit.go b/internal/functions/pandownload/download_task_unit.go index 3a68774..5251e06 100644 --- a/internal/functions/pandownload/download_task_unit.go +++ b/internal/functions/pandownload/download_task_unit.go @@ -25,6 +25,7 @@ import ( "github.com/tickstep/aliyunpan/internal/localfile" "github.com/tickstep/aliyunpan/internal/plugins" "github.com/tickstep/aliyunpan/internal/taskframework" + "github.com/tickstep/aliyunpan/internal/utils" "github.com/tickstep/aliyunpan/library/requester/transfer" "github.com/tickstep/library-go/converter" "github.com/tickstep/library-go/logger" @@ -537,6 +538,13 @@ func (dtu *DownloadTaskUnit) Run() (result *taskframework.TaskUnitRunResult) { // 创建对应的任务进行下载 for k := range fileList { fileList[k].Path = path.Join(dtu.FilePanPath, fileList[k].FileName) + + // 是否排除下载 + if utils.IsExcludeFile(fileList[k].Path, &dtu.Cfg.ExcludeNames) { + fmt.Printf("排除文件: %s\n", fileList[k].Path) + continue + } + if fileList[k].IsFolder() { logger.Verbosef("[%s] create sub folder download task: %s\n", dtu.taskInfo.Id(), fileList[k].Path) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index b1bc6ea..171a93c 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -254,3 +254,19 @@ func IsLocalAbsPath(filePath string) bool { func IsPanAbsPath(filePath string) bool { return path.IsAbs(filePath) } + +// IsExcludeFile 是否是指定排除的文件 +func IsExcludeFile(filePath string, excludeNames *[]string) bool { + if excludeNames == nil || len(*excludeNames) == 0 { + return false + } + + for _, pattern := range *excludeNames { + fileName := path.Base(strings.ReplaceAll(filePath, "\\", "/")) + m, _ := regexp.MatchString(pattern, fileName) + if m { + return true + } + } + return false +}