refactor: filesystem struct

This commit is contained in:
Noah Hsu 2022-07-27 17:09:48 +08:00
parent b399c924b7
commit 06f3618897
3 changed files with 86 additions and 26 deletions

View File

@ -21,8 +21,8 @@ var CopyTaskManager = task.NewTaskManager(3, func(tid *uint64) {
// Copy if in the same storage, call move method // Copy if in the same storage, call move method
// if not, add copy task // if not, add copy task
func _copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { func _copy(ctx context.Context, srcPath, dstDirPath string) (bool, error) {
srcStorage, srcObjActualPath, err := operations.GetStorageAndActualPath(srcObjPath) srcStorage, srcActualPath, err := operations.GetStorageAndActualPath(srcPath)
if err != nil { if err != nil {
return false, errors.WithMessage(err, "failed get src storage") 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 // copy if in the same storage, just call driver.Copy
if srcStorage.GetStorage() == dstStorage.GetStorage() { 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 // not in the same storage
CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ 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 { Func: func(task *task.Task[uint64]) error {
return copyBetween2Storages(task, srcStorage, dstStorage, srcObjActualPath, dstDirActualPath) return copyBetween2Storages(task, srcStorage, dstStorage, srcActualPath, dstDirActualPath)
}, },
})) }))
return true, nil 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") t.SetStatus("getting src object")
srcObj, err := operations.Get(t.Ctx, srcStorage, srcObjPath) srcObj, err := operations.Get(t.Ctx, srcStorage, srcPath)
if err != nil { 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() { if srcObj.IsDir() {
t.SetStatus("src object is dir, listing objs") 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 { 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 { for _, obj := range objs {
if utils.IsCanceled(t.Ctx) { if utils.IsCanceled(t.Ctx) {
return nil return nil
} }
srcObjPath := stdpath.Join(srcObjPath, obj.GetName()) srcObjPath := stdpath.Join(srcPath, obj.GetName())
dstObjPath := stdpath.Join(dstDirPath, obj.GetName()) dstObjPath := stdpath.Join(dstDirPath, obj.GetName())
CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{
Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcObjPath, dstStorage.GetStorage().MountPath, dstObjPath), 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 { } else {
CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ 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 { Func: func(t *task.Task[uint64]) error {
return copyFileBetween2Storages(t, srcStorage, dstStorage, srcObjPath, dstDirPath) return copyFileBetween2Storages(t, srcStorage, dstStorage, srcPath, dstDirPath)
}, },
})) }))
} }

View File

@ -6,13 +6,33 @@ import (
"github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/operations" "github.com/alist-org/alist/v3/internal/operations"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
stdpath "path"
) )
// the param named path of functions in this package is a virtual 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 // So, the purpose of this package is to convert virtual path to actual path
// then pass the actual path to the operations package // 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) res, err := list(ctx, path)
if err != nil { if err != nil {
log.Errorf("failed list %s: %+v", path, err) 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 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) res, err := get(ctx, path)
if err != nil { if err != nil {
log.Errorf("failed get %s: %+v", path, err) 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 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) res, file, err := link(ctx, path, args)
if err != nil { if err != nil {
log.Errorf("failed link %s: %+v", path, err) 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 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) err := makeDir(ctx, path)
if err != nil { if err != nil {
log.Errorf("failed make dir %s: %+v", path, err) log.Errorf("failed make dir %s: %+v", path, err)
@ -47,7 +70,9 @@ func MakeDir(ctx context.Context, path string) error {
return err 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) err := move(ctx, srcPath, dstDirPath)
if err != nil { if err != nil {
log.Errorf("failed move %s to %s: %+v", srcPath, dstDirPath, err) 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 return err
} }
func Copy(ctx context.Context, srcObjPath, dstDirPath string) (bool, error) { func (fs *FileSystem) Copy(ctx context.Context, srcPath string, dstDirPath string) (bool, error) {
res, err := _copy(ctx, srcObjPath, dstDirPath) srcPath = stdpath.Join(fs.User.BasePath, srcPath)
dstDirPath = stdpath.Join(fs.User.BasePath, dstDirPath)
res, err := _copy(ctx, srcPath, dstDirPath)
if err != nil { 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 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) err := rename(ctx, srcPath, dstName)
if err != nil { if err != nil {
log.Errorf("failed rename %s to %s: %+v", srcPath, dstName, err) 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 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) err := remove(ctx, path)
if err != nil { if err != nil {
log.Errorf("failed remove %s: %+v", path, err) log.Errorf("failed remove %s: %+v", path, err)
@ -79,7 +108,8 @@ func Remove(ctx context.Context, path string) error {
return err 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) err := putDirectly(ctx, dstDirPath, file)
if err != nil { if err != nil {
log.Errorf("failed put %s: %+v", dstDirPath, err) log.Errorf("failed put %s: %+v", dstDirPath, err)
@ -87,7 +117,8 @@ func PutDirectly(ctx context.Context, dstDirPath string, file model.FileStreamer
return err 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) err := putAsTask(dstDirPath, file)
if err != nil { if err != nil {
log.Errorf("failed put %s: %+v", dstDirPath, err) log.Errorf("failed put %s: %+v", dstDirPath, err)
@ -95,10 +126,13 @@ func PutAsTask(dstDirPath string, file model.FileStreamer) error {
return err 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) storageDriver, _, err := operations.GetStorageAndActualPath(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return storageDriver, nil return storageDriver, nil
} }
var _ Fs = (*FileSystem)(nil)

26
internal/fs/pool.go Normal file
View File

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