Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion drivers/123_open/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package _123_open
import (
"context"
"fmt"
"slices"
"strconv"
"time"

Expand Down Expand Up @@ -128,6 +129,26 @@ func (d *Open123) Rename(ctx context.Context, srcObj model.Obj, newName string)
return d.rename(fileId, newName)
}

func (d *Open123) BatchRename(ctx context.Context, obj model.Obj, renameObjs []model.RenameObj) error {
rl := []string{}
for _, ro := range renameObjs {
fileID, err := strconv.ParseInt(ro.ID, 10, 64)
if err != nil {
return err
}
rl = append(rl, fmt.Sprintf("%d|%s", fileID, ro.NewName))

}
// 每次最多30
for names := range slices.Chunk(rl, 30) {
if err := d.batchRename(names); err != nil {
return err
}
}

return nil
}

func (d *Open123) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
// 尝试使用上传+MD5秒传功能实现复制
// 1. 创建文件
Expand All @@ -151,7 +172,27 @@ func (d *Open123) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
func (d *Open123) Remove(ctx context.Context, obj model.Obj) error {
fileId, _ := strconv.ParseInt(obj.GetID(), 10, 64)

return d.trash(fileId)
return d.trash([]int64{fileId})
}

// BatchRemove 批量删除
func (d *Open123) BatchRemove(ctx context.Context, srcObj model.Obj, objs []model.IDName) error {

ids := []int64{}
for _, obj := range objs {
id, err := strconv.ParseInt(obj.ID, 10, 64)
if err != nil {
return err
}
ids = append(ids, id)
}
//每次最多100
for cids := range slices.Chunk(ids, 100) {
if err := d.trash(cids); err != nil {
return err
}
}
return nil
}

func (d *Open123) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
Expand Down
14 changes: 12 additions & 2 deletions drivers/123_open/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var ( //不同情况下获取的AccessTokenQPS限制不同 如下模块化易于
Mkdir = InitApiInfo(Api+"/upload/v1/file/mkdir", 2)
Move = InitApiInfo(Api+"/api/v1/file/move", 1)
Rename = InitApiInfo(Api+"/api/v1/file/name", 1)
BatchRename = InitApiInfo(Api+"/api/v1/file/rename", 0)
Trash = InitApiInfo(Api+"/api/v1/file/trash", 2)
UploadCreate = InitApiInfo(Api+"/upload/v2/file/create", 2)
UploadComplete = InitApiInfo(Api+"/upload/v2/file/upload_complete", 0)
Expand Down Expand Up @@ -248,11 +249,20 @@ func (d *Open123) rename(fileId int64, fileName string) error {

return nil
}
func (d *Open123) batchRename(renamelist []string) error {

func (d *Open123) trash(fileId int64) error {
_, err := d.Request(BatchRename, http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"renameList": renamelist,
})
}, nil)
return err
}

func (d *Open123) trash(fileIDs []int64) error {
_, err := d.Request(Trash, http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"fileIDs": []int64{fileId},
"fileIDs": fileIDs,
})
}, nil)
if err != nil {
Expand Down
24 changes: 24 additions & 0 deletions drivers/baidu_netdisk/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/url"
"os"
stdpath "path"
"path/filepath"
"strconv"
"time"

Expand Down Expand Up @@ -133,6 +134,19 @@ func (d *BaiduNetdisk) Rename(ctx context.Context, srcObj model.Obj, newName str
return nil, nil
}

func (d *BaiduNetdisk) BatchRename(ctx context.Context, obj model.Obj, renameObjs []model.RenameObj) error {
data := []base.Json{}
for _, ro := range renameObjs {
data = append(data, base.Json{
"path": filepath.Join(obj.GetPath(), ro.SrcName),
"newname": ro.NewName,
})
}

_, err := d.manage("rename", data)
return err
}

func (d *BaiduNetdisk) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
Expand All @@ -151,6 +165,16 @@ func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
return err
}

func (d *BaiduNetdisk) BatchRemove(ctx context.Context, srcObj model.Obj, objs []model.IDName) error {
data := []string{}
for _, obj := range objs {
data = append(data, filepath.Join(srcObj.GetPath(), obj.Name))
}

_, err := d.manage("delete", data)
return err
}

func (d *BaiduNetdisk) PutRapid(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) (model.Obj, error) {
contentMd5 := stream.GetHash().GetHash(utils.MD5)
if len(contentMd5) < utils.MD5.Width {
Expand Down
1 change: 1 addition & 0 deletions internal/conf/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,5 @@ const (
UserAgentKey
PathKey
SharingIDKey
StorageKey
)
8 changes: 8 additions & 0 deletions internal/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ type Rename interface {
Rename(ctx context.Context, srcObj model.Obj, newName string) error
}

type BatchRename interface {
BatchRename(ctx context.Context, obj model.Obj, renameObjs []model.RenameObj) error
}

type Copy interface {
Copy(ctx context.Context, srcObj, dstDir model.Obj) error
}
Expand All @@ -81,6 +85,10 @@ type Remove interface {
Remove(ctx context.Context, obj model.Obj) error
}

type BatchRemove interface {
BatchRemove(ctx context.Context, srcobj model.Obj, objs []model.IDName) error
}

type Put interface {
// Put a file (provided as a FileStreamer) into the driver
// Besides the most basic upload functionality, the following features also need to be implemented:
Expand Down
44 changes: 44 additions & 0 deletions internal/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fs
import (
"context"
"io"
stdpath "path"

log "github.com/sirupsen/logrus"

Expand Down Expand Up @@ -90,13 +91,56 @@ func Rename(ctx context.Context, srcPath, dstName string, lazyCache ...bool) err
return err
}

func BatchRename(ctx context.Context, storage driver.Driver, srcPath string, renameObjs []model.RenameObj, lazyCache ...bool) error {

srcRawObj, err := op.Get(ctx, storage, srcPath)
if err != nil {
return errors.WithMessage(err, "failed to get src object")
}
srcObj := model.UnwrapObj(srcRawObj)
srcDirPath := stdpath.Dir(srcPath)

switch s := storage.(type) {
case driver.BatchRename:
err := s.BatchRename(ctx, srcObj, renameObjs)
if err == nil {
op.ClearCache(storage, srcDirPath)
return nil
}
return err
default:
for _, renameObject := range renameObjs {
err := op.Rename(ctx, storage, stdpath.Join(srcPath, renameObject.SrcName), renameObject.NewName, lazyCache...)
if err != nil {
log.Errorf("failed rename %s to %s: %+v", renameObject.ID, renameObject.NewName, err)
return err
}
}
}
return nil
}

func Remove(ctx context.Context, path string) error {
err := remove(ctx, path)
if err != nil {
log.Errorf("failed remove %s: %+v", path, err)
}
return err
}
func BatchRemove(ctx context.Context, storage driver.Driver, actualPath string, objs []model.IDName) error {
switch storage.(type) {
case driver.BatchRemove:
return op.BatchRemove(ctx, storage, actualPath, objs)
default:
for _, obj := range objs {
err := op.Remove(ctx, storage, stdpath.Join(actualPath, obj.Name))
if err != nil {
return err
}
}
}
return nil
}

func PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer, lazyCache ...bool) error {
err := putDirectly(ctx, dstDirPath, file, lazyCache...)
Expand Down
12 changes: 12 additions & 0 deletions internal/model/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,15 @@ func (om *ObjMerge) InitHideReg(hides string) {
func (om *ObjMerge) Reset() {
om.set.Clear()
}

// IDName 文件ID,文件名称,有的网盘使用文件id管理文件,有的使用路径名称
type IDName struct {
ID string `json:"id" form:"id"`
Name string `json:"name" form:"name"`
}

type RenameObj struct {
ID string `json:"id"` //文件id,部分网盘需要,如果没有可以不传
SrcName string `json:"src_name"`
NewName string `json:"new_name"`
}
19 changes: 19 additions & 0 deletions internal/op/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,25 @@ func Remove(ctx context.Context, storage driver.Driver, path string) error {
return errors.WithStack(err)
}

func BatchRemove(ctx context.Context, storage driver.Driver, actualPath string, objs []model.IDName) error {
srcobj, err := Get(ctx, storage, actualPath)
if err != nil {
return errors.WithMessage(err, "failed to get src object")
}
switch s := storage.(type) {
case driver.BatchRemove:
err := s.BatchRemove(ctx, srcobj, objs)
if err == nil {
ClearCache(storage, actualPath)
return nil
}
return err
default:
return errs.NotImplement
}

}

func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file model.FileStreamer, up driver.UpdateProgress, lazyCache ...bool) error {
close := file.Close
defer func() {
Expand Down
41 changes: 6 additions & 35 deletions server/handles/fsbatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"slices"

"github.com/OpenListTeam/OpenList/v4/internal/conf"
"github.com/OpenListTeam/OpenList/v4/internal/driver"
"github.com/OpenListTeam/OpenList/v4/internal/errs"
"github.com/OpenListTeam/OpenList/v4/internal/fs"
"github.com/OpenListTeam/OpenList/v4/internal/model"
Expand Down Expand Up @@ -136,11 +137,7 @@ func FsRecursiveMove(c *gin.Context) {
}

type BatchRenameReq struct {
SrcDir string `json:"src_dir"`
RenameObjects []struct {
SrcName string `json:"src_name"`
NewName string `json:"new_name"`
} `json:"rename_objects"`
RenameObjects []model.RenameObj `json:"rename_objects"`
}

func FsBatchRename(c *gin.Context) {
Expand All @@ -149,41 +146,15 @@ func FsBatchRename(c *gin.Context) {
common.ErrorResp(c, err, 400)
return
}
user := c.Request.Context().Value(conf.UserKey).(*model.User)
if !user.CanRename() {
common.ErrorResp(c, errs.PermissionDenied, 403)
return
}
storage := c.Request.Context().Value(conf.StorageKey).(driver.Driver)
path := c.Request.Context().Value(conf.PathKey).(string)

reqPath, err := user.JoinPath(req.SrcDir)
err := fs.BatchRename(c.Request.Context(), storage, path, req.RenameObjects)
if err != nil {
common.ErrorResp(c, err, 403)
common.ErrorResp(c, err, 500)
return
}

meta, err := op.GetNearestMeta(reqPath)
if err != nil {
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
common.ErrorResp(c, err, 500, true)
return
}
}
common.GinWithValue(c, conf.MetaKey, meta)
for _, renameObject := range req.RenameObjects {
if renameObject.SrcName == "" || renameObject.NewName == "" {
continue
}
err = checkRelativePath(renameObject.NewName)
if err != nil {
common.ErrorResp(c, err, 403)
return
}
filePath := fmt.Sprintf("%s/%s", reqPath, renameObject.SrcName)
if err := fs.Rename(c.Request.Context(), filePath, renameObject.NewName); err != nil {
common.ErrorResp(c, err, 500)
return
}
}
common.SuccessResp(c)
}

Expand Down
26 changes: 10 additions & 16 deletions server/handles/fsmanage.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/OpenListTeam/OpenList/v4/internal/conf"
"github.com/OpenListTeam/OpenList/v4/internal/driver"
"github.com/OpenListTeam/OpenList/v4/internal/task"

"github.com/OpenListTeam/OpenList/v4/internal/errs"
Expand Down Expand Up @@ -236,8 +237,7 @@ func checkRelativePath(path string) error {
}

type RemoveReq struct {
Dir string `json:"dir"`
Names []string `json:"names"`
Names []model.IDName `json:"names"`
}

func FsRemove(c *gin.Context) {
Expand All @@ -250,23 +250,17 @@ func FsRemove(c *gin.Context) {
common.ErrorStrResp(c, "Empty file names", 400)
return
}
user := c.Request.Context().Value(conf.UserKey).(*model.User)
if !user.CanRemove() {
common.ErrorResp(c, errs.PermissionDenied, 403)
return
}
reqDir, err := user.JoinPath(req.Dir)

storage := c.Request.Context().Value(conf.StorageKey).(driver.Driver)
actualPath := c.Request.Context().Value(conf.PathKey).(string)

err := fs.BatchRemove(c.Request.Context(), storage, actualPath, req.Names)

if err != nil {
common.ErrorResp(c, err, 403)
common.ErrorResp(c, err, 500)
return
}
for _, name := range req.Names {
err := fs.Remove(c.Request.Context(), stdpath.Join(reqDir, name))
if err != nil {
common.ErrorResp(c, err, 500)
return
}
}

//fs.ClearCache(req.Dir)
common.SuccessResp(c)
}
Expand Down
Loading