From 62a06fa0f9008b9eae35912df23b35af65ee3357 Mon Sep 17 00:00:00 2001 From: foxxorcat <95907542+foxxorcat@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:02:40 +0800 Subject: [PATCH] feat: optimize file operation interface (#2757) * feat: optimize file operation interface * chore: fix typo Co-authored-by: Noah Hsu --- internal/driver/driver.go | 63 +++++++-- internal/fs/copy.go | 6 +- internal/fs/fs.go | 20 +-- internal/fs/other.go | 12 +- internal/fs/put.go | 6 +- internal/model/obj.go | 33 +++++ internal/op/fs.go | 273 ++++++++++++++++++++++++++++--------- pkg/utils/bool.go | 5 + server/handles/fsmanage.go | 15 +- server/handles/fsread.go | 9 +- server/handles/fsup.go | 4 +- server/webdav/file.go | 3 - server/webdav/webdav.go | 2 - 13 files changed, 330 insertions(+), 121 deletions(-) create mode 100644 pkg/utils/bool.go diff --git a/internal/driver/driver.go b/internal/driver/driver.go index 3e617eb9..c82ff3bc 100644 --- a/internal/driver/driver.go +++ b/internal/driver/driver.go @@ -9,7 +9,7 @@ import ( type Driver interface { Meta Reader - Writer + //Writer //Other } @@ -42,19 +42,66 @@ type Getter interface { GetRoot(ctx context.Context) (model.Obj, error) } -type Writer interface { - // MakeDir make a folder named `dirName` in `parentDir` +//type Writer interface { +// Mkdir +// Move +// Rename +// Copy +// Remove +// Put +//} + +type Mkdir interface { MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error - // Move `srcObject` to `dstDir` +} + +type Move interface { Move(ctx context.Context, srcObj, dstDir model.Obj) error - // Rename rename `srcObject` to `newName` +} + +type Rename interface { Rename(ctx context.Context, srcObj model.Obj, newName string) error - // Copy `srcObject` to `dstDir` +} + +type Copy interface { Copy(ctx context.Context, srcObj, dstDir model.Obj) error - // Remove remove `object` +} + +type Remove interface { Remove(ctx context.Context, obj model.Obj) error - // Put upload `stream` to `parentDir` +} + +type Put interface { Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up UpdateProgress) error } +//type WriteResult interface { +// MkdirResult +// MoveResult +// RenameResult +// CopyResult +// PutResult +// Remove +//} + +type MkdirResult interface { + MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) +} + +type MoveResult interface { + Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) +} + +type RenameResult interface { + Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) +} + +type CopyResult interface { + Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) +} + +type PutResult interface { + Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up UpdateProgress) (model.Obj, error) +} + type UpdateProgress func(percentage int) diff --git a/internal/fs/copy.go b/internal/fs/copy.go index 9f3871fd..e18a6127 100644 --- a/internal/fs/copy.go +++ b/internal/fs/copy.go @@ -21,7 +21,7 @@ var CopyTaskManager = task.NewTaskManager(3, func(tid *uint64) { // Copy if in the same storage, call move method // if not, add copy task -func _copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { +func _copy(ctx context.Context, srcObjPath, dstDirPath string, lazyCache ...bool) (bool, error) { srcStorage, srcObjActualPath, err := op.GetStorageAndActualPath(srcObjPath) if err != nil { return false, errors.WithMessage(err, "failed get src storage") @@ -32,7 +32,7 @@ func _copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { } // copy if in the same storage, just call driver.Copy if srcStorage.GetStorage() == dstStorage.GetStorage() { - return false, op.Copy(ctx, srcStorage, srcObjActualPath, dstDirActualPath) + return false, op.Copy(ctx, srcStorage, srcObjActualPath, dstDirActualPath, lazyCache...) } // not in the same storage CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ @@ -95,5 +95,5 @@ func copyFileBetween2Storages(tsk *task.Task[uint64], srcStorage, dstStorage dri if err != nil { return errors.WithMessagef(err, "failed get [%s] stream", srcFilePath) } - return op.Put(tsk.Ctx, dstStorage, dstDirPath, stream, tsk.SetProgress) + return op.Put(tsk.Ctx, dstStorage, dstDirPath, stream, tsk.SetProgress, true) } diff --git a/internal/fs/fs.go b/internal/fs/fs.go index 05429f7e..b15b2225 100644 --- a/internal/fs/fs.go +++ b/internal/fs/fs.go @@ -40,32 +40,32 @@ func Link(ctx context.Context, path string, args model.LinkArgs) (*model.Link, m return res, file, nil } -func MakeDir(ctx context.Context, path string) error { - err := makeDir(ctx, path) +func MakeDir(ctx context.Context, path string, lazyCache ...bool) error { + err := makeDir(ctx, path, lazyCache...) if err != nil { log.Errorf("failed make dir %s: %+v", path, err) } return err } -func Move(ctx context.Context, srcPath, dstDirPath string) error { - err := move(ctx, srcPath, dstDirPath) +func Move(ctx context.Context, srcPath, dstDirPath string, lazyCache ...bool) error { + err := move(ctx, srcPath, dstDirPath, lazyCache...) if err != nil { log.Errorf("failed move %s to %s: %+v", srcPath, dstDirPath, err) } return err } -func Copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { - res, err := _copy(ctx, srcObjPath, dstDirPath) +func Copy(ctx context.Context, srcObjPath, dstDirPath string, lazyCache ...bool) (bool, error) { + res, err := _copy(ctx, srcObjPath, dstDirPath, lazyCache...) if err != nil { log.Errorf("failed copy %s to %s: %+v", srcObjPath, dstDirPath, err) } return res, err } -func Rename(ctx context.Context, srcPath, dstName string) error { - err := rename(ctx, srcPath, dstName) +func Rename(ctx context.Context, srcPath, dstName string, lazyCache ...bool) error { + err := rename(ctx, srcPath, dstName, lazyCache...) if err != nil { log.Errorf("failed rename %s to %s: %+v", srcPath, dstName, err) } @@ -80,8 +80,8 @@ func Remove(ctx context.Context, path string) error { return err } -func PutDirectly(ctx context.Context, dstDirPath string, file *model.FileStream) error { - err := putDirectly(ctx, dstDirPath, file) +func PutDirectly(ctx context.Context, dstDirPath string, file *model.FileStream, lazyCache ...bool) error { + err := putDirectly(ctx, dstDirPath, file, lazyCache...) if err != nil { log.Errorf("failed put %s: %+v", dstDirPath, err) } diff --git a/internal/fs/other.go b/internal/fs/other.go index f71cf576..85b7b1d1 100644 --- a/internal/fs/other.go +++ b/internal/fs/other.go @@ -9,15 +9,15 @@ import ( "github.com/pkg/errors" ) -func makeDir(ctx context.Context, path string) error { +func makeDir(ctx context.Context, path string, lazyCache ...bool) error { storage, actualPath, err := op.GetStorageAndActualPath(path) if err != nil { return errors.WithMessage(err, "failed get storage") } - return op.MakeDir(ctx, storage, actualPath) + return op.MakeDir(ctx, storage, actualPath, lazyCache...) } -func move(ctx context.Context, srcPath, dstDirPath string) error { +func move(ctx context.Context, srcPath, dstDirPath string, lazyCache ...bool) error { srcStorage, srcActualPath, err := op.GetStorageAndActualPath(srcPath) if err != nil { return errors.WithMessage(err, "failed get src storage") @@ -29,15 +29,15 @@ func move(ctx context.Context, srcPath, dstDirPath string) error { if srcStorage.GetStorage() != dstStorage.GetStorage() { return errors.WithStack(errs.MoveBetweenTwoStorages) } - return op.Move(ctx, srcStorage, srcActualPath, dstDirActualPath) + return op.Move(ctx, srcStorage, srcActualPath, dstDirActualPath, lazyCache...) } -func rename(ctx context.Context, srcPath, dstName string) error { +func rename(ctx context.Context, srcPath, dstName string, lazyCache ...bool) error { storage, srcActualPath, err := op.GetStorageAndActualPath(srcPath) if err != nil { return errors.WithMessage(err, "failed get storage") } - return op.Rename(ctx, storage, srcActualPath, dstName) + return op.Rename(ctx, storage, srcActualPath, dstName, lazyCache...) } func remove(ctx context.Context, path string) error { diff --git a/internal/fs/put.go b/internal/fs/put.go index 5adfb7f7..7eec268b 100644 --- a/internal/fs/put.go +++ b/internal/fs/put.go @@ -36,14 +36,14 @@ func putAsTask(dstDirPath string, file *model.FileStream) error { UploadTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ Name: fmt.Sprintf("upload %s to [%s](%s)", file.GetName(), storage.GetStorage().MountPath, dstDirActualPath), Func: func(task *task.Task[uint64]) error { - return op.Put(task.Ctx, storage, dstDirActualPath, file, nil) + return op.Put(task.Ctx, storage, dstDirActualPath, file, nil, true) }, })) return nil } // putDirect put the file and return after finish -func putDirectly(ctx context.Context, dstDirPath string, file *model.FileStream) error { +func putDirectly(ctx context.Context, dstDirPath string, file *model.FileStream, lazyCache ...bool) error { storage, dstDirActualPath, err := op.GetStorageAndActualPath(dstDirPath) if err != nil { return errors.WithMessage(err, "failed get storage") @@ -51,5 +51,5 @@ func putDirectly(ctx context.Context, dstDirPath string, file *model.FileStream) if storage.Config().NoUpload { return errors.WithStack(errs.UploadNotSupported) } - return op.Put(ctx, storage, dstDirActualPath, file, nil) + return op.Put(ctx, storage, dstDirActualPath, file, nil, lazyCache...) } diff --git a/internal/model/obj.go b/internal/model/obj.go index a81b318e..e57b7c83 100644 --- a/internal/model/obj.go +++ b/internal/model/obj.go @@ -99,12 +99,45 @@ func ExtractFolder(objs []Obj, extractFolder string) { }) } +// Wrap +func WrapObjName(objs Obj) Obj { + return &ObjWrapName{Obj: objs} +} + func WrapObjsName(objs []Obj) { for i := 0; i < len(objs); i++ { objs[i] = &ObjWrapName{Obj: objs[i]} } } +func UnwrapObjs(obj Obj) Obj { + if unwrap, ok := obj.(UnwrapObj); ok { + obj = unwrap.Unwrap() + } + return obj +} + +func GetThumb(obj Obj) (thumb string, ok bool) { + if obj, ok := obj.(Thumb); ok { + return obj.Thumb(), true + } + if unwrap, ok := obj.(UnwrapObj); ok { + return GetThumb(unwrap.Unwrap()) + } + return thumb, false +} + +func GetUrl(obj Obj) (url string, ok bool) { + if obj, ok := obj.(URL); ok { + return obj.URL(), true + } + if unwrap, ok := obj.(UnwrapObj); ok { + return GetUrl(unwrap.Unwrap()) + } + return url, false +} + +// Merge func NewObjMerge() *ObjMerge { return &ObjMerge{ set: mapset.NewSet[string](), diff --git a/internal/op/fs.go b/internal/op/fs.go index b5bd4e6f..e175ec2c 100644 --- a/internal/op/fs.go +++ b/internal/op/fs.go @@ -21,6 +21,49 @@ import ( var listCache = cache.NewMemCache(cache.WithShards[[]model.Obj](64)) var listG singleflight.Group[[]model.Obj] +func updateCacheObj(storage driver.Driver, path string, oldObj model.Obj, newObj model.Obj) { + key := Key(storage, path) + objs, ok := listCache.Get(key) + if ok { + for i, obj := range objs { + if obj.GetName() == oldObj.GetName() { + objs[i] = newObj + break + } + } + listCache.Set(key, objs, cache.WithEx[[]model.Obj](time.Minute*time.Duration(storage.GetStorage().CacheExpiration))) + } +} + +func delCacheObj(storage driver.Driver, path string, obj model.Obj) { + key := Key(storage, path) + objs, ok := listCache.Get(key) + if ok { + for i, oldObj := range objs { + if oldObj.GetName() == obj.GetName() { + objs = append(objs[:i], objs[i+1:]...) + break + } + } + listCache.Set(key, objs, cache.WithEx[[]model.Obj](time.Minute*time.Duration(storage.GetStorage().CacheExpiration))) + } +} + +func addCacheObj(storage driver.Driver, path string, newObj model.Obj) { + key := Key(storage, path) + objs, ok := listCache.Get(key) + if ok { + for i, obj := range objs { + if obj.GetName() == newObj.GetName() { + objs[i] = newObj + return + } + } + objs = append(objs, newObj) + listCache.Set(key, objs, cache.WithEx[[]model.Obj](time.Minute*time.Duration(storage.GetStorage().CacheExpiration))) + } +} + func ClearCache(storage driver.Driver, path string) { listCache.Del(Key(storage, path)) } @@ -37,7 +80,7 @@ func List(ctx context.Context, storage driver.Driver, path string, args model.Li path = utils.FixAndCleanPath(path) log.Debugf("op.List %s", path) key := Key(storage, path) - if len(refresh) == 0 || !refresh[0] { + if !utils.IsBool(refresh...) { if files, ok := listCache.Get(key); ok { log.Debugf("use cache when list %s", path) return files, nil @@ -148,10 +191,7 @@ func GetUnwrap(ctx context.Context, storage driver.Driver, path string) (model.O if err != nil { return nil, err } - if unwrap, ok := obj.(model.UnwrapObj); ok { - obj = unwrap.Unwrap() - } - return obj, err + return model.UnwrapObjs(obj), err } var linkCache = cache.NewMemCache(cache.WithShards[*model.Link](16)) @@ -169,7 +209,7 @@ func Link(ctx context.Context, storage driver.Driver, path string, args model.Li if file.IsDir() { return nil, nil, errors.WithStack(errs.NotFile) } - key := stdpath.Join(storage.GetStorage().MountPath, path) + ":" + args.IP + key := Key(storage, path) + ":" + args.IP if link, ok := linkCache.Get(key); ok { return link, file, nil } @@ -206,7 +246,7 @@ func Other(ctx context.Context, storage driver.Driver, args model.FsOtherArgs) ( var mkdirG singleflight.Group[interface{}] -func MakeDir(ctx context.Context, storage driver.Driver, path string) error { +func MakeDir(ctx context.Context, storage driver.Driver, path string, lazyCache ...bool) error { if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { return errors.Errorf("storage not init: %s", storage.GetStorage().Status) } @@ -227,32 +267,124 @@ func MakeDir(ctx context.Context, storage driver.Driver, path string) error { if err != nil { return nil, errors.WithMessagef(err, "failed to get parent dir [%s]", parentPath) } - err = storage.MakeDir(ctx, parentDir, dirName) - if err == nil { - ClearCache(storage, parentPath) + + switch s := storage.(type) { + case driver.MkdirResult: + var newObj model.Obj + newObj, err = s.MakeDir(ctx, parentDir, dirName) + if err == nil { + if newObj != nil { + addCacheObj(storage, parentPath, model.WrapObjName(newObj)) + } else if !utils.IsBool(lazyCache...) { + ClearCache(storage, parentPath) + } + } + case driver.Mkdir: + err = s.MakeDir(ctx, parentDir, dirName) + if err == nil && !utils.IsBool(lazyCache...) { + ClearCache(storage, parentPath) + } + default: + return nil, errs.NotImplement } return nil, errors.WithStack(err) - } else { - return nil, errors.WithMessage(err, "failed to check if dir exists") - } - } else { - // dir exists - if f.IsDir() { - return nil, nil - } else { - // dir to make is a file - return nil, errors.New("file exists") } + return nil, errors.WithMessage(err, "failed to check if dir exists") } + // dir exists + if f.IsDir() { + return nil, nil + } + // dir to make is a file + return nil, errors.New("file exists") }) return err - } -func Move(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string) error { +func Move(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string, lazyCache ...bool) error { if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { return errors.Errorf("storage not init: %s", storage.GetStorage().Status) } + srcPath = utils.FixAndCleanPath(srcPath) + dstDirPath = utils.FixAndCleanPath(dstDirPath) + srcRawObj, err := Get(ctx, storage, srcPath) + if err != nil { + return errors.WithMessage(err, "failed to get src object") + } + srcObj := model.UnwrapObjs(srcRawObj) + dstDir, err := GetUnwrap(ctx, storage, dstDirPath) + if err != nil { + return errors.WithMessage(err, "failed to get dst dir") + } + srcDirPath := stdpath.Dir(srcPath) + + switch s := storage.(type) { + case driver.MoveResult: + var newObj model.Obj + newObj, err = s.Move(ctx, srcObj, dstDir) + if err == nil { + delCacheObj(storage, srcDirPath, srcRawObj) + if newObj != nil { + addCacheObj(storage, dstDirPath, model.WrapObjName(newObj)) + } else if !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + } + case driver.Move: + err = s.Move(ctx, srcObj, dstDir) + if err == nil { + delCacheObj(storage, srcDirPath, srcRawObj) + if !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + } + default: + return errs.NotImplement + } + return errors.WithStack(err) +} + +func Rename(ctx context.Context, storage driver.Driver, srcPath, dstName string, lazyCache ...bool) error { + if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { + return errors.Errorf("storage not init: %s", storage.GetStorage().Status) + } + srcPath = utils.FixAndCleanPath(srcPath) + srcRawObj, err := Get(ctx, storage, srcPath) + if err != nil { + return errors.WithMessage(err, "failed to get src object") + } + srcObj := model.UnwrapObjs(srcRawObj) + srcDirPath := stdpath.Dir(srcPath) + + switch s := storage.(type) { + case driver.RenameResult: + var newObj model.Obj + newObj, err = s.Rename(ctx, srcObj, dstName) + if err == nil { + if newObj != nil { + updateCacheObj(storage, srcDirPath, srcRawObj, model.WrapObjName(newObj)) + } else if !utils.IsBool(lazyCache...) { + ClearCache(storage, srcDirPath) + } + } + case driver.Rename: + err = s.Rename(ctx, srcObj, dstName) + if err == nil && !utils.IsBool(lazyCache...) { + ClearCache(storage, srcDirPath) + } + default: + return errs.NotImplement + } + return errors.WithStack(err) +} + +// Copy Just copy file[s] in a storage +func Copy(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string, lazyCache ...bool) error { + if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { + return errors.Errorf("storage not init: %s", storage.GetStorage().Status) + } + srcPath = utils.FixAndCleanPath(srcPath) + dstDirPath = utils.FixAndCleanPath(dstDirPath) srcObj, err := GetUnwrap(ctx, storage, srcPath) if err != nil { return errors.WithMessage(err, "failed to get src object") @@ -261,38 +393,35 @@ func Move(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string if err != nil { return errors.WithMessage(err, "failed to get dst dir") } - return errors.WithStack(storage.Move(ctx, srcObj, dstDir)) -} -func Rename(ctx context.Context, storage driver.Driver, srcPath, dstName string) error { - if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { - return errors.Errorf("storage not init: %s", storage.GetStorage().Status) + switch s := storage.(type) { + case driver.CopyResult: + var newObj model.Obj + newObj, err = s.Copy(ctx, srcObj, dstDir) + if err == nil { + if newObj != nil { + addCacheObj(storage, dstDirPath, model.WrapObjName(newObj)) + } else if !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + } + case driver.Copy: + err = s.Copy(ctx, srcObj, dstDir) + if err == nil && !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + default: + return errs.NotImplement } - srcObj, err := GetUnwrap(ctx, storage, srcPath) - if err != nil { - return errors.WithMessage(err, "failed to get src object") - } - return errors.WithStack(storage.Rename(ctx, srcObj, dstName)) -} - -// Copy Just copy file[s] in a storage -func Copy(ctx context.Context, storage driver.Driver, srcPath, dstDirPath string) error { - if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { - return errors.Errorf("storage not init: %s", storage.GetStorage().Status) - } - srcObj, err := GetUnwrap(ctx, storage, srcPath) - if err != nil { - return errors.WithMessage(err, "failed to get src object") - } - dstDir, err := GetUnwrap(ctx, storage, dstDirPath) - return errors.WithStack(storage.Copy(ctx, srcObj, dstDir)) + return errors.WithStack(err) } func Remove(ctx context.Context, storage driver.Driver, path string) error { if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { return errors.Errorf("storage not init: %s", storage.GetStorage().Status) } - obj, err := GetUnwrap(ctx, storage, path) + path = utils.FixAndCleanPath(path) + rawObj, err := Get(ctx, storage, path) if err != nil { // if object not found, it's ok if errs.IsObjectNotFound(err) { @@ -300,31 +429,21 @@ func Remove(ctx context.Context, storage driver.Driver, path string) error { } return errors.WithMessage(err, "failed to get object") } - err = storage.Remove(ctx, obj) - if err == nil { - key := Key(storage, stdpath.Dir(path)) - if objs, ok := listCache.Get(key); ok { - j := -1 - for i, m := range objs { - if m.GetName() == obj.GetName() { - j = i - break - } - } - if j >= 0 && j < len(objs) { - objs = append(objs[:j], objs[j+1:]...) - listCache.Set(key, objs) - } else { - log.Debugf("not found obj") - } - } else { - log.Debugf("not found parent cache") + dirPath := stdpath.Dir(path) + + switch s := storage.(type) { + case driver.Remove: + err = s.Remove(ctx, model.UnwrapObjs(rawObj)) + if err == nil { + delCacheObj(storage, dirPath, rawObj) } + default: + return errs.NotImplement } return errors.WithStack(err) } -func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *model.FileStream, up driver.UpdateProgress) error { +func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *model.FileStream, up driver.UpdateProgress, lazyCache ...bool) error { if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { return errors.Errorf("storage not init: %s", storage.GetStorage().Status) } @@ -342,6 +461,7 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *mo } }() // if file exist and size = 0, delete it + dstDirPath = utils.FixAndCleanPath(dstDirPath) dstPath := stdpath.Join(dstDirPath, file.GetName()) fi, err := GetUnwrap(ctx, storage, dstPath) if err == nil { @@ -367,7 +487,26 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *mo if up == nil { up = func(p int) {} } - err = storage.Put(ctx, parentDir, file, up) + + switch s := storage.(type) { + case driver.PutResult: + var newObj model.Obj + newObj, err = s.Put(ctx, parentDir, file, up) + if err == nil { + if newObj != nil { + addCacheObj(storage, dstDirPath, model.WrapObjName(newObj)) + } else if !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + } + case driver.Put: + err = s.Put(ctx, parentDir, file, up) + if err == nil && !utils.IsBool(lazyCache...) { + ClearCache(storage, dstDirPath) + } + default: + return errs.NotImplement + } log.Debugf("put file [%s] done", file.GetName()) //if err == nil { // //clear cache diff --git a/pkg/utils/bool.go b/pkg/utils/bool.go new file mode 100644 index 00000000..eecf550b --- /dev/null +++ b/pkg/utils/bool.go @@ -0,0 +1,5 @@ +package utils + +func IsBool(bs ...bool) bool { + return len(bs) > 0 && bs[0] +} diff --git a/server/handles/fsmanage.go b/server/handles/fsmanage.go index 7b95af5b..7bab2709 100644 --- a/server/handles/fsmanage.go +++ b/server/handles/fsmanage.go @@ -48,7 +48,6 @@ func FsMkdir(c *gin.Context) { common.ErrorResp(c, err, 500) return } - fs.ClearCache(stdpath.Dir(reqPath)) common.SuccessResp(c) } @@ -83,15 +82,13 @@ func FsMove(c *gin.Context) { common.ErrorResp(c, err, 403) return } - for _, name := range req.Names { - err := fs.Move(c, stdpath.Join(srcDir, name), dstDir) + for i, name := range req.Names { + err := fs.Move(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1) if err != nil { common.ErrorResp(c, err, 500) return } } - fs.ClearCache(srcDir) - fs.ClearCache(dstDir) common.SuccessResp(c) } @@ -121,8 +118,8 @@ func FsCopy(c *gin.Context) { return } var addedTask []string - for _, name := range req.Names { - ok, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir) + for i, name := range req.Names { + ok, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1) if ok { addedTask = append(addedTask, name) } @@ -131,9 +128,6 @@ func FsCopy(c *gin.Context) { return } } - if len(req.Names) != len(addedTask) { - fs.ClearCache(dstDir) - } if len(addedTask) > 0 { common.SuccessResp(c, fmt.Sprintf("Added %d tasks", len(addedTask))) } else { @@ -166,7 +160,6 @@ func FsRename(c *gin.Context) { common.ErrorResp(c, err, 500) return } - fs.ClearCache(stdpath.Dir(reqPath)) common.SuccessResp(c) } diff --git a/server/handles/fsread.go b/server/handles/fsread.go index 4d4d617a..83c14ed9 100644 --- a/server/handles/fsread.go +++ b/server/handles/fsread.go @@ -191,10 +191,7 @@ func pagination(objs []model.Obj, req *model.PageReq) (int, []model.Obj) { func toObjsResp(objs []model.Obj, parent string, encrypt bool) []ObjResp { var resp []ObjResp for _, obj := range objs { - thumb := "" - if t, ok := obj.(model.Thumb); ok { - thumb = t.Thumb() - } + thumb, _ := model.GetThumb(obj) resp = append(resp, ObjResp{ Name: obj.GetName(), Size: obj.GetSize(), @@ -276,8 +273,8 @@ func FsGet(c *gin.Context) { } } else { // file have raw url - if u, ok := obj.(model.URL); ok { - rawURL = u.URL() + if url, ok := model.GetUrl(obj); ok { + rawURL = url } else { // if storage is not proxy, use raw url by fs.Link link, _, err := fs.Link(c, reqPath, model.LinkArgs{IP: c.ClientIP(), Header: c.Request.Header}) diff --git a/server/handles/fsup.go b/server/handles/fsup.go index b32fca50..a8ddb0ab 100644 --- a/server/handles/fsup.go +++ b/server/handles/fsup.go @@ -46,7 +46,7 @@ func FsStream(c *gin.Context) { if asTask { err = fs.PutAsTask(dir, stream) } else { - err = fs.PutDirectly(c, dir, stream) + err = fs.PutDirectly(c, dir, stream, true) } if err != nil { common.ErrorResp(c, err, 500) @@ -102,7 +102,7 @@ func FsForm(c *gin.Context) { if asTask { err = fs.PutAsTask(dir, stream) } else { - err = fs.PutDirectly(c, dir, stream) + err = fs.PutDirectly(c, dir, stream, true) } if err != nil { common.ErrorResp(c, err, 500) diff --git a/server/webdav/file.go b/server/webdav/file.go index c053a4cb..36e3dc11 100644 --- a/server/webdav/file.go +++ b/server/webdav/file.go @@ -46,8 +46,6 @@ func moveFiles(ctx context.Context, src, dst string, overwrite bool) (status int if err != nil { return http.StatusInternalServerError, err } - fs.ClearCache(srcDir) - fs.ClearCache(dstDir) // TODO if there are no files copy, should return 204 return http.StatusCreated, nil } @@ -60,7 +58,6 @@ func copyFiles(ctx context.Context, src, dst string, overwrite bool) (status int if err != nil { return http.StatusInternalServerError, err } - fs.ClearCache(path.Dir(dst)) // TODO if there are no files copy, should return 204 return http.StatusCreated, nil } diff --git a/server/webdav/webdav.go b/server/webdav/webdav.go index 7ab8dbf5..9f856e4f 100644 --- a/server/webdav/webdav.go +++ b/server/webdav/webdav.go @@ -337,7 +337,6 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int, return http.StatusInternalServerError, err } w.Header().Set("ETag", etag) - fs.ClearCache(path.Dir(reqPath)) return http.StatusCreated, nil } @@ -368,7 +367,6 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in } return http.StatusMethodNotAllowed, err } - fs.ClearCache(path.Dir(reqPath)) return http.StatusCreated, nil }