aliyunpan/internal/command/ls_search.go
2024-03-02 17:38:21 +08:00

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")
}