feat(recursive-move): Advanced conflict policy for preventing unintentional overwriting (#7906)

pull/7976/head
Jealous 2025-02-09 18:32:57 +08:00 committed by GitHub
parent 0219c4e15a
commit b9ad18bd0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 18 deletions

View File

@ -68,21 +68,29 @@ func ErrorStrResp(c *gin.Context, str string, code int, l ...bool) {
} }
func SuccessResp(c *gin.Context, data ...interface{}) { func SuccessResp(c *gin.Context, data ...interface{}) {
if len(data) == 0 { SuccessWithMsgResp(c, "success", data...)
c.JSON(200, Resp[interface{}]{ }
Code: 200,
Message: "success", func SuccessWithMsgResp(c *gin.Context, msg string, data ...interface{}) {
Data: nil, var respData interface{}
}) if len(data) > 0 {
return respData = data[0]
} }
c.JSON(200, Resp[interface{}]{ c.JSON(200, Resp[interface{}]{
Code: 200, Code: 200,
Message: "success", Message: msg,
Data: data[0], Data: respData,
}) })
} }
func Pluralize(count int, singular, plural string) string {
if count == 1 {
return singular
}
return plural
}
func GetHttpReq(ctx context.Context) *http.Request { func GetHttpReq(ctx context.Context) *http.Request {
if c, ok := ctx.(*gin.Context); ok { if c, ok := ctx.(*gin.Context); ok {
return c.Request return c.Request

7
server/handles/const.go Normal file
View File

@ -0,0 +1,7 @@
package handles
const (
CANCEL = "cancel"
OVERWRITE = "overwrite"
SKIP = "skip"
)

View File

@ -18,7 +18,7 @@ import (
type RecursiveMoveReq struct { type RecursiveMoveReq struct {
SrcDir string `json:"src_dir"` SrcDir string `json:"src_dir"`
DstDir string `json:"dst_dir"` DstDir string `json:"dst_dir"`
Overwrite bool `json:"overwrite"` ConflictPolicy string `json:"conflict_policy"`
} }
func FsRecursiveMove(c *gin.Context) { func FsRecursiveMove(c *gin.Context) {
@ -60,7 +60,7 @@ func FsRecursiveMove(c *gin.Context) {
} }
var existingFileNames []string var existingFileNames []string
if !req.Overwrite { if req.ConflictPolicy != OVERWRITE {
dstFiles, err := fs.List(c, dstDir, &fs.ListArgs{}) dstFiles, err := fs.List(c, dstDir, &fs.ListArgs{})
if err != nil { if err != nil {
common.ErrorResp(c, err, 500) common.ErrorResp(c, err, 500)
@ -99,25 +99,28 @@ func FsRecursiveMove(c *gin.Context) {
filePathMap[subFile] = subFilePath filePathMap[subFile] = subFilePath
} }
} else { } else {
if movingFilePath == dstDir { if movingFilePath == dstDir {
// same directory, don't move // same directory, don't move
continue continue
} }
if !req.Overwrite {
if slices.Contains(existingFileNames, movingFile.GetName()) { if slices.Contains(existingFileNames, movingFile.GetName()) {
if req.ConflictPolicy == CANCEL {
common.ErrorStrResp(c, fmt.Sprintf("file [%s] exists", movingFile.GetName()), 403) common.ErrorStrResp(c, fmt.Sprintf("file [%s] exists", movingFile.GetName()), 403)
return return
} else if req.ConflictPolicy == SKIP {
continue
} }
} else if req.ConflictPolicy != OVERWRITE {
existingFileNames = append(existingFileNames, movingFile.GetName()) existingFileNames = append(existingFileNames, movingFile.GetName())
} }
movingFileNames = append(movingFileNames, movingFileName) movingFileNames = append(movingFileNames, movingFileName)
} }
} }
var count = 0
for i, fileName := range movingFileNames { for i, fileName := range movingFileNames {
// move // move
err := fs.Move(c, fileName, dstDir, len(movingFileNames) > i+1) err := fs.Move(c, fileName, dstDir, len(movingFileNames) > i+1)
@ -125,9 +128,10 @@ func FsRecursiveMove(c *gin.Context) {
common.ErrorResp(c, err, 500) common.ErrorResp(c, err, 500)
return return
} }
count++
} }
common.SuccessResp(c) common.SuccessWithMsgResp(c, fmt.Sprintf("Successfully moved %d %s", count, common.Pluralize(count, "file", "files")))
} }
type BatchRenameReq struct { type BatchRenameReq struct {