|
|
|
|
|
|
|
|
|
package webdav |
|
|
|
import ( |
|
"context" |
|
"net/http" |
|
"path" |
|
"path/filepath" |
|
|
|
"github.com/alist-org/alist/v3/internal/conf" |
|
"github.com/alist-org/alist/v3/internal/fs" |
|
"github.com/alist-org/alist/v3/internal/model" |
|
"github.com/alist-org/alist/v3/internal/op" |
|
) |
|
|
|
|
|
|
|
func slashClean(name string) string { |
|
if name == "" || name[0] != '/' { |
|
name = "/" + name |
|
} |
|
return path.Clean(name) |
|
} |
|
|
|
|
|
|
|
|
|
func moveFiles(ctx context.Context, src, dst string, overwrite bool) (status int, err error) { |
|
srcDir := path.Dir(src) |
|
dstDir := path.Dir(dst) |
|
srcName := path.Base(src) |
|
dstName := path.Base(dst) |
|
if srcDir == dstDir { |
|
err = fs.Rename(ctx, src, dstName) |
|
} else { |
|
err = fs.Move(ctx, src, dstDir) |
|
if err != nil { |
|
return http.StatusInternalServerError, err |
|
} |
|
if srcName != dstName { |
|
err = fs.Rename(ctx, path.Join(dstDir, srcName), dstName) |
|
} |
|
} |
|
if err != nil { |
|
return http.StatusInternalServerError, err |
|
} |
|
|
|
return http.StatusCreated, nil |
|
} |
|
|
|
|
|
|
|
|
|
func copyFiles(ctx context.Context, src, dst string, overwrite bool) (status int, err error) { |
|
dstDir := path.Dir(dst) |
|
_, err = fs.Copy(context.WithValue(ctx, conf.NoTaskKey, struct{}{}), src, dstDir, overwrite) |
|
if err != nil { |
|
return http.StatusInternalServerError, err |
|
} |
|
|
|
return http.StatusCreated, nil |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
func walkFS(ctx context.Context, depth int, name string, info model.Obj, walkFn func(reqPath string, info model.Obj, err error) error) error { |
|
|
|
err := walkFn(name, info, nil) |
|
if err != nil { |
|
if info.IsDir() && err == filepath.SkipDir { |
|
return nil |
|
} |
|
return err |
|
} |
|
if !info.IsDir() || depth == 0 { |
|
return nil |
|
} |
|
if depth == 1 { |
|
depth = 0 |
|
} |
|
meta, _ := op.GetNearestMeta(name) |
|
|
|
objs, err := fs.List(context.WithValue(ctx, "meta", meta), name, &fs.ListArgs{}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
return walkFn(name, info, err) |
|
} |
|
|
|
for _, fileInfo := range objs { |
|
filename := path.Join(name, fileInfo.GetName()) |
|
if err != nil { |
|
if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir { |
|
return err |
|
} |
|
} else { |
|
err = walkFS(ctx, depth, filename, fileInfo, walkFn) |
|
if err != nil { |
|
if !fileInfo.IsDir() || err != filepath.SkipDir { |
|
return err |
|
} |
|
} |
|
} |
|
} |
|
return nil |
|
} |
|
|