Skip to content

Commit

Permalink
fix: copy folder between two storage (fix #1670)
Browse files Browse the repository at this point in the history
  • Loading branch information
xhofe committed Sep 15, 2022
1 parent 86a625c commit d9f0603
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 78 deletions.
4 changes: 2 additions & 2 deletions drivers/local/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 0 additions & 66 deletions drivers/local/util.go
Original file line number Diff line number Diff line change
@@ -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
}
7 changes: 5 additions & 2 deletions internal/fs/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
},
}))
}
Expand Down
12 changes: 11 additions & 1 deletion internal/fs/util.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package fs

import (
"fmt"
"io"
"mime"
"net/http"
"os"
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"
)

Expand Down Expand Up @@ -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)
}
Expand Down
12 changes: 5 additions & 7 deletions internal/op/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
1 change: 1 addition & 0 deletions pkg/task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
61 changes: 61 additions & 0 deletions pkg/utils/file.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,76 @@
package utils

import (
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"

"github.com/alist-org/alist/v3/internal/conf"
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 {
Expand Down

0 comments on commit d9f0603

Please sign in to comment.