Преглед изворни кода

:art: 支持数据快照对比 https://github.com/siyuan-note/siyuan/issues/6858

Liang Ding пре 2 година
родитељ
комит
d13adf234b
4 измењених фајлова са 121 додато и 24 уклоњено
  1. 2 4
      kernel/api/repo.go
  2. 3 3
      kernel/go.mod
  3. 6 0
      kernel/go.sum
  4. 110 17
      kernel/model/repository.go

+ 2 - 4
kernel/api/repo.go

@@ -62,7 +62,7 @@ func diffRepoSnapshots(c *gin.Context) {
 
 	left := arg["left"].(string)
 	right := arg["right"].(string)
-	adds, updates, removes, err := model.DiffRepoSnapshots(left, right)
+	diff, err := model.DiffRepoSnapshots(left, right)
 	if nil != err {
 		ret.Code = -1
 		ret.Msg = err.Error()
@@ -70,9 +70,7 @@ func diffRepoSnapshots(c *gin.Context) {
 	}
 
 	ret.Data = map[string]interface{}{
-		"adds":    adds,
-		"updates": updates,
-		"removes": removes,
+		"diff": diff,
 	}
 }
 

+ 3 - 3
kernel/go.mod

@@ -39,7 +39,7 @@ require (
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/radovskyb/watcher v1.0.7
 	github.com/shirou/gopsutil/v3 v3.22.11
-	github.com/siyuan-note/dejavu v0.0.0-20221215030457-cdeb29f2189f
+	github.com/siyuan-note/dejavu v0.0.0-20221217082303-2b63c518c7b1
 	github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75
 	github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da
 	github.com/siyuan-note/filelock v0.0.0-20221117095924-e1947438a35e
@@ -61,7 +61,7 @@ require (
 	github.com/alecthomas/chroma v0.10.0 // indirect
 	github.com/andybalholm/cascadia v1.3.1 // indirect
 	github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef // indirect
-	github.com/aws/aws-sdk-go v1.44.160 // indirect
+	github.com/aws/aws-sdk-go v1.44.162 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/dlclark/regexp2 v1.7.0 // indirect
 	github.com/dsnet/compress v0.0.1 // indirect
@@ -119,7 +119,7 @@ require (
 	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
 	golang.org/x/crypto v0.4.0 // indirect
-	golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 // indirect
+	golang.org/x/exp v0.0.0-20221215174704-0915cd710c24 // indirect
 	golang.org/x/mod v0.7.0 // indirect
 	golang.org/x/net v0.4.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect

+ 6 - 0
kernel/go.sum

@@ -48,6 +48,8 @@ github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef h1:2JGTg6JapxP
 github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII=
 github.com/aws/aws-sdk-go v1.44.160 h1:F41sWUel1CJ69ezoBGCg8sDyu9kyeKEpwmDrLXbCuyA=
 github.com/aws/aws-sdk-go v1.44.160/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
+github.com/aws/aws-sdk-go v1.44.162 h1:hKAd+X+/BLxVMzH+4zKxbQcQQGrk2UhFX0OTu1Mhon8=
+github.com/aws/aws-sdk-go v1.44.162/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
@@ -373,6 +375,8 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED
 github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
 github.com/siyuan-note/dejavu v0.0.0-20221215030457-cdeb29f2189f h1:ufAgHjQdpXsEN0CVnMbXng3qyObITEw7dnoiSBlbjL0=
 github.com/siyuan-note/dejavu v0.0.0-20221215030457-cdeb29f2189f/go.mod h1:aarwJw3uJaqNoIGVLmyhZjMCjI+xAzwrMIg05scqmtc=
+github.com/siyuan-note/dejavu v0.0.0-20221217082303-2b63c518c7b1 h1:OsKmVwcihgfoylPB4+qjJ5q0GuZgUPBBDXQ9hMs4zZM=
+github.com/siyuan-note/dejavu v0.0.0-20221217082303-2b63c518c7b1/go.mod h1:aarwJw3uJaqNoIGVLmyhZjMCjI+xAzwrMIg05scqmtc=
 github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75 h1:Bi7/7f29LW+Fm0cHc0J1NO1cZqyJwljSWVmfOqVZgaE=
 github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75/go.mod h1:H8fyqqAbp9XreANjeSbc72zEdFfKTXYN34tc1TjZwtw=
 github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da h1:/jNhl7LC+9BhkWvNxuJDdsNfA/2wvfuj9mqWx4CbV90=
@@ -456,6 +460,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
 golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 h1:OvjRkcNHnf6/W5FZXSxODbxwD+X7fspczG7Jn/xQVD4=
 golang.org/x/exp v0.0.0-20221212164502-fae10dda9338/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/exp v0.0.0-20221215174704-0915cd710c24 h1:6w3iSY8IIkp5OQtbYj8NeuKG1jS9d+kYaubXqsoOiQ8=
+golang.org/x/exp v0.0.0-20221215174704-0915cd710c24/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190823064033-3a9bac650e44/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=

+ 110 - 17
kernel/model/repository.go

@@ -34,6 +34,7 @@ import (
 	"time"
 
 	"github.com/88250/gulu"
+	"github.com/88250/lute"
 	"github.com/88250/lute/ast"
 	"github.com/88250/lute/parse"
 	"github.com/88250/lute/render"
@@ -77,20 +78,8 @@ func OpenRepoSnapshotDoc(fileID string) (id, rootID, content string, isLargeDoc
 	if nil != err {
 		return
 	}
-
-	file, err := repo.GetFile(fileID)
-	if nil != err {
-		return
-	}
-
-	data, err := repo.OpenFile(file)
-	if nil != err {
-		return
-	}
-
-	isLargeDoc = 1024*1024*1 <= len(data)
 	luteEngine := NewLute()
-	snapshotTree, err := parse.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
+	isLargeDoc, snapshotTree, err := parseTreeInSnapshot(fileID, repo, luteEngine)
 	if nil != err {
 		logging.LogErrorf("parse tree from snapshot file [%s] failed", fileID)
 		return
@@ -138,7 +127,19 @@ func OpenRepoSnapshotDoc(fileID string) (id, rootID, content string, isLargeDoc
 	return
 }
 
-func DiffRepoSnapshots(left, right string) (adds, updates, removes []*entity.File, err error) {
+type LeftRightDiff struct {
+	AddsLeft     []*DiffFile
+	UpdatesLeft  []*DiffFile
+	UpdatesRight []*DiffFile
+	RemovesRight []*DiffFile
+}
+
+type DiffFile struct {
+	FileID string
+	Title  string
+}
+
+func DiffRepoSnapshots(left, right string) (ret *LeftRightDiff, err error) {
 	if 1 > len(Conf.Repo.Key) {
 		err = errors.New(Conf.Language(26))
 		return
@@ -149,16 +150,108 @@ func DiffRepoSnapshots(left, right string) (adds, updates, removes []*entity.Fil
 		return
 	}
 
-	leftIndex, err := repo.GetIndex(left)
+	diff, err := repo.DiffIndex(left, right)
+	if nil != err {
+		return
+	}
+
+	luteEngine := NewLute()
+	for _, addLeft := range diff.AddsLeft {
+		title, err := parseTitleInSnapshot(addLeft.ID, repo, luteEngine)
+		if nil != err {
+			logging.LogErrorf("parse title from snapshot file [%s] failed", addLeft.ID)
+			continue
+		}
+
+		ret.AddsLeft = append(ret.AddsLeft, &DiffFile{
+			FileID: addLeft.ID,
+			Title:  title,
+		})
+	}
+
+	for _, updateLeft := range diff.UpdatesLeft {
+		title, err := parseTitleInSnapshot(updateLeft.ID, repo, luteEngine)
+		if nil != err {
+			logging.LogErrorf("parse title from snapshot file [%s] failed", updateLeft.ID)
+			continue
+		}
+
+		ret.UpdatesLeft = append(ret.UpdatesLeft, &DiffFile{
+			FileID: updateLeft.ID,
+			Title:  title,
+		})
+	}
+
+	for _, updateRight := range diff.UpdatesRight {
+		title, err := parseTitleInSnapshot(updateRight.ID, repo, luteEngine)
+		if nil != err {
+			logging.LogErrorf("parse title from snapshot file [%s] failed", updateRight.ID)
+			continue
+		}
+
+		ret.UpdatesRight = append(ret.UpdatesRight, &DiffFile{
+			FileID: updateRight.ID,
+			Title:  title,
+		})
+	}
+
+	for _, removeRight := range diff.RemovesRight {
+		title, err := parseTitleInSnapshot(removeRight.ID, repo, luteEngine)
+		if nil != err {
+			logging.LogErrorf("parse title from snapshot file [%s] failed", removeRight.ID)
+			continue
+		}
+
+		ret.RemovesRight = append(ret.RemovesRight, &DiffFile{
+			FileID: removeRight.ID,
+			Title:  title,
+		})
+	}
+	return
+}
+
+func parseTitleInSnapshot(fileID string, repo *dejavu.Repo, luteEngine *lute.Lute) (title string, err error) {
+	file, err := repo.GetFile(fileID)
+	if nil != err {
+		return
+	}
+
+	if strings.HasSuffix(file.Path, ".sy") {
+		var data []byte
+		data, err = repo.OpenFile(file)
+		if nil != err {
+			return
+		}
+
+		var tree *parse.Tree
+		tree, err = parse.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
+		if nil != err {
+			return
+		}
+
+		title = tree.Root.IALAttr("title")
+	} else {
+		title = path.Base(file.Path)
+	}
+	return
+}
+
+func parseTreeInSnapshot(fileID string, repo *dejavu.Repo, luteEngine *lute.Lute) (isLargeDoc bool, tree *parse.Tree, err error) {
+	file, err := repo.GetFile(fileID)
 	if nil != err {
 		return
 	}
-	rightIndex, err := repo.GetIndex(right)
+
+	data, err := repo.OpenFile(file)
 	if nil != err {
 		return
 	}
 
-	adds, updates, removes, err = repo.DiffIndex(leftIndex, rightIndex)
+	isLargeDoc = 1024*1024*1 <= len(data)
+	tree, err = parse.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
+	if nil != err {
+		return
+	}
 	return
 }