Merge 5d976c7b3769bd685be5e4e8ae60d4a83652fb70 into 41bdab49aa8acca9e88862c3db55cd7a8a84ba6a

This commit is contained in:
5aaee9 2025-04-19 14:56:29 +08:00 committed by GitHub
commit 22b6130a54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 6 deletions

View File

@ -12,8 +12,7 @@ var (
NotSupport = errors.New("not support")
RelativePath = errors.New("access using relative path is not allowed")
MoveBetweenTwoStorages = errors.New("can't move files between two storages, try to copy")
UploadNotSupported = errors.New("upload not supported")
UploadNotSupported = errors.New("upload not supported")
MetaNotFound = errors.New("meta not found")
StorageNotFound = errors.New("storage not found")

View File

@ -3,11 +3,14 @@ package fs
import (
"context"
"fmt"
"github.com/alist-org/alist/v3/internal/errs"
"net/http"
stdpath "path"
"sync"
"sync/atomic"
"time"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
@ -19,6 +22,7 @@ import (
"github.com/xhofe/tache"
)
type CopyCallback func(t *CopyTask) error
type CopyTask struct {
task.TaskExtension
Status string `json:"-"` //don't save status to save space
@ -28,6 +32,7 @@ type CopyTask struct {
dstStorage driver.Driver `json:"-"`
SrcStorageMp string `json:"src_storage_mp"`
DstStorageMp string `json:"dst_storage_mp"`
Callback CopyCallback `json:"-"`
}
func (t *CopyTask) GetName() string {
@ -53,7 +58,16 @@ func (t *CopyTask) Run() error {
if err != nil {
return errors.WithMessage(err, "failed get storage")
}
return copyBetween2Storages(t, t.srcStorage, t.dstStorage, t.SrcObjPath, t.DstDirPath)
err = copyBetween2Storages(t, t.srcStorage, t.dstStorage, t.SrcObjPath, t.DstDirPath)
if err != nil {
return err
}
if t.Callback != nil {
return t.Callback(t)
}
return nil
}
var CopyTaskManager *tache.Manager[*CopyTask]
@ -130,12 +144,16 @@ func copyBetween2Storages(t *CopyTask, srcStorage, dstStorage driver.Driver, src
if err != nil {
return errors.WithMessagef(err, "failed list src [%s] objs", srcObjPath)
}
var wg sync.WaitGroup
var doneCount uint64 = 0
totalTaskCount := len(objs)
for _, obj := range objs {
if utils.IsCanceled(t.Ctx()) {
return nil
}
srcObjPath := stdpath.Join(srcObjPath, obj.GetName())
dstObjPath := stdpath.Join(dstDirPath, srcObj.GetName())
wg.Add(1)
CopyTaskManager.Add(&CopyTask{
TaskExtension: task.TaskExtension{
Creator: t.GetCreator(),
@ -146,9 +164,17 @@ func copyBetween2Storages(t *CopyTask, srcStorage, dstStorage driver.Driver, src
DstDirPath: dstObjPath,
SrcStorageMp: srcStorage.GetStorage().MountPath,
DstStorageMp: dstStorage.GetStorage().MountPath,
Callback: func(ct *CopyTask) error {
atomic.AddUint64(&doneCount, 1)
t.SetProgress(100 * (float64(doneCount) / float64(totalTaskCount)))
wg.Done()
return nil
},
})
}
t.Status = "src object is dir, added all copy tasks of objs"
wg.Wait()
return nil
}
return copyFileBetween2Storages(t, srcStorage, dstStorage, srcObjPath, dstDirPath)

View File

@ -3,9 +3,9 @@ package fs
import (
"context"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/internal/task"
"github.com/pkg/errors"
)
@ -27,7 +27,22 @@ func move(ctx context.Context, srcPath, dstDirPath string, lazyCache ...bool) er
return errors.WithMessage(err, "failed get dst storage")
}
if srcStorage.GetStorage() != dstStorage.GetStorage() {
return errors.WithStack(errs.MoveBetweenTwoStorages)
taskCreator, _ := ctx.Value("user").(*model.User)
CopyTaskManager.Add(&CopyTask{
TaskExtension: task.TaskExtension{
Creator: taskCreator,
},
srcStorage: srcStorage,
dstStorage: dstStorage,
SrcObjPath: srcActualPath,
DstDirPath: dstDirActualPath,
SrcStorageMp: srcStorage.GetStorage().MountPath,
DstStorageMp: dstStorage.GetStorage().MountPath,
Callback: func(t *CopyTask) error {
return op.Remove(t.Ctx(), srcStorage, srcActualPath)
},
})
return nil
}
return op.Move(ctx, srcStorage, srcActualPath, dstDirActualPath, lazyCache...)
}