mirror of
https://github.com/tickstep/aliyunpan.git
synced 2025-01-23 22:42:15 +08:00
249 lines
7.0 KiB
Go
249 lines
7.0 KiB
Go
// 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"
|
|
"github.com/olekukonko/tablewriter"
|
|
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
|
"github.com/tickstep/aliyunpan/cmder"
|
|
"github.com/tickstep/aliyunpan/cmder/cmdtable"
|
|
"github.com/tickstep/aliyunpan/internal/config"
|
|
"github.com/tickstep/library-go/converter"
|
|
"github.com/urfave/cli"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type (
|
|
// LsOptions 列目录可选项
|
|
LsOptions struct {
|
|
Total bool
|
|
}
|
|
|
|
// SearchOptions 搜索可选项
|
|
SearchOptions struct {
|
|
Total bool
|
|
Recurse bool
|
|
}
|
|
)
|
|
|
|
const (
|
|
opLs int = iota
|
|
opSearch
|
|
)
|
|
|
|
func CmdLs() cli.Command {
|
|
return cli.Command{
|
|
Name: "ls",
|
|
Aliases: []string{"l", "ll"},
|
|
Usage: "列出目录",
|
|
UsageText: cmder.App().Name + " ls <目录>",
|
|
Description: `
|
|
列出当前工作目录内的文件和目录, 或指定目录内的文件和目录
|
|
|
|
示例:
|
|
|
|
列出 我的资源 内的文件和目录
|
|
aliyunpan ls 我的资源
|
|
|
|
绝对路径
|
|
aliyunpan ls /我的资源
|
|
|
|
列出 我的资源 内的文件和目录,使用通配符
|
|
aliyunpan ls /我的*
|
|
|
|
详细列出 我的资源 内的文件和目录
|
|
aliyunpan ll /我的资源
|
|
`,
|
|
Category: "阿里云盘",
|
|
Before: ReloadConfigFunc,
|
|
Action: func(c *cli.Context) error {
|
|
if config.Config.ActiveUser() == nil {
|
|
fmt.Println("未登录账号")
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
orderBy aliyunpan.FileOrderBy = aliyunpan.FileOrderByUpdatedAt
|
|
orderSort aliyunpan.FileOrderDirection = aliyunpan.FileOrderDirectionDesc
|
|
)
|
|
|
|
switch {
|
|
case c.IsSet("asc"):
|
|
orderSort = aliyunpan.FileOrderDirectionAsc
|
|
case c.IsSet("desc"):
|
|
orderSort = aliyunpan.FileOrderDirectionDesc
|
|
default:
|
|
orderSort = aliyunpan.FileOrderDirectionDesc
|
|
}
|
|
|
|
switch {
|
|
case c.IsSet("time"):
|
|
orderBy = aliyunpan.FileOrderByUpdatedAt
|
|
case c.IsSet("name"):
|
|
orderBy = aliyunpan.FileOrderByName
|
|
case c.IsSet("size"):
|
|
orderBy = aliyunpan.FileOrderBySize
|
|
default:
|
|
orderBy = aliyunpan.FileOrderByUpdatedAt
|
|
}
|
|
|
|
RunLs(parseDriveId(c), c.Args().Get(0), &LsOptions{
|
|
Total: c.Bool("l") || c.Parent().Args().Get(0) == "ll",
|
|
}, orderBy, orderSort)
|
|
|
|
return nil
|
|
},
|
|
Flags: []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "driveId",
|
|
Usage: "网盘ID",
|
|
Value: "",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "asc",
|
|
Usage: "升序排序",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "desc",
|
|
Usage: "降序排序",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "time",
|
|
Usage: "根据修改时间排序",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "name",
|
|
Usage: "根据文件名排序",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "size",
|
|
Usage: "根据大小排序",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func RunLs(driveId, targetPath string, lsOptions *LsOptions,
|
|
orderBy aliyunpan.FileOrderBy, orderDirection aliyunpan.FileOrderDirection) {
|
|
activeUser := config.Config.ActiveUser()
|
|
targetPath = activeUser.PathJoin(driveId, targetPath)
|
|
|
|
// 获取目标路径文件信息
|
|
targetPathInfo, err := activeUser.PanClient().OpenapiPanClient().FileInfoByPath(driveId, targetPath)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// 适配通配符路径获取目标文件信息(弃用,容易触发风控)
|
|
//files, err := matchPathByShellPattern(driveId, targetPath)
|
|
//if err != nil {
|
|
// fmt.Println(err)
|
|
// return
|
|
//}
|
|
//var targetPathInfo *aliyunpan.FileEntity
|
|
//if len(files) == 1 {
|
|
// targetPathInfo = files[0]
|
|
//} else {
|
|
// for _, f := range files {
|
|
// if f.IsFolder() {
|
|
// targetPathInfo = f
|
|
// break
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
if targetPathInfo == nil {
|
|
fmt.Println("目录路径不存在")
|
|
return
|
|
}
|
|
|
|
fileList := aliyunpan.FileList{}
|
|
fileListParam := &aliyunpan.FileListParam{}
|
|
fileListParam.ParentFileId = targetPathInfo.FileId
|
|
fileListParam.DriveId = driveId
|
|
fileListParam.OrderBy = orderBy
|
|
fileListParam.OrderDirection = orderDirection
|
|
if targetPathInfo.IsFolder() {
|
|
fileResult, err1 := activeUser.PanClient().OpenapiPanClient().FileListGetAll(fileListParam, 200)
|
|
if err1 != nil {
|
|
fmt.Println(err1)
|
|
return
|
|
}
|
|
fileList = fileResult
|
|
} else {
|
|
fileList = append(fileList, targetPathInfo)
|
|
}
|
|
renderTable(opLs, lsOptions.Total, targetPathInfo.Path, fileList)
|
|
}
|
|
|
|
func renderTable(op int, isTotal bool, path string, files aliyunpan.FileList) {
|
|
tb := cmdtable.NewTable(os.Stdout)
|
|
var (
|
|
fN, dN int64
|
|
showPath string
|
|
)
|
|
|
|
switch op {
|
|
case opLs:
|
|
showPath = "文件(目录)"
|
|
case opSearch:
|
|
showPath = "路径"
|
|
}
|
|
|
|
if isTotal {
|
|
tb.SetHeader([]string{"#", "file_id", "文件大小", "文件SHA1", "文件大小(原始)", "创建日期", "修改日期", showPath})
|
|
tb.SetColumnAlignment([]int{tablewriter.ALIGN_DEFAULT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT})
|
|
for k, file := range files {
|
|
if file.IsFolder() {
|
|
tb.Append([]string{strconv.Itoa(k + 1), file.FileId, "-", "-", "-", file.CreatedAt, file.UpdatedAt, file.FileName + aliyunpan.PathSeparator})
|
|
continue
|
|
}
|
|
|
|
switch op {
|
|
case opLs:
|
|
tb.Append([]string{strconv.Itoa(k + 1), file.FileId, converter.ConvertFileSize(file.FileSize, 2), file.ContentHash, strconv.FormatInt(file.FileSize, 10), file.CreatedAt, file.UpdatedAt, file.FileName})
|
|
case opSearch:
|
|
tb.Append([]string{strconv.Itoa(k + 1), file.FileId, converter.ConvertFileSize(file.FileSize, 2), file.ContentHash, strconv.FormatInt(file.FileSize, 10), file.CreatedAt, file.UpdatedAt, file.Path})
|
|
}
|
|
}
|
|
fN, dN = files.Count()
|
|
tb.Append([]string{"", "", "总: " + converter.ConvertFileSize(files.TotalSize(), 2), "", "", "", fmt.Sprintf("文件总数: %d, 目录总数: %d", fN, dN)})
|
|
} else {
|
|
tb.SetHeader([]string{"#", "文件大小", "修改日期", showPath})
|
|
tb.SetColumnAlignment([]int{tablewriter.ALIGN_DEFAULT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT})
|
|
for k, file := range files {
|
|
if file.IsFolder() {
|
|
tb.Append([]string{strconv.Itoa(k + 1), "-", file.UpdatedAt, file.FileName + aliyunpan.PathSeparator})
|
|
continue
|
|
}
|
|
|
|
switch op {
|
|
case opLs:
|
|
tb.Append([]string{strconv.Itoa(k + 1), converter.ConvertFileSize(file.FileSize, 2), file.UpdatedAt, file.FileName})
|
|
case opSearch:
|
|
tb.Append([]string{strconv.Itoa(k + 1), converter.ConvertFileSize(file.FileSize, 2), file.UpdatedAt, file.Path})
|
|
}
|
|
}
|
|
fN, dN = files.Count()
|
|
tb.Append([]string{"", "总: " + converter.ConvertFileSize(files.TotalSize(), 2), "", fmt.Sprintf("文件总数: %d, 目录总数: %d", fN, dN)})
|
|
}
|
|
fmt.Printf("\n当前目录: %s\n", path)
|
|
fmt.Printf("----\n")
|
|
tb.Render()
|
|
fmt.Printf("----\n")
|
|
}
|