mirror of
https://github.com/halejohn/Cloudreve.git
synced 2026-01-27 10:01:56 +08:00
webdav兼容rclone的nextcloud选项(修改日期和checksum)
This commit is contained in:
@@ -38,26 +38,26 @@ func moveFiles(ctx context.Context, fs *filesystem.FileSystem, src FileInfo, dst
|
||||
fileIDs = []uint{src.(*model.File).ID}
|
||||
}
|
||||
|
||||
// 判断是否需要移动
|
||||
if src.GetPosition() != path.Dir(dst) {
|
||||
err = fs.Move(
|
||||
ctx,
|
||||
folderIDs,
|
||||
fileIDs,
|
||||
src.GetPosition(),
|
||||
path.Dir(dst),
|
||||
)
|
||||
}
|
||||
// 判断是否需要移动
|
||||
if src.GetPosition() != path.Dir(dst) {
|
||||
err = fs.Move(
|
||||
ctx,
|
||||
folderIDs,
|
||||
fileIDs,
|
||||
src.GetPosition(),
|
||||
path.Dir(dst),
|
||||
)
|
||||
}
|
||||
|
||||
// 判断是否需要重命名
|
||||
if err == nil && src.GetName() != path.Base(dst) {
|
||||
err = fs.Rename(
|
||||
ctx,
|
||||
folderIDs,
|
||||
fileIDs,
|
||||
path.Base(dst),
|
||||
)
|
||||
}
|
||||
// 判断是否需要重命名
|
||||
if err == nil && src.GetName() != path.Base(dst) {
|
||||
err = fs.Rename(
|
||||
ctx,
|
||||
folderIDs,
|
||||
fileIDs,
|
||||
path.Base(dst),
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
@@ -74,21 +74,25 @@ func copyFiles(ctx context.Context, fs *filesystem.FileSystem, src FileInfo, dst
|
||||
}
|
||||
recursion++
|
||||
|
||||
var (
|
||||
fileIDs []uint
|
||||
folderIDs []uint
|
||||
)
|
||||
if src.IsDir() {
|
||||
err := fs.Copy(
|
||||
ctx,
|
||||
[]uint{src.(*model.Folder).ID},
|
||||
[]uint{}, src.(*model.Folder).Position,
|
||||
path.Dir(dst),
|
||||
)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
folderIDs = []uint{src.(*model.Folder).ID}
|
||||
} else {
|
||||
err := fs.Copy(ctx, []uint{}, []uint{src.(*model.File).ID}, src.(*model.File).Position, path.Dir(dst))
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
fileIDs = []uint{src.(*model.File).ID}
|
||||
}
|
||||
|
||||
err = fs.Copy(
|
||||
ctx,
|
||||
folderIDs,
|
||||
fileIDs,
|
||||
src.GetPosition(),
|
||||
path.Dir(dst),
|
||||
)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
return http.StatusNoContent, nil
|
||||
|
||||
@@ -16,9 +16,30 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem"
|
||||
)
|
||||
|
||||
type FileDeadProps struct {
|
||||
*model.File
|
||||
}
|
||||
|
||||
// 实现 webdav.DeadPropsHolder 接口,不能在models.file里面定义
|
||||
func (file *FileDeadProps) DeadProps() (map[xml.Name]Property, error) {
|
||||
return map[xml.Name]Property{
|
||||
xml.Name{Space: "http://owncloud.org/ns", Local: "checksums"}: {
|
||||
XMLName: xml.Name{
|
||||
Space: "http://owncloud.org/ns", Local: "checksums",
|
||||
},
|
||||
InnerXML: []byte("<checksum>" + file.MetadataSerialized[model.ChecksumMetadataKey] + "</checksum>"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (file *FileDeadProps) Patch([]Proppatch) ([]Propstat, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type FileInfo interface {
|
||||
GetSize() uint64
|
||||
GetName() string
|
||||
@@ -177,8 +198,18 @@ var liveProps = map[xml.Name]struct {
|
||||
// of one Propstat element.
|
||||
func props(ctx context.Context, fs *filesystem.FileSystem, ls LockSystem, fi FileInfo, pnames []xml.Name) ([]Propstat, error) {
|
||||
isDir := fi.IsDir()
|
||||
if !isDir {
|
||||
fi = &FileDeadProps{fi.(*model.File)}
|
||||
}
|
||||
|
||||
var deadProps map[xml.Name]Property
|
||||
if dph, ok := fi.(DeadPropsHolder); ok {
|
||||
var err error
|
||||
deadProps, err = dph.DeadProps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pstatOK := Propstat{Status: http.StatusOK}
|
||||
pstatNotFound := Propstat{Status: http.StatusNotFound}
|
||||
@@ -210,8 +241,18 @@ func props(ctx context.Context, fs *filesystem.FileSystem, ls LockSystem, fi Fil
|
||||
// Propnames returns the property names defined for resource name.
|
||||
func propnames(ctx context.Context, fs *filesystem.FileSystem, ls LockSystem, fi FileInfo) ([]xml.Name, error) {
|
||||
isDir := fi.IsDir()
|
||||
if !isDir {
|
||||
fi = &FileDeadProps{fi.(*model.File)}
|
||||
}
|
||||
|
||||
var deadProps map[xml.Name]Property
|
||||
if dph, ok := fi.(DeadPropsHolder); ok {
|
||||
var err error
|
||||
deadProps, err = dph.DeadProps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pnames := make([]xml.Name, 0, len(liveProps)+len(deadProps))
|
||||
for pn, prop := range liveProps {
|
||||
@@ -219,6 +260,9 @@ func propnames(ctx context.Context, fs *filesystem.FileSystem, ls LockSystem, fi
|
||||
pnames = append(pnames, pn)
|
||||
}
|
||||
}
|
||||
for pn := range deadProps {
|
||||
pnames = append(pnames, pn)
|
||||
}
|
||||
return pnames, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -389,6 +389,9 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *filesyst
|
||||
fs.Use("AfterValidateFailed", filesystem.HookDeleteTempFile)
|
||||
}
|
||||
|
||||
// rclone 请求
|
||||
fs.Use("AfterUpload", filesystem.NewWebdavAfterUploadHook(r))
|
||||
|
||||
// 执行上传
|
||||
err = fs.Upload(ctx, &fileData)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user