mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 22:50:13 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
52eaa5519b
2 changed files with 73 additions and 61 deletions
|
|
@ -1556,9 +1556,11 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
||||||
for _, avID := range avIDs {
|
for _, avID := range avIDs {
|
||||||
attrView := cachedAttrViews[avID]
|
attrView := cachedAttrViews[avID]
|
||||||
if nil == attrView {
|
if nil == attrView {
|
||||||
attrView, _ = av.ParseAttributeView(avID)
|
var err error
|
||||||
|
attrView, err = av.ParseAttributeView(avID)
|
||||||
if nil == attrView {
|
if nil == attrView {
|
||||||
return
|
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
cachedAttrViews[avID] = attrView
|
cachedAttrViews[avID] = attrView
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1657,8 +1657,8 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
||||||
baseFolderName = path.Join(dir, name)
|
baseFolderName = path.Join(dir, name)
|
||||||
box := Conf.Box(boxID)
|
box := Conf.Box(boxID)
|
||||||
|
|
||||||
exportFolder := filepath.Join(util.TempDir, "export", baseFolderName)
|
exportDir := filepath.Join(util.TempDir, "export", baseFolderName)
|
||||||
if err := os.MkdirAll(exportFolder, 0755); err != nil {
|
if err := os.MkdirAll(exportDir, 0755); err != nil {
|
||||||
logging.LogErrorf("create export temp folder failed: %s", err)
|
logging.LogErrorf("create export temp folder failed: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1709,7 +1709,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
writePath := strings.TrimPrefix(tree.Path, rootDirPath)
|
writePath := strings.TrimPrefix(tree.Path, rootDirPath)
|
||||||
writePath = filepath.Join(exportFolder, writePath)
|
writePath = filepath.Join(exportDir, writePath)
|
||||||
writeFolder := filepath.Dir(writePath)
|
writeFolder := filepath.Dir(writePath)
|
||||||
if mkdirErr := os.MkdirAll(writeFolder, 0755); nil != mkdirErr {
|
if mkdirErr := os.MkdirAll(writeFolder, 0755); nil != mkdirErr {
|
||||||
logging.LogErrorf("create export temp folder [%s] failed: %s", writeFolder, 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 := 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 {
|
if writeErr := os.WriteFile(writePath, data, 0644); nil != writeErr {
|
||||||
logging.LogErrorf("write export file [%s] failed: %s", writePath, writeErr)
|
logging.LogErrorf("write export file [%s] failed: %s", writePath, writeErr)
|
||||||
continue
|
continue
|
||||||
|
|
@ -1785,7 +1785,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
destPath := filepath.Join(exportFolder, asset)
|
destPath := filepath.Join(exportDir, asset)
|
||||||
assetErr := filelock.Copy(srcPath, destPath)
|
assetErr := filelock.Copy(srcPath, destPath)
|
||||||
if nil != assetErr {
|
if nil != assetErr {
|
||||||
logging.LogErrorf("copy asset from [%s] to [%s] failed: %s", srcPath, destPath, 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)
|
emojis := emojisInTree(tree)
|
||||||
for _, emoji := range emojis {
|
for _, emoji := range emojis {
|
||||||
from := filepath.Join(util.DataDir, emoji)
|
from := filepath.Join(util.DataDir, emoji)
|
||||||
to := filepath.Join(exportFolder, emoji)
|
to := filepath.Join(exportDir, emoji)
|
||||||
if copyErr := filelock.Copy(from, to); copyErr != nil {
|
if copyErr := filelock.Copy(from, to); copyErr != nil {
|
||||||
logging.LogErrorf("copy emojis from [%s] to [%s] failed: %s", from, to, copyErr)
|
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
|
// 导出数据库 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 {
|
for _, tree := range trees {
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
if !entering {
|
if !entering || !n.IsBlock() {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeAttributeView != n.Type {
|
if ast.NodeAttributeView == n.Type {
|
||||||
return ast.WalkContinue
|
avIDs = append(avIDs, n.AttributeViewID)
|
||||||
}
|
}
|
||||||
|
avs := n.IALAttr(av.NodeAttrNameAvs)
|
||||||
avID := n.AttributeViewID
|
for _, avID := range strings.Split(avs, ",") {
|
||||||
avJSONPath := av.GetAttributeViewDataPath(avID)
|
avIDs = append(avIDs, strings.TrimSpace(avID))
|
||||||
if !filelock.IsExist(avJSONPath) {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
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
|
// 导出闪卡 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)
|
deck, loadErr := riff.LoadDeck(exportStorageRiffDir, builtinDeckID, Conf.Flashcard.RequestRetention, Conf.Flashcard.MaximumInterval, Conf.Flashcard.Weights)
|
||||||
if nil != loadErr {
|
if nil != loadErr {
|
||||||
logging.LogErrorf("load deck [%s] failed: %s", name, 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)
|
logging.LogErrorf("marshal sort conf failed: %s", sortErr)
|
||||||
}
|
}
|
||||||
if 0 < len(sortData) {
|
if 0 < len(sortData) {
|
||||||
confDir := filepath.Join(exportFolder, ".siyuan")
|
confDir := filepath.Join(exportDir, ".siyuan")
|
||||||
if mkdirErr := os.MkdirAll(confDir, 0755); nil != mkdirErr {
|
if mkdirErr := os.MkdirAll(confDir, 0755); nil != mkdirErr {
|
||||||
logging.LogErrorf("create export conf folder [%s] failed: %s", confDir, mkdirErr)
|
logging.LogErrorf("create export conf folder [%s] failed: %s", confDir, mkdirErr)
|
||||||
} else {
|
} 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)
|
zip, err := gulu.Zip.Create(zipPath)
|
||||||
if err != nil {
|
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 ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1948,8 +1914,8 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
||||||
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(253), filename))
|
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(253), filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = zip.AddDirectory(baseFolderName, exportFolder, zipCallback); err != nil {
|
if err = zip.AddDirectory(baseFolderName, exportDir, zipCallback); 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 ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1957,11 +1923,55 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
||||||
logging.LogErrorf("close export .sy.zip failed: %s", err)
|
logging.LogErrorf("close export .sy.zip failed: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.RemoveAll(exportFolder)
|
os.RemoveAll(exportDir)
|
||||||
zipPath = "/export/" + url.PathEscape(filepath.Base(zipPath))
|
zipPath = "/export/" + url.PathEscape(filepath.Base(zipPath))
|
||||||
return
|
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) {
|
func exportRelationAvs(avID, exportStorageAvDir string) {
|
||||||
avIDs := hashset.New()
|
avIDs := hashset.New()
|
||||||
walkRelationAvs(avID, avIDs)
|
walkRelationAvs(avID, avIDs)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue