fix: Handle folder move override (#22)
parent
9f931d3d24
commit
853a5e5c5e
|
@ -1,7 +1,9 @@
|
||||||
package fileutils
|
package fileutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -16,8 +18,14 @@ func MoveFile(fs afero.Fs, src, dst string) error {
|
||||||
if fs.Rename(src, dst) == nil {
|
if fs.Rename(src, dst) == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info, err := fs.Stat(src)
|
||||||
|
if err == nil && info.IsDir() {
|
||||||
|
return CopyFolder(fs, src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
// fallback
|
// fallback
|
||||||
err := CopyFile(fs, src, dst)
|
err = CopyFile(fs, src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = fs.Remove(dst)
|
_ = fs.Remove(dst)
|
||||||
return err
|
return err
|
||||||
|
@ -71,6 +79,40 @@ func CopyFile(fs afero.Fs, source, dest string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CopyFolder copies a folder to destination and returns
|
||||||
|
// an error if any. If the destination already exists,
|
||||||
|
// it get overriden.
|
||||||
|
func CopyFolder(fs afero.Fs, source, dest string) error {
|
||||||
|
tmpDest := ""
|
||||||
|
_, err := fs.Stat(dest)
|
||||||
|
if err == nil {
|
||||||
|
// destination already exists - rename it so that src
|
||||||
|
// could be moved to its place
|
||||||
|
tmpDest = fmt.Sprintf("%s.%d", dest, rand.Intn(9999))
|
||||||
|
err = fs.Rename(dest, tmpDest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
// unknown error, return
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = fs.Rename(source, dest); err != nil {
|
||||||
|
// if moving fails and we renamed an existing destination
|
||||||
|
// in the previous step, then restore its name
|
||||||
|
if tmpDest != "" {
|
||||||
|
fs.Rename(tmpDest, dest)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// if moving was successful, delete the renamed dest
|
||||||
|
_ = fs.Remove(tmpDest)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// CommonPrefix returns common directory path of provided files
|
// CommonPrefix returns common directory path of provided files
|
||||||
func CommonPrefix(sep byte, paths ...string) string {
|
func CommonPrefix(sep byte, paths ...string) string {
|
||||||
// Handle special cases.
|
// Handle special cases.
|
||||||
|
|
|
@ -415,6 +415,32 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileutils.Copy(d.user.Fs, src, dst)
|
return fileutils.Copy(d.user.Fs, src, dst)
|
||||||
|
case "rename":
|
||||||
|
if !d.user.Perm.Rename {
|
||||||
|
return errors.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
src = path.Clean("/" + src)
|
||||||
|
dst = path.Clean("/" + dst)
|
||||||
|
|
||||||
|
file, err := files.NewFileInfo(files.FileOptions{
|
||||||
|
Fs: d.user.Fs,
|
||||||
|
Path: src,
|
||||||
|
Modify: d.user.Perm.Modify,
|
||||||
|
Expand: false,
|
||||||
|
ReadHeader: false,
|
||||||
|
Checker: d,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete thumbnails
|
||||||
|
err = delThumbs(ctx, fileCache, file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileutils.MoveFile(d.user.Fs, src, dst)
|
||||||
case "unarchive":
|
case "unarchive":
|
||||||
if !d.user.Perm.Create {
|
if !d.user.Perm.Create {
|
||||||
return errors.ErrPermissionDenied
|
return errors.ErrPermissionDenied
|
||||||
|
@ -459,32 +485,6 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
|
||||||
return errors.ErrInvalidRequestParams
|
return errors.ErrInvalidRequestParams
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case "rename":
|
|
||||||
if !d.user.Perm.Rename {
|
|
||||||
return errors.ErrPermissionDenied
|
|
||||||
}
|
|
||||||
src = path.Clean("/" + src)
|
|
||||||
dst = path.Clean("/" + dst)
|
|
||||||
|
|
||||||
file, err := files.NewFileInfo(files.FileOptions{
|
|
||||||
Fs: d.user.Fs,
|
|
||||||
Path: src,
|
|
||||||
Modify: d.user.Perm.Modify,
|
|
||||||
Expand: false,
|
|
||||||
ReadHeader: false,
|
|
||||||
Checker: d,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete thumbnails
|
|
||||||
err = delThumbs(ctx, fileCache, file)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileutils.MoveFile(d.user.Fs, src, dst)
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams)
|
return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue