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

This commit is contained in:
Vanessa 2025-09-26 18:52:36 +08:00
commit 52eaa5519b
2 changed files with 73 additions and 61 deletions

View file

@ -1556,9 +1556,11 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
for _, avID := range avIDs {
attrView := cachedAttrViews[avID]
if nil == attrView {
attrView, _ = av.ParseAttributeView(avID)
var err error
attrView, err = av.ParseAttributeView(avID)
if nil == attrView {
return
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
continue
}
cachedAttrViews[avID] = attrView
}

View file

@ -1657,8 +1657,8 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
baseFolderName = path.Join(dir, name)
box := Conf.Box(boxID)
exportFolder := filepath.Join(util.TempDir, "export", baseFolderName)
if err := os.MkdirAll(exportFolder, 0755); err != nil {
exportDir := filepath.Join(util.TempDir, "export", baseFolderName)
if err := os.MkdirAll(exportDir, 0755); err != nil {
logging.LogErrorf("create export temp folder failed: %s", err)
return
}
@ -1709,7 +1709,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
}
writePath := strings.TrimPrefix(tree.Path, rootDirPath)
writePath = filepath.Join(exportFolder, writePath)
writePath = filepath.Join(exportDir, writePath)
writeFolder := filepath.Dir(writePath)
if mkdirErr := os.MkdirAll(writeFolder, 0755); nil != mkdirErr {
logging.LogErrorf("create export temp folder [%s] failed: %s", writeFolder, mkdirErr)
@ -1735,7 +1735,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
}
writePath := strings.TrimPrefix(tree.Path, rootDirPath)
writePath = filepath.Join(exportFolder, treeID+".sy")
writePath = filepath.Join(exportDir, treeID+".sy")
if writeErr := os.WriteFile(writePath, data, 0644); nil != writeErr {
logging.LogErrorf("write export file [%s] failed: %s", writePath, writeErr)
continue
@ -1785,7 +1785,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
continue
}
destPath := filepath.Join(exportFolder, asset)
destPath := filepath.Join(exportDir, asset)
assetErr := filelock.Copy(srcPath, destPath)
if nil != assetErr {
logging.LogErrorf("copy asset from [%s] to [%s] failed: %s", srcPath, destPath, assetErr)
@ -1809,7 +1809,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
emojis := emojisInTree(tree)
for _, emoji := range emojis {
from := filepath.Join(util.DataDir, emoji)
to := filepath.Join(exportFolder, emoji)
to := filepath.Join(exportDir, emoji)
if copyErr := filelock.Copy(from, to); copyErr != nil {
logging.LogErrorf("copy emojis from [%s] to [%s] failed: %s", from, to, copyErr)
}
@ -1817,65 +1817,31 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
}
// 导出数据库 Attribute View export https://github.com/siyuan-note/siyuan/issues/8710
exportStorageAvDir := filepath.Join(exportFolder, "storage", "av")
exportStorageAvDir := filepath.Join(exportDir, "storage", "av")
var avIDs []string
for _, tree := range trees {
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
if !entering || !n.IsBlock() {
return ast.WalkContinue
}
if ast.NodeAttributeView != n.Type {
return ast.WalkContinue
if ast.NodeAttributeView == n.Type {
avIDs = append(avIDs, n.AttributeViewID)
}
avID := n.AttributeViewID
avJSONPath := av.GetAttributeViewDataPath(avID)
if !filelock.IsExist(avJSONPath) {
return ast.WalkContinue
avs := n.IALAttr(av.NodeAttrNameAvs)
for _, avID := range strings.Split(avs, ",") {
avIDs = append(avIDs, strings.TrimSpace(avID))
}
if copyErr := filelock.Copy(avJSONPath, filepath.Join(exportStorageAvDir, avID+".json")); nil != copyErr {
logging.LogErrorf("copy av json failed: %s", copyErr)
}
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return ast.WalkContinue
}
for _, keyValues := range attrView.KeyValues {
switch keyValues.Key.Type {
case av.KeyTypeMAsset: // 导出资源文件列 https://github.com/siyuan-note/siyuan/issues/9919
for _, value := range keyValues.Values {
for _, asset := range value.MAsset {
if !util.IsAssetLinkDest([]byte(asset.Content)) {
continue
}
destPath := filepath.Join(exportFolder, asset.Content)
srcPath := assetPathMap[asset.Content]
if "" == srcPath {
logging.LogWarnf("get asset [%s] abs path failed", asset.Content)
continue
}
if copyErr := filelock.Copy(srcPath, destPath); nil != copyErr {
logging.LogErrorf("copy asset failed: %s", copyErr)
}
}
}
}
}
// 级联导出关联列关联的数据库
exportRelationAvs(avID, exportStorageAvDir)
return ast.WalkContinue
})
}
avIDs = gulu.Str.RemoveDuplicatedElem(avIDs)
for _, avID := range avIDs {
exportAv(avID, exportStorageAvDir, exportDir, assetPathMap)
}
// 导出闪卡 Export related flashcard data when exporting .sy.zip https://github.com/siyuan-note/siyuan/issues/9372
exportStorageRiffDir := filepath.Join(exportFolder, "storage", "riff")
exportStorageRiffDir := filepath.Join(exportDir, "storage", "riff")
deck, loadErr := riff.LoadDeck(exportStorageRiffDir, builtinDeckID, Conf.Flashcard.RequestRetention, Conf.Flashcard.MaximumInterval, Conf.Flashcard.Weights)
if nil != loadErr {
logging.LogErrorf("load deck [%s] failed: %s", name, loadErr)
@ -1924,7 +1890,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
logging.LogErrorf("marshal sort conf failed: %s", sortErr)
}
if 0 < len(sortData) {
confDir := filepath.Join(exportFolder, ".siyuan")
confDir := filepath.Join(exportDir, ".siyuan")
if mkdirErr := os.MkdirAll(confDir, 0755); nil != mkdirErr {
logging.LogErrorf("create export conf folder [%s] failed: %s", confDir, mkdirErr)
} else {
@ -1937,10 +1903,10 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
}
}
zipPath = exportFolder + ".sy.zip"
zipPath = exportDir + ".sy.zip"
zip, err := gulu.Zip.Create(zipPath)
if err != nil {
logging.LogErrorf("create export .sy.zip [%s] failed: %s", exportFolder, err)
logging.LogErrorf("create export .sy.zip [%s] failed: %s", exportDir, err)
return ""
}
@ -1948,8 +1914,8 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(253), filename))
}
if err = zip.AddDirectory(baseFolderName, exportFolder, zipCallback); err != nil {
logging.LogErrorf("create export .sy.zip [%s] failed: %s", exportFolder, err)
if err = zip.AddDirectory(baseFolderName, exportDir, zipCallback); err != nil {
logging.LogErrorf("create export .sy.zip [%s] failed: %s", exportDir, err)
return ""
}
@ -1957,11 +1923,55 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
logging.LogErrorf("close export .sy.zip failed: %s", err)
}
os.RemoveAll(exportFolder)
os.RemoveAll(exportDir)
zipPath = "/export/" + url.PathEscape(filepath.Base(zipPath))
return
}
func exportAv(avID, exportStorageAvDir, exportFolder string, assetPathMap map[string]string) {
avJSONPath := av.GetAttributeViewDataPath(avID)
if !filelock.IsExist(avJSONPath) {
return
}
if copyErr := filelock.Copy(avJSONPath, filepath.Join(exportStorageAvDir, avID+".json")); nil != copyErr {
logging.LogErrorf("copy av json failed: %s", copyErr)
}
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
for _, keyValues := range attrView.KeyValues {
switch keyValues.Key.Type {
case av.KeyTypeMAsset: // 导出资源文件列 https://github.com/siyuan-note/siyuan/issues/9919
for _, value := range keyValues.Values {
for _, asset := range value.MAsset {
if !util.IsAssetLinkDest([]byte(asset.Content)) {
continue
}
destPath := filepath.Join(exportFolder, asset.Content)
srcPath := assetPathMap[asset.Content]
if "" == srcPath {
logging.LogWarnf("get asset [%s] abs path failed", asset.Content)
continue
}
if copyErr := filelock.Copy(srcPath, destPath); nil != copyErr {
logging.LogErrorf("copy asset failed: %s", copyErr)
}
}
}
}
}
// 级联导出关联列关联的数据库
exportRelationAvs(avID, exportStorageAvDir)
}
func exportRelationAvs(avID, exportStorageAvDir string) {
avIDs := hashset.New()
walkRelationAvs(avID, avIDs)