mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-04 04:20:53 +08:00
🧑💻 siyuan-note#12718 (#12723)
This commit is contained in:
parent
f965d6b91b
commit
7afea33d36
@ -278,6 +278,30 @@ func getDocInfo(c *gin.Context) {
|
|||||||
ret.Data = info
|
ret.Data = info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDocsInfo(c *gin.Context) {
|
||||||
|
ret := gulu.Ret.NewResult()
|
||||||
|
defer c.JSON(http.StatusOK, ret)
|
||||||
|
|
||||||
|
arg, ok := util.JsonArg(c, ret)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
idsArg := arg["ids"].([]interface{})
|
||||||
|
var ids []string
|
||||||
|
for _, id := range idsArg {
|
||||||
|
ids = append(ids, id.(string))
|
||||||
|
}
|
||||||
|
queryRefCount := arg["refCount"].(bool)
|
||||||
|
queryAv := arg["av"].(bool)
|
||||||
|
info := model.GetDocsInfo(ids, queryRefCount, queryAv)
|
||||||
|
if nil == info {
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = fmt.Sprintf(model.Conf.Language(15), ids)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret.Data = info
|
||||||
|
}
|
||||||
|
|
||||||
func getRecentUpdatedBlocks(c *gin.Context) {
|
func getRecentUpdatedBlocks(c *gin.Context) {
|
||||||
ret := gulu.Ret.NewResult()
|
ret := gulu.Ret.NewResult()
|
||||||
defer c.JSON(http.StatusOK, ret)
|
defer c.JSON(http.StatusOK, ret)
|
||||||
|
@ -182,6 +182,7 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||||||
ginServer.Handle("POST", "/api/block/getContentWordCount", model.CheckAuth, getContentWordCount)
|
ginServer.Handle("POST", "/api/block/getContentWordCount", model.CheckAuth, getContentWordCount)
|
||||||
ginServer.Handle("POST", "/api/block/getRecentUpdatedBlocks", model.CheckAuth, getRecentUpdatedBlocks)
|
ginServer.Handle("POST", "/api/block/getRecentUpdatedBlocks", model.CheckAuth, getRecentUpdatedBlocks)
|
||||||
ginServer.Handle("POST", "/api/block/getDocInfo", model.CheckAuth, getDocInfo)
|
ginServer.Handle("POST", "/api/block/getDocInfo", model.CheckAuth, getDocInfo)
|
||||||
|
ginServer.Handle("POST", "/api/block/getDocsInfo", model.CheckAuth, getDocsInfo)
|
||||||
ginServer.Handle("POST", "/api/block/checkBlockExist", model.CheckAuth, checkBlockExist)
|
ginServer.Handle("POST", "/api/block/checkBlockExist", model.CheckAuth, checkBlockExist)
|
||||||
ginServer.Handle("POST", "/api/block/checkBlockFold", model.CheckAuth, checkBlockFold)
|
ginServer.Handle("POST", "/api/block/checkBlockFold", model.CheckAuth, checkBlockFold)
|
||||||
ginServer.Handle("POST", "/api/block/insertBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, insertBlock)
|
ginServer.Handle("POST", "/api/block/insertBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, insertBlock)
|
||||||
|
@ -21,10 +21,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/88250/lute"
|
"github.com/88250/lute"
|
||||||
"github.com/88250/lute/parse"
|
"github.com/88250/lute/parse"
|
||||||
"github.com/88250/lute/render"
|
"github.com/88250/lute/render"
|
||||||
@ -34,23 +30,39 @@ import (
|
|||||||
"github.com/siyuan-note/siyuan/kernel/cache"
|
"github.com/siyuan-note/siyuan/kernel/cache"
|
||||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||||
"github.com/siyuan-note/siyuan/kernel/util"
|
"github.com/siyuan-note/siyuan/kernel/util"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadTrees(ids []string) (ret map[string]*parse.Tree) {
|
func LoadTrees(ids []string) (ret map[string]*parse.Tree) {
|
||||||
ret, tmpCache := map[string]*parse.Tree{}, map[string]*parse.Tree{}
|
ret = map[string]*parse.Tree{}
|
||||||
bts := treenode.GetBlockTrees(ids)
|
bts := treenode.GetBlockTrees(ids)
|
||||||
luteEngine := util.NewLute()
|
luteEngine := util.NewLute()
|
||||||
for id, bt := range bts {
|
var boxIDs []string
|
||||||
tree := tmpCache[bt.RootID]
|
var paths []string
|
||||||
if nil == tree {
|
seen := make(map[string]bool)
|
||||||
tree, _ = LoadTree(bt.BoxID, bt.Path, luteEngine)
|
for _, bt := range bts {
|
||||||
if nil == tree {
|
key := bt.BoxID + bt.Path
|
||||||
logging.LogWarnf("load tree [%s] failed: %s", id, bt.Path)
|
if !seen[key] {
|
||||||
continue
|
seen[key] = true
|
||||||
}
|
boxIDs = append(boxIDs, bt.BoxID)
|
||||||
tmpCache[bt.RootID] = tree
|
paths = append(paths, bt.Path)
|
||||||
}
|
}
|
||||||
ret[id] = tree
|
}
|
||||||
|
|
||||||
|
trees, errs := BatchLoadTrees(boxIDs, paths, luteEngine)
|
||||||
|
|
||||||
|
for i := range trees {
|
||||||
|
tree := trees[i]
|
||||||
|
err := errs[i]
|
||||||
|
if err != nil || tree == nil {
|
||||||
|
logging.LogErrorf("load tree failed: %s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[tree.ID] = tree
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -67,6 +79,31 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BatchLoadTrees(boxIDs, paths []string, luteEngine *lute.Lute) ([]*parse.Tree, []error) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
results := make([]*parse.Tree, len(paths))
|
||||||
|
errors := make([]error, len(paths))
|
||||||
|
|
||||||
|
for i := range paths {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
boxID := boxIDs[i]
|
||||||
|
path := paths[i]
|
||||||
|
|
||||||
|
tree, err := LoadTree(boxID, path, luteEngine)
|
||||||
|
|
||||||
|
results[i] = tree
|
||||||
|
errors[i] = err
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return results, errors
|
||||||
|
}
|
||||||
|
|
||||||
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
||||||
ret = parseJSON2Tree(boxID, p, data, luteEngine)
|
ret = parseJSON2Tree(boxID, p, data, luteEngine)
|
||||||
if nil == ret {
|
if nil == ret {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/siyuan-note/siyuan/kernel/filesys"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@ -123,6 +124,85 @@ func GetDocInfo(blockID string) (ret *BlockInfo) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDocsInfo(blockIDs []string, queryRefCount bool, queryAv bool) (rets []*BlockInfo) {
|
||||||
|
WaitForWritingFiles()
|
||||||
|
|
||||||
|
trees := filesys.LoadTrees(blockIDs)
|
||||||
|
for _, blockID := range blockIDs {
|
||||||
|
tree := trees[blockID]
|
||||||
|
if nil == tree {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
title := tree.Root.IALAttr("title")
|
||||||
|
ret := &BlockInfo{ID: blockID, RootID: tree.Root.ID, Name: title}
|
||||||
|
ret.IAL = parse.IAL2Map(tree.Root.KramdownIAL)
|
||||||
|
scrollData := ret.IAL["scroll"]
|
||||||
|
if 0 < len(scrollData) {
|
||||||
|
scroll := map[string]interface{}{}
|
||||||
|
if parseErr := gulu.JSON.UnmarshalJSON([]byte(scrollData), &scroll); nil != parseErr {
|
||||||
|
logging.LogWarnf("parse scroll data [%s] failed: %s", scrollData, parseErr)
|
||||||
|
delete(ret.IAL, "scroll")
|
||||||
|
} else {
|
||||||
|
if zoomInId := scroll["zoomInId"]; nil != zoomInId {
|
||||||
|
if !treenode.ExistBlockTree(zoomInId.(string)) {
|
||||||
|
delete(ret.IAL, "scroll")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if startId := scroll["startId"]; nil != startId {
|
||||||
|
if !treenode.ExistBlockTree(startId.(string)) {
|
||||||
|
delete(ret.IAL, "scroll")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if endId := scroll["endId"]; nil != endId {
|
||||||
|
if !treenode.ExistBlockTree(endId.(string)) {
|
||||||
|
delete(ret.IAL, "scroll")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if queryRefCount {
|
||||||
|
ret.RefIDs, _ = sql.QueryRefIDsByDefID(blockID, false)
|
||||||
|
ret.RefCount = len(ret.RefIDs) // 填充块引计数
|
||||||
|
}
|
||||||
|
|
||||||
|
if queryAv {
|
||||||
|
// 填充属性视图角标 Display the database title on the block superscript https://github.com/siyuan-note/siyuan/issues/10545
|
||||||
|
avIDs := strings.Split(ret.IAL[av.NodeAttrNameAvs], ",")
|
||||||
|
for _, avID := range avIDs {
|
||||||
|
avName, getErr := av.GetAttributeViewName(avID)
|
||||||
|
if nil != getErr {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if "" == avName {
|
||||||
|
avName = Conf.language(105)
|
||||||
|
}
|
||||||
|
|
||||||
|
attrView := &AttrView{ID: avID, Name: avName}
|
||||||
|
ret.AttrViews = append(ret.AttrViews, attrView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var subFileCount int
|
||||||
|
boxLocalPath := filepath.Join(util.DataDir, tree.Box)
|
||||||
|
subFiles, err := os.ReadDir(filepath.Join(boxLocalPath, strings.TrimSuffix(tree.Path, ".sy")))
|
||||||
|
if err == nil {
|
||||||
|
for _, subFile := range subFiles {
|
||||||
|
if strings.HasSuffix(subFile.Name(), ".sy") {
|
||||||
|
subFileCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.SubFileCount = subFileCount
|
||||||
|
ret.Icon = tree.Root.IALAttr("icon")
|
||||||
|
|
||||||
|
rets = append(rets, ret)
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetBlockRefText(id string) string {
|
func GetBlockRefText(id string) string {
|
||||||
bt := treenode.GetBlockTree(id)
|
bt := treenode.GetBlockTree(id)
|
||||||
if nil == bt {
|
if nil == bt {
|
||||||
|
Loading…
Reference in New Issue
Block a user