From 06f3618897acc6731ad4c58f7d717252d98b7e73 Mon Sep 17 00:00:00 2001 From: Noah Hsu Date: Wed, 27 Jul 2022 17:09:48 +0800 Subject: [PATCH] refactor: filesystem struct --- internal/fs/copy.go | 26 ++++++++++---------- internal/fs/fs.go | 60 +++++++++++++++++++++++++++++++++++---------- internal/fs/pool.go | 26 ++++++++++++++++++++ 3 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 internal/fs/pool.go diff --git a/internal/fs/copy.go b/internal/fs/copy.go index 1b4463c1..7b0871cc 100644 --- a/internal/fs/copy.go +++ b/internal/fs/copy.go @@ -21,8 +21,8 @@ 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) { - srcStorage, srcObjActualPath, err := operations.GetStorageAndActualPath(srcObjPath) +func _copy(ctx context.Context, srcPath, dstDirPath string) (bool, error) { + srcStorage, srcActualPath, err := operations.GetStorageAndActualPath(srcPath) if err != nil { return false, errors.WithMessage(err, "failed get src storage") } @@ -32,35 +32,35 @@ 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, operations.Copy(ctx, srcStorage, srcObjActualPath, dstDirActualPath) + return false, operations.Copy(ctx, srcStorage, srcActualPath, dstDirActualPath) } // not in the same storage CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ - Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcObjActualPath, dstStorage.GetStorage().MountPath, dstDirActualPath), + Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcActualPath, dstStorage.GetStorage().MountPath, dstDirActualPath), Func: func(task *task.Task[uint64]) error { - return copyBetween2Storages(task, srcStorage, dstStorage, srcObjActualPath, dstDirActualPath) + return copyBetween2Storages(task, srcStorage, dstStorage, srcActualPath, dstDirActualPath) }, })) return true, nil } -func copyBetween2Storages(t *task.Task[uint64], srcStorage, dstStorage driver.Driver, srcObjPath, dstDirPath string) error { +func copyBetween2Storages(t *task.Task[uint64], srcStorage, dstStorage driver.Driver, srcPath, dstDirPath string) error { t.SetStatus("getting src object") - srcObj, err := operations.Get(t.Ctx, srcStorage, srcObjPath) + srcObj, err := operations.Get(t.Ctx, srcStorage, srcPath) if err != nil { - return errors.WithMessagef(err, "failed get src [%s] file", srcObjPath) + return errors.WithMessagef(err, "failed get src [%s] file", srcPath) } if srcObj.IsDir() { t.SetStatus("src object is dir, listing objs") - objs, err := operations.List(t.Ctx, srcStorage, srcObjPath) + objs, err := operations.List(t.Ctx, srcStorage, srcPath) if err != nil { - return errors.WithMessagef(err, "failed list src [%s] objs", srcObjPath) + return errors.WithMessagef(err, "failed list src [%s] objs", srcPath) } for _, obj := range objs { if utils.IsCanceled(t.Ctx) { return nil } - srcObjPath := stdpath.Join(srcObjPath, obj.GetName()) + srcObjPath := stdpath.Join(srcPath, obj.GetName()) dstObjPath := stdpath.Join(dstDirPath, obj.GetName()) CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcObjPath, dstStorage.GetStorage().MountPath, dstObjPath), @@ -71,9 +71,9 @@ func copyBetween2Storages(t *task.Task[uint64], srcStorage, dstStorage driver.Dr } } else { CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ - Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcObjPath, dstStorage.GetStorage().MountPath, dstDirPath), + Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcPath, dstStorage.GetStorage().MountPath, dstDirPath), Func: func(t *task.Task[uint64]) error { - return copyFileBetween2Storages(t, srcStorage, dstStorage, srcObjPath, dstDirPath) + return copyFileBetween2Storages(t, srcStorage, dstStorage, srcPath, dstDirPath) }, })) } diff --git a/internal/fs/fs.go b/internal/fs/fs.go index b811e9be..c3ad0f00 100644 --- a/internal/fs/fs.go +++ b/internal/fs/fs.go @@ -6,13 +6,33 @@ import ( "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/operations" log "github.com/sirupsen/logrus" + stdpath "path" ) // the param named path of functions in this package is a virtual path // So, the purpose of this package is to convert virtual path to actual path // then pass the actual path to the operations package -func List(ctx context.Context, path string) ([]model.Obj, error) { +type Fs interface { + List(ctx context.Context, path string) ([]model.Obj, error) + Get(ctx context.Context, path string) (model.Obj, error) + Link(ctx context.Context, path string, args model.LinkArgs) (*model.Link, model.Obj, error) + MakeDir(ctx context.Context, path string) error + Move(ctx context.Context, srcPath string, dstDirPath string) error + Copy(ctx context.Context, srcObjPath string, dstDirPath string) (bool, error) + Rename(ctx context.Context, srcPath, dstName string) error + Remove(ctx context.Context, path string) error + PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer) error + PutAsTask(dstDirPath string, file model.FileStreamer) error + GetStorage(path string) (driver.Driver, error) +} + +type FileSystem struct { + User *model.User +} + +func (fs *FileSystem) List(ctx context.Context, path string) ([]model.Obj, error) { + path = stdpath.Join(fs.User.BasePath, path) res, err := list(ctx, path) if err != nil { log.Errorf("failed list %s: %+v", path, err) @@ -21,7 +41,8 @@ func List(ctx context.Context, path string) ([]model.Obj, error) { return res, nil } -func Get(ctx context.Context, path string) (model.Obj, error) { +func (fs *FileSystem) Get(ctx context.Context, path string) (model.Obj, error) { + path = stdpath.Join(fs.User.BasePath, path) res, err := get(ctx, path) if err != nil { log.Errorf("failed get %s: %+v", path, err) @@ -30,7 +51,8 @@ func Get(ctx context.Context, path string) (model.Obj, error) { return res, nil } -func Link(ctx context.Context, path string, args model.LinkArgs) (*model.Link, model.Obj, error) { +func (fs *FileSystem) Link(ctx context.Context, path string, args model.LinkArgs) (*model.Link, model.Obj, error) { + path = stdpath.Join(fs.User.BasePath, path) res, file, err := link(ctx, path, args) if err != nil { log.Errorf("failed link %s: %+v", path, err) @@ -39,7 +61,8 @@ 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 { +func (fs *FileSystem) MakeDir(ctx context.Context, path string) error { + path = stdpath.Join(fs.User.BasePath, path) err := makeDir(ctx, path) if err != nil { log.Errorf("failed make dir %s: %+v", path, err) @@ -47,7 +70,9 @@ func MakeDir(ctx context.Context, path string) error { return err } -func Move(ctx context.Context, srcPath, dstDirPath string) error { +func (fs *FileSystem) Move(ctx context.Context, srcPath string, dstDirPath string) error { + srcPath = stdpath.Join(fs.User.BasePath, srcPath) + dstDirPath = stdpath.Join(fs.User.BasePath, dstDirPath) err := move(ctx, srcPath, dstDirPath) if err != nil { log.Errorf("failed move %s to %s: %+v", srcPath, dstDirPath, err) @@ -55,15 +80,18 @@ func Move(ctx context.Context, srcPath, dstDirPath string) error { return err } -func Copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { - res, err := _copy(ctx, srcObjPath, dstDirPath) +func (fs *FileSystem) Copy(ctx context.Context, srcPath string, dstDirPath string) (bool, error) { + srcPath = stdpath.Join(fs.User.BasePath, srcPath) + dstDirPath = stdpath.Join(fs.User.BasePath, dstDirPath) + res, err := _copy(ctx, srcPath, dstDirPath) if err != nil { - log.Errorf("failed copy %s to %s: %+v", srcObjPath, dstDirPath, err) + log.Errorf("failed copy %s to %s: %+v", srcPath, dstDirPath, err) } return res, err } -func Rename(ctx context.Context, srcPath, dstName string) error { +func (fs *FileSystem) Rename(ctx context.Context, srcPath, dstName string) error { + srcPath = stdpath.Join(fs.User.BasePath, srcPath) err := rename(ctx, srcPath, dstName) if err != nil { log.Errorf("failed rename %s to %s: %+v", srcPath, dstName, err) @@ -71,7 +99,8 @@ func Rename(ctx context.Context, srcPath, dstName string) error { return err } -func Remove(ctx context.Context, path string) error { +func (fs *FileSystem) Remove(ctx context.Context, path string) error { + path = stdpath.Join(fs.User.BasePath, path) err := remove(ctx, path) if err != nil { log.Errorf("failed remove %s: %+v", path, err) @@ -79,7 +108,8 @@ func Remove(ctx context.Context, path string) error { return err } -func PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer) error { +func (fs *FileSystem) PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer) error { + dstDirPath = stdpath.Join(fs.User.BasePath, dstDirPath) err := putDirectly(ctx, dstDirPath, file) if err != nil { log.Errorf("failed put %s: %+v", dstDirPath, err) @@ -87,7 +117,8 @@ func PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer return err } -func PutAsTask(dstDirPath string, file model.FileStreamer) error { +func (fs *FileSystem) PutAsTask(dstDirPath string, file model.FileStreamer) error { + dstDirPath = stdpath.Join(fs.User.BasePath, dstDirPath) err := putAsTask(dstDirPath, file) if err != nil { log.Errorf("failed put %s: %+v", dstDirPath, err) @@ -95,10 +126,13 @@ func PutAsTask(dstDirPath string, file model.FileStreamer) error { return err } -func GetStorage(path string) (driver.Driver, error) { +func (fs *FileSystem) GetStorage(path string) (driver.Driver, error) { + path = stdpath.Join(fs.User.BasePath, path) storageDriver, _, err := operations.GetStorageAndActualPath(path) if err != nil { return nil, err } return storageDriver, nil } + +var _ Fs = (*FileSystem)(nil) diff --git a/internal/fs/pool.go b/internal/fs/pool.go new file mode 100644 index 00000000..a21caf1e --- /dev/null +++ b/internal/fs/pool.go @@ -0,0 +1,26 @@ +package fs + +import ( + "github.com/alist-org/alist/v3/internal/model" + "sync" +) + +var FsPool = sync.Pool{ + New: func() any { + return &FileSystem{} + }, +} + +func getEmptyFs() *FileSystem { + return FsPool.Get().(*FileSystem) +} + +func New(user *model.User) Fs { + fs := getEmptyFs() + fs.User = user + return fs +} + +func Recycle(fs Fs) { + FsPool.Put(fs) +}