🎨 Support for listing missing files in Settings - Assets https://github.com/siyuan-note/siyuan/issues/8383

This commit is contained in:
Daniel 2023-06-04 10:30:19 +08:00
parent 17d8c79057
commit 558f1cdabc
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 79 additions and 0 deletions

View file

@ -210,6 +210,16 @@ func getUnusedAssets(c *gin.Context) {
}
}
func getMissingAssets(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
missingAssets := model.MissingAssets()
ret.Data = map[string]interface{}{
"missingAssets": missingAssets,
}
}
func resolveAssetPath(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)

View file

@ -224,6 +224,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/asset/setFileAnnotation", model.CheckAuth, model.CheckReadonly, setFileAnnotation)
ginServer.Handle("POST", "/api/asset/getFileAnnotation", model.CheckAuth, getFileAnnotation)
ginServer.Handle("POST", "/api/asset/getUnusedAssets", model.CheckAuth, getUnusedAssets)
ginServer.Handle("POST", "/api/asset/getMissingAssets", model.CheckAuth, getMissingAssets)
ginServer.Handle("POST", "/api/asset/removeUnusedAsset", model.CheckAuth, model.CheckReadonly, removeUnusedAsset)
ginServer.Handle("POST", "/api/asset/removeUnusedAssets", model.CheckAuth, model.CheckReadonly, removeUnusedAssets)
ginServer.Handle("POST", "/api/asset/getDocImageAssets", model.CheckAuth, model.CheckReadonly, getDocImageAssets)

View file

@ -83,6 +83,8 @@ func NewSearch() *Search {
Memo: true,
IAL: false,
IndexAssetPath: true,
BacklinkMentionName: true,
BacklinkMentionAlias: false,
BacklinkMentionAnchor: true,

View file

@ -680,6 +680,72 @@ func UnusedAssets() (ret []string) {
return
}
func MissingAssets() (ret []string) {
defer logging.Recover()
ret = []string{}
assetsPathMap, err := allAssetAbsPaths()
if nil != err {
return
}
notebooks, err := ListNotebooks()
if nil != err {
return
}
luteEngine := util.NewLute()
for _, notebook := range notebooks {
dests := map[string]bool{}
pages := pagedPaths(filepath.Join(util.DataDir, notebook.ID), 32)
for _, paths := range pages {
var trees []*parse.Tree
for _, localPath := range paths {
tree, loadTreeErr := loadTree(localPath, luteEngine)
if nil != loadTreeErr {
continue
}
trees = append(trees, tree)
}
for _, tree := range trees {
for _, d := range assetsLinkDestsInTree(tree) {
dests[d] = true
}
if titleImgPath := treenode.GetDocTitleImgPath(tree.Root); "" != titleImgPath {
// 题头图计入
if !util.IsAssetLinkDest([]byte(titleImgPath)) {
continue
}
dests[titleImgPath] = true
}
}
}
for dest, _ := range dests {
if !strings.HasPrefix(dest, "assets/") {
continue
}
if idx := strings.Index(dest, "?"); 0 < idx {
dest = dest[:idx]
}
if strings.HasSuffix(dest, "/") {
continue
}
if "" == assetsPathMap[dest] {
ret = append(ret, dest)
continue
}
}
}
sort.Strings(ret)
return
}
func emojisInTree(tree *parse.Tree) (ret []string) {
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {