mirror of
https://github.com/AlistGo/alist.git
synced 2025-04-22 21:04:07 +08:00
feat: empty folder clear API [ckip ci] (#4132)
* 增加清理空文件夹API * 修复嵌套文件夹删除Bug Author: varg247 <varg247@gmail.com> --------- Co-authored-by: varg247 <varg247@qq.com>
This commit is contained in:
parent
fdcad9c154
commit
46f9aefb04
@ -351,6 +351,105 @@ func FsRemove(c *gin.Context) {
|
||||
common.SuccessResp(c)
|
||||
}
|
||||
|
||||
type RemoveEmptyDirectoryReq struct {
|
||||
SrcDir string `json:"src_dir"`
|
||||
}
|
||||
|
||||
func FsRemoveEmptyDirectory(c *gin.Context) {
|
||||
var req RemoveEmptyDirectoryReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
|
||||
user := c.MustGet("user").(*model.User)
|
||||
if !user.CanRemove() {
|
||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||
return
|
||||
}
|
||||
srcDir, err := user.JoinPath(req.SrcDir)
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 403)
|
||||
return
|
||||
}
|
||||
|
||||
meta, err := op.GetNearestMeta(srcDir)
|
||||
if err != nil {
|
||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||
common.ErrorResp(c, err, 500, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Set("meta", meta)
|
||||
|
||||
rootFiles, err := fs.List(c, srcDir, &fs.ListArgs{})
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
|
||||
// record the file path
|
||||
filePathMap := make(map[model.Obj]string)
|
||||
// record the parent file
|
||||
fileParentMap := make(map[model.Obj]model.Obj)
|
||||
// removing files
|
||||
removingFiles := generic.NewQueue[model.Obj]()
|
||||
// removed files
|
||||
removedFiles := make(map[string]bool)
|
||||
for _, file := range rootFiles {
|
||||
if !file.IsDir() {
|
||||
continue
|
||||
}
|
||||
removingFiles.Push(file)
|
||||
filePathMap[file] = srcDir
|
||||
}
|
||||
|
||||
for !removingFiles.IsEmpty() {
|
||||
|
||||
removingFile := removingFiles.Pop()
|
||||
removingFilePath := fmt.Sprintf("%s/%s", filePathMap[removingFile], removingFile.GetName())
|
||||
|
||||
if removedFiles[removingFilePath] {
|
||||
continue
|
||||
}
|
||||
|
||||
subFiles, err := fs.List(c, removingFilePath, &fs.ListArgs{Refresh: true})
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
|
||||
if len(subFiles) == 0 {
|
||||
// remove empty directory
|
||||
err = fs.Remove(c, removingFilePath)
|
||||
removedFiles[removingFilePath] = true
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
// recheck parent folder
|
||||
parentFile, exist := fileParentMap[removingFile]
|
||||
if exist {
|
||||
removingFiles.Push(parentFile)
|
||||
}
|
||||
|
||||
} else {
|
||||
// recursive remove
|
||||
for _, subFile := range subFiles {
|
||||
if !subFile.IsDir() {
|
||||
continue
|
||||
}
|
||||
removingFiles.Push(subFile)
|
||||
filePathMap[subFile] = removingFilePath
|
||||
fileParentMap[subFile] = removingFile
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
common.SuccessResp(c)
|
||||
}
|
||||
|
||||
// Link return real link, just for proxy program, it may contain cookie, so just allowed for admin
|
||||
func Link(c *gin.Context) {
|
||||
var req MkdirOrLinkReq
|
||||
|
@ -131,6 +131,7 @@ func _fs(g *gin.RouterGroup) {
|
||||
g.POST("/recursive_move", handles.FsRecursiveMove)
|
||||
g.POST("/copy", handles.FsCopy)
|
||||
g.POST("/remove", handles.FsRemove)
|
||||
g.POST("/remove_empty_directory", handles.FsRemoveEmptyDirectory)
|
||||
g.PUT("/put", middlewares.FsUp, handles.FsStream)
|
||||
g.PUT("/form", middlewares.FsUp, handles.FsForm)
|
||||
g.POST("/link", middlewares.AuthAdmin, handles.Link)
|
||||
|
Loading…
x
Reference in New Issue
Block a user