diff --git a/drivers/local/driver.go b/drivers/local/driver.go index fc49e142e98..d3cdcd0b365 100644 --- a/drivers/local/driver.go +++ b/drivers/local/driver.go @@ -175,9 +175,9 @@ func (d *Local) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { dstPath := filepath.Join(dstDir.GetPath(), srcObj.GetName()) var err error if srcObj.IsDir() { - err = copyDir(srcPath, dstPath) + err = utils.CopyDir(srcPath, dstPath) } else { - err = copyFile(srcPath, dstPath) + err = utils.CopyFile(srcPath, dstPath) } if err != nil { return err diff --git a/drivers/local/util.go b/drivers/local/util.go index 866bf1667e1..469c3dc0d8c 100644 --- a/drivers/local/util.go +++ b/drivers/local/util.go @@ -1,67 +1 @@ package local - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path" -) - -// copyFile File copies a single file from src to dst -func copyFile(src, dst string) error { - var err error - var srcfd *os.File - var dstfd *os.File - var srcinfo os.FileInfo - - if srcfd, err = os.Open(src); err != nil { - return err - } - defer srcfd.Close() - - if dstfd, err = os.Create(dst); err != nil { - return err - } - defer dstfd.Close() - - if _, err = io.Copy(dstfd, srcfd); err != nil { - return err - } - if srcinfo, err = os.Stat(src); err != nil { - return err - } - return os.Chmod(dst, srcinfo.Mode()) -} - -// copyDir Dir copies a whole directory recursively -func copyDir(src string, dst string) error { - var err error - var fds []os.FileInfo - var srcinfo os.FileInfo - - if srcinfo, err = os.Stat(src); err != nil { - return err - } - if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil { - return err - } - if fds, err = ioutil.ReadDir(src); err != nil { - return err - } - for _, fd := range fds { - srcfp := path.Join(src, fd.Name()) - dstfp := path.Join(dst, fd.Name()) - - if fd.IsDir() { - if err = copyDir(srcfp, dstfp); err != nil { - fmt.Println(err) - } - } else { - if err = copyFile(srcfp, dstfp); err != nil { - fmt.Println(err) - } - } - } - return nil -} diff --git a/internal/fs/copy.go b/internal/fs/copy.go index 825a3b1a9d2..9f3871fdec0 100644 --- a/internal/fs/copy.go +++ b/internal/fs/copy.go @@ -12,6 +12,7 @@ import ( "github.com/alist-org/alist/v3/pkg/task" "github.com/alist-org/alist/v3/pkg/utils" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) var CopyTaskManager = task.NewTaskManager(3, func(tid *uint64) { @@ -60,7 +61,7 @@ func copyBetween2Storages(t *task.Task[uint64], srcStorage, dstStorage driver.Dr return nil } srcObjPath := stdpath.Join(srcObjPath, obj.GetName()) - dstObjPath := stdpath.Join(dstDirPath, obj.GetName()) + dstObjPath := stdpath.Join(dstDirPath, srcObj.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), Func: func(t *task.Task[uint64]) error { @@ -72,7 +73,9 @@ func copyBetween2Storages(t *task.Task[uint64], srcStorage, dstStorage driver.Dr CopyTaskManager.Submit(task.WithCancelCtx(&task.Task[uint64]{ Name: fmt.Sprintf("copy [%s](%s) to [%s](%s)", srcStorage.GetStorage().MountPath, srcObjPath, dstStorage.GetStorage().MountPath, dstDirPath), Func: func(t *task.Task[uint64]) error { - return copyFileBetween2Storages(t, srcStorage, dstStorage, srcObjPath, dstDirPath) + err := copyFileBetween2Storages(t, srcStorage, dstStorage, srcObjPath, dstDirPath) + log.Debugf("copy file between storages: %+v", err) + return err }, })) } diff --git a/internal/fs/util.go b/internal/fs/util.go index 10ee9e8122f..3f41641ec3f 100644 --- a/internal/fs/util.go +++ b/internal/fs/util.go @@ -1,6 +1,7 @@ package fs import ( + "fmt" "io" "mime" "net/http" @@ -8,8 +9,11 @@ import ( stdpath "path" "strings" + "github.com/alist-org/alist/v3/internal/conf" "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/pkg/utils" + "github.com/google/uuid" "github.com/pkg/errors" ) @@ -38,7 +42,13 @@ func getFileStreamFromLink(file model.Obj, link *model.Link) (model.FileStreamer if link.Data != nil { rc = link.Data } else if link.FilePath != nil { - f, err := os.Open(*link.FilePath) + // copy a new temp, because will be deleted after upload + newFilePath := stdpath.Join(conf.Conf.TempDir, fmt.Sprintf("%s-%s", uuid.NewString(), file.GetName())) + err := utils.CopyFile(*link.FilePath, newFilePath) + if err != nil { + return nil, err + } + f, err := os.Open(newFilePath) if err != nil { return nil, errors.Wrapf(err, "failed to open file %s", *link.FilePath) } diff --git a/internal/op/fs.go b/internal/op/fs.go index 88ffc5546d7..564b5eaefb9 100644 --- a/internal/op/fs.go +++ b/internal/op/fs.go @@ -338,12 +338,10 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file mod } err = storage.Put(ctx, parentDir, file, up) log.Debugf("put file [%s] done", file.GetName()) - if err == nil { - // set as complete - up(100) - // clear cache - //key := stdpath.Join(storage.GetStorage().MountPath, dstDirPath) - //listCache.Del(key) - } + //if err == nil { + // //clear cache + // key := stdpath.Join(storage.GetStorage().MountPath, dstDirPath) + // listCache.Del(key) + //} return errors.WithStack(err) } diff --git a/pkg/task/task.go b/pkg/task/task.go index 8a44286e642..eb1e7b5d588 100644 --- a/pkg/task/task.go +++ b/pkg/task/task.go @@ -82,6 +82,7 @@ func (t *Task[K]) run() { t.state = ERRORED } else { t.state = SUCCEEDED + t.SetProgress(100) if t.callback != nil { t.callback(t) } diff --git a/pkg/utils/file.go b/pkg/utils/file.go index 614260b4c17..4e66d039e42 100644 --- a/pkg/utils/file.go +++ b/pkg/utils/file.go @@ -1,8 +1,11 @@ package utils import ( + "fmt" "io" + "io/ioutil" "os" + "path" "path/filepath" "strings" @@ -10,6 +13,64 @@ import ( log "github.com/sirupsen/logrus" ) +// CopyFile File copies a single file from src to dst +func CopyFile(src, dst string) error { + var err error + var srcfd *os.File + var dstfd *os.File + var srcinfo os.FileInfo + + if srcfd, err = os.Open(src); err != nil { + return err + } + defer srcfd.Close() + + if dstfd, err = CreateNestedFile(dst); err != nil { + return err + } + defer dstfd.Close() + + if _, err = io.Copy(dstfd, srcfd); err != nil { + return err + } + if srcinfo, err = os.Stat(src); err != nil { + return err + } + return os.Chmod(dst, srcinfo.Mode()) +} + +// CopyDir Dir copies a whole directory recursively +func CopyDir(src string, dst string) error { + var err error + var fds []os.FileInfo + var srcinfo os.FileInfo + + if srcinfo, err = os.Stat(src); err != nil { + return err + } + if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil { + return err + } + if fds, err = ioutil.ReadDir(src); err != nil { + return err + } + for _, fd := range fds { + srcfp := path.Join(src, fd.Name()) + dstfp := path.Join(dst, fd.Name()) + + if fd.IsDir() { + if err = CopyDir(srcfp, dstfp); err != nil { + fmt.Println(err) + } + } else { + if err = CopyFile(srcfp, dstfp); err != nil { + fmt.Println(err) + } + } + } + return nil +} + // Exists determine whether the file exists func Exists(name string) bool { if _, err := os.Stat(name); err != nil {