Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2024-10-07 19:30:25 +08:00
commit 86d2d1047d
6 changed files with 182 additions and 11 deletions

View file

@ -278,6 +278,30 @@ func getDocInfo(c *gin.Context) {
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) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)

View file

@ -182,6 +182,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/block/getContentWordCount", model.CheckAuth, getContentWordCount)
ginServer.Handle("POST", "/api/block/getRecentUpdatedBlocks", model.CheckAuth, getRecentUpdatedBlocks)
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/checkBlockFold", model.CheckAuth, checkBlockFold)
ginServer.Handle("POST", "/api/block/insertBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, insertBlock)

View file

@ -44,6 +44,10 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
switch value.Type {
case KeyTypeBlock:
if nil != value.Block && nil != other.Block {
if 0 == strings.Compare(value.Block.Content, other.Block.Content) {
return 0
}
if util.PinYinCompare(value.Block.Content, other.Block.Content) {
return -1
}
@ -59,6 +63,11 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
} else if "" == other.Text.Content {
return -1
}
if 0 == strings.Compare(value.Text.Content, other.Text.Content) {
return 0
}
if util.PinYinCompare(value.Text.Content, other.Text.Content) {
return -1
}
@ -229,6 +238,11 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
for _, v := range other.MAsset {
v2 += v.Content
}
if 0 == strings.Compare(v1, v2) {
return 0
}
if util.PinYinCompare(v1, v2) {
return -1
}
@ -247,6 +261,11 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
}
return 0
}
if 0 == strings.Compare(value.Template.Content, other.Template.Content) {
return 0
}
if util.PinYinCompare(value.Template.Content, other.Template.Content) {
return -1
}
@ -290,6 +309,11 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
oContentBuf.WriteByte(' ')
}
oContent := strings.TrimSpace(oContentBuf.String())
if 0 == strings.Compare(vContent, oContent) {
return 0
}
if util.PinYinCompare(vContent, oContent) {
return -1
}
@ -323,6 +347,11 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int {
oContentBuf.WriteByte(' ')
}
oContent := strings.TrimSpace(oContentBuf.String())
if 0 == strings.Compare(vContent, oContent) {
return 0
}
if util.PinYinCompare(vContent, oContent) {
return -1
}

View file

@ -24,6 +24,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"github.com/88250/lute"
"github.com/88250/lute/parse"
@ -37,20 +38,32 @@ import (
)
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)
luteEngine := util.NewLute()
for id, bt := range bts {
tree := tmpCache[bt.RootID]
if nil == tree {
tree, _ = LoadTree(bt.BoxID, bt.Path, luteEngine)
if nil == tree {
logging.LogWarnf("load tree [%s] failed: %s", id, bt.Path)
continue
}
tmpCache[bt.RootID] = tree
var boxIDs []string
var paths []string
seen := make(map[string]bool)
for _, bt := range bts {
key := bt.BoxID + bt.Path
if !seen[key] {
seen[key] = true
boxIDs = append(boxIDs, bt.BoxID)
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
}
@ -67,6 +80,28 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
return
}
func BatchLoadTrees(boxIDs, paths []string, luteEngine *lute.Lute) ([]*parse.Tree, []error) {
results := make([]*parse.Tree, len(paths))
errs := make([]error, len(paths))
var wg sync.WaitGroup
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
errs[i] = err
}(i)
}
wg.Wait()
return results, errs
}
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
ret = parseJSON2Tree(boxID, p, data, luteEngine)
if nil == ret {

View file

@ -29,6 +29,7 @@ import (
"github.com/88250/lute/parse"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/av"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@ -123,6 +124,85 @@ func GetDocInfo(blockID string) (ret *BlockInfo) {
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 {
bt := treenode.GetBlockTree(id)
if nil == bt {

View file

@ -96,6 +96,8 @@ func EscapeHTML(s string) (ret string) {
ret = strings.ReplaceAll(ret, "__@gt__", "&gt;")
ret = strings.ReplaceAll(ret, "__@34__", "&#34;")
ret = strings.ReplaceAll(ret, "__@13__", "&#13;")
ret = strings.ReplaceAll(ret, "&lt;", "&amp;lt;")
ret = strings.ReplaceAll(ret, "&gt;", "&amp;gt;")
return
}