From 77057829f9ec3dd862cb72eeed7ada40172872ee Mon Sep 17 00:00:00 2001 From: apple <2571583272@qq.com> Date: Sat, 28 Apr 2018 08:02:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E6=A1=A3=E9=94=99?= =?UTF-8?q?=E8=AF=AF;=20#5=20#64=20#113=20#124,=20fix=20#136,=20fix=20#80,?= =?UTF-8?q?=20fix=20#41,=20=E5=88=9D=E6=AD=A5=E6=94=AF=E6=8C=81tab=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=A1=A5=E5=85=A8=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++--- baidupcs/file_directory.go | 2 +- main.go | 118 +++++++++++++++++++++++++++++++++++-- pcsutil/pcsutil.go | 10 ++++ requester/fetch.go | 12 ++++ 5 files changed, 143 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index af370536..4c59230d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ This project was largely inspired by [GangZhuo/BaiduPCS](https://github.com/Gang - [特色](#特色) - [编译/交叉编译 说明](#编译交叉编译-说明) - [下载/运行 说明](#下载运行-说明) - * [Windows](#Windows) + * [Windows](#windows) * [Linux / macOS](#linux--macos) * [Android / iOS](#android--ios) - [命令列表及说明](#命令列表及说明) @@ -29,11 +29,11 @@ This project was largely inspired by [GangZhuo/BaiduPCS](https://github.com/Gang * [下载文件/目录](#下载文件目录) * [上传文件/目录](#上传文件目录) * [手动秒传文件](#手动秒传文件) - * [获取文件的秒传信息](#获取文件的秒传信息) + * [获取本地文件的秒传信息](#获取本地文件的秒传信息) * [创建目录](#创建目录) * [删除文件/目录](#删除文件目录) * [拷贝文件/目录](#拷贝文件目录) - * [移动/重命名文件/目录](#移动/重命名文件目录) + * [移动/重命名文件/目录](#移动重命名文件目录) * [离线下载](#离线下载) + [添加离线下载任务](#添加离线下载任务) + [精确查询离线下载任务](#精确查询离线下载任务) @@ -92,13 +92,13 @@ cli交互模式下, 光标所在行的前缀应为 `BaiduPCS-Go >`, 如果登录 程序应在 命令提示符 (Command Prompt) 或 PowerShell 中运行, 在 mintty (例如: GitBash) 可能会有显示问题. -也可直接双击程序运行, 具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [例子](#举一些例子). +也可直接双击程序运行, 具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [初级使用教程](#初级使用教程). ## Linux / macOS 程序应在 终端 (Terminal) 运行. -具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [例子](#举一些例子). +具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [初级使用教程](#初级使用教程). ## Android / iOS @@ -110,7 +110,7 @@ cli交互模式下, 光标所在行的前缀应为 `BaiduPCS-Go >`, 如果登录 苹果iOS, 需要越狱, 在 Cydia 搜索下载并安装 MobileTerminal, 或者其他提供终端环境的软件. -具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [例子](#举一些例子). +具体使用方法请参见 [命令列表及说明](#命令列表及说明) 和 [初级使用教程](#初级使用教程). # 命令列表及说明 @@ -347,13 +347,13 @@ BaiduPCS-Go rapidupload -length=56276137 -md5=fbe082d80e90f90f0fb1f94adbbcfa7f - BaiduPCS-Go rapidupload -length=56276137 -md5=fbe082d80e90f90f0fb1f94adbbcfa7f /test ``` -## 获取文件的秒传信息 +## 获取本地文件的秒传信息 ``` BaiduPCS-Go sumfile <本地文件的路径> BaiduPCS-Go sf <本地文件的路径> ``` -获取文件的大小, md5, 前256KB切片的 md5, crc32, 可用于秒传文件. +获取本地文件的大小, md5, 前256KB切片的 md5, crc32, 可用于秒传文件. #### 例子: ``` diff --git a/baidupcs/file_directory.go b/baidupcs/file_directory.go index 42749777..b061d8ed 100644 --- a/baidupcs/file_directory.go +++ b/baidupcs/file_directory.go @@ -265,7 +265,7 @@ func (fl FileDirectoryList) Count() (fileN, directoryN int64) { // AllFilePaths 返回所有的网盘路径, 包括子目录 func (fl FileDirectoryList) AllFilePaths() (pcspaths []string) { fN, dN := fl.Count() - pcspaths = make([]string, fN+dN) + pcspaths = make([]string, 0, fN+dN) for k := range fl { if fl[k] == nil { continue diff --git a/main.go b/main.go index 5b3bc9a8..469a2e4d 100644 --- a/main.go +++ b/main.go @@ -99,7 +99,12 @@ func main() { --------------------------------------------------- 前往 https://github.com/iikira/BaiduPCS-Go 以获取更多帮助信息! 前往 https://github.com/iikira/BaiduPCS-Go/releases 以获取程序更新信息! - ---------------------------------------------------` + --------------------------------------------------- + + 交流反馈: + 提交Issue: https://github.com/iikira/BaiduPCS-Go/issues + 邮箱: i@mail.iikira.com + QQ群: 178324706` app.Flags = []cli.Flag{ cli.BoolFlag{ @@ -133,15 +138,116 @@ func main() { // tab 自动补全命令 line.State.SetCompleter(func(line string) (s []string) { - cmds := cli.CommandsByName(app.Commands) + var ( + lineArgs = args.GetArgs(line) + numArgs = len(lineArgs) + acceptCompleteFileCommands = []string{ + "cd", "cp", "download", "ls", "meta", "mkdir", "mv", "rapidupload", "rm", "tree", "upload", + } + closed = strings.LastIndex(line, " ") == len(line)-1 + ) + + for _, cmd := range app.Commands { + for _, name := range cmd.Names() { + if !strings.HasPrefix(name, line) { + continue + } + + s = append(s, name+" ") + } + } + + switch numArgs { + case 0: + return + case 1: + if !closed { + return + } + default: + thisCmd := app.Command(lineArgs[0]) + if thisCmd == nil { + return + } - for k := range cmds { - if !strings.HasPrefix(cmds[k].FullName(), line) { + if !pcsutil.ContainsString(acceptCompleteFileCommands, thisCmd.FullName()) { + return + } + } + + var ( + activeUser = pcsconfig.Config.ActiveUser() + pcs = pcsconfig.Config.ActiveUserBaiduPCS() + targetPath string + ) + + if !closed { + targetPath = lineArgs[numArgs-1] + } + + var ( + targetDir string + isAbs = path.IsAbs(targetPath) + isDir = strings.LastIndex(targetPath, "/") == len(targetPath)-1 + ) + + if isAbs { + targetDir = path.Dir(targetPath) + } else { + targetDir = path.Join(activeUser.Workdir, targetPath) + if !isDir { + targetDir = path.Dir(targetDir) + } + } + filesPtr := pcscache.DirCache.Get(targetDir) + + if filesPtr == nil { + files, err := pcs.FilesDirectoriesList(targetDir) + if err != nil { + return + } + pcscache.DirCache.Set(targetDir, &files) + filesPtr = &files + } + + for _, file := range *filesPtr { + if file == nil { continue } - s = append(s, cmds[k].FullName()+" ") + + var ( + cleanedPath string + appendLine string + ) + + if isAbs { + cleanedPath = file.Path + } else { + cleanedPath = strings.TrimPrefix(file.Path, path.Clean(activeUser.Workdir+"/")) + } + + // 已经有的情况 + if !closed { + if !strings.HasPrefix(cleanedPath, targetPath) { + continue + } + appendLine = strings.Join(append(lineArgs[:len(lineArgs)-1], cleanedPath), " ") + goto handle + } + // 没有的情况 + appendLine = strings.Join(append(lineArgs, cleanedPath), " ") + goto handle + + handle: + if file.Isdir { + s = append(s, appendLine+"/") + continue + } + s = append(s, appendLine+" ") + continue } - return s + + return }) for { diff --git a/pcsutil/pcsutil.go b/pcsutil/pcsutil.go index 58ceb74d..8f5c2591 100644 --- a/pcsutil/pcsutil.go +++ b/pcsutil/pcsutil.go @@ -25,6 +25,16 @@ func init() { PipeInput = (fileInfo.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe } +// ContainsString 检测字符串是否在字符串数组里 +func ContainsString(ss []string, s string) bool { + for k := range ss { + if strings.Compare(ss[k], s) == 0 { + return true + } + } + return false +} + // GetURLCookieString 返回cookie字串 func GetURLCookieString(urlString string, jar *cookiejar.Jar) string { url, _ := url.Parse(urlString) diff --git a/requester/fetch.go b/requester/fetch.go index 9b7e91e7..9ff2dd23 100644 --- a/requester/fetch.go +++ b/requester/fetch.go @@ -56,6 +56,18 @@ func (h *HTTPClient) Req(method string, urlStr string, post interface{}, header query.Set(k, value[k]) } obody = strings.NewReader(query.Encode()) + case map[string]interface{}: + query := url.Values{} + for k := range value { + query.Set(k, fmt.Sprint(value[k])) + } + obody = strings.NewReader(query.Encode()) + case map[interface{}]interface{}: + query := url.Values{} + for k := range value { + query.Set(fmt.Sprint(k), fmt.Sprint(value[k])) + } + obody = strings.NewReader(query.Encode()) case string: obody = strings.NewReader(value) case []byte: