diff --git a/internal/fs/copy.go b/internal/fs/copy.go new file mode 100644 index 00000000000..f1bff409f7e --- /dev/null +++ b/internal/fs/copy.go @@ -0,0 +1,41 @@ +package fs + +import ( + "context" + stdpath "path" + + "github.com/alist-org/alist/v3/internal/driver" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/operations" + "github.com/pkg/errors" +) + +func CopyBetween2Accounts(ctx context.Context, srcAccount, dstAccount driver.Driver, srcPath, dstPath string) error { + srcFile, err := operations.Get(ctx, srcAccount, srcPath) + if err != nil { + return errors.WithMessagef(err, "failed get src [%s] file", srcPath) + } + if srcFile.IsDir() { + files, err := operations.List(ctx, srcAccount, srcPath) + if err != nil { + return errors.WithMessagef(err, "failed list src [%s] files", srcPath) + } + for _, file := range files { + srcFilePath := stdpath.Join(srcPath, file.GetName()) + dstFilePath := stdpath.Join(dstPath, file.GetName()) + if err := CopyBetween2Accounts(ctx, srcAccount, dstAccount, srcFilePath, dstFilePath); err != nil { + return errors.WithMessagef(err, "failed copy file [%s] to [%s]", srcFilePath, dstFilePath) + } + } + } + link, err := operations.Link(ctx, srcAccount, srcPath, model.LinkArgs{}) + if err != nil { + return errors.WithMessagef(err, "failed get [%s] link", srcPath) + } + stream, err := getFileStreamFromLink(srcFile, link) + if err != nil { + return errors.WithMessagef(err, "failed get [%s] stream", srcPath) + } + // TODO add as task + return operations.Put(ctx, dstAccount, dstPath, stream) +} diff --git a/internal/fs/write.go b/internal/fs/write.go index 36152557332..0a353fc8a79 100644 --- a/internal/fs/write.go +++ b/internal/fs/write.go @@ -55,18 +55,19 @@ func Copy(ctx context.Context, account driver.Driver, srcPath, dstPath string) e if srcAccount.GetAccount() == dstAccount.GetAccount() { return operations.Copy(ctx, account, srcActualPath, dstActualPath) } - // not in an account, add copy task - srcFile, err := operations.Get(ctx, srcAccount, srcActualPath) - if srcFile.IsDir() { - // TODO: recursive copy - return nil - } - // TODO: add copy task, maybe like this: - // operations.Link(ctx,srcAccount,srcActualPath,args) - // get a Reader from link - // boxing the Reader to a driver.FileStream - // operations.Put(ctx,dstParentPath, stream) - panic("TODO") + // not in an account + return CopyBetween2Accounts(ctx, srcAccount, dstAccount, srcActualPath, dstActualPath) + // srcFile, err := operations.Get(ctx, srcAccount, srcActualPath) + // if srcFile.IsDir() { + // // TODO: recursive copy + // return nil + // } + // // TODO: add copy task, maybe like this: + // // operations.Link(ctx,srcAccount,srcActualPath,args) + // // get a Reader from link + // // boxing the Reader to a driver.FileStream + // // operations.Put(ctx,dstParentPath, stream) + // panic("TODO") } func Remove(ctx context.Context, account driver.Driver, path string) error {