refactor: filesystem struct

refactor/fs
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
// 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)
},
}))
}

View File

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

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