diff --git a/kernel/model/history.go b/kernel/model/history.go index 265ed4fc0..29015c95a 100644 --- a/kernel/model/history.go +++ b/kernel/model/history.go @@ -18,6 +18,7 @@ package model import ( "encoding/json" + "errors" "fmt" "io" "io/fs" @@ -28,6 +29,7 @@ import ( "time" "github.com/88250/gulu" + "github.com/88250/lute" "github.com/88250/lute/parse" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" @@ -48,6 +50,8 @@ func AutoGenerateDocHistory() { } func generateDocHistory() { + defer logging.Recover() + if 1 > Conf.Editor.GenerateHistoryInterval { return } @@ -504,6 +508,9 @@ func (box *Box) generateDocHistory0() { return } } + + luteEngine := NewLute() + indexHistoryDir(filepath.Base(historyDir), luteEngine) return } @@ -610,7 +617,6 @@ func indexHistory() { return } - validOps := []string{HistoryOpClean, HistoryOpUpdate, HistoryOpDelete, HistoryOpFormat} lutEngine := NewLute() for _, historyDir := range historyDirs { if !historyDir.IsDir() { @@ -618,77 +624,90 @@ func indexHistory() { } name := historyDir.Name() - op := name[strings.LastIndex(name, "-")+1:] - if !gulu.Str.Contains(op, validOps) { - logging.LogWarnf("invalid history op [%s]", op) - continue - } - t := name[:strings.LastIndex(name, "-")] - tt, parseErr := time.Parse("2006-01-02-150405", t) - if nil != parseErr { - logging.LogWarnf("parse time [%s] failed: %s", t, parseErr) - continue - } - created := fmt.Sprintf("%d", tt.Unix()) - - entryPath := filepath.Join(util.HistoryDir, name) - var docs, assets []string - filepath.Walk(entryPath, func(path string, info os.FileInfo, err error) error { - if strings.HasSuffix(info.Name(), ".sy") { - docs = append(docs, path) - } else if strings.Contains(path, "assets/") { - assets = append(assets, path) - } - return nil - }) - - var histories []*sql.History - for _, doc := range docs { - tree, loadErr := loadTree(doc, lutEngine) - if nil != loadErr { - logging.LogErrorf("load tree [%s] failed: %s", doc, loadErr) - continue - } - - title := tree.Root.IALAttr("title") - content := tree.Root.Content() - p := strings.TrimPrefix(doc, util.HistoryDir) - p = filepath.ToSlash(p[1:]) - histories = append(histories, &sql.History{ - Type: 0, - Op: op, - Title: title, - Content: content, - Path: p, - Created: created, - }) - } - - for _, asset := range assets { - p := strings.TrimPrefix(asset, util.HistoryDir) - p = filepath.ToSlash(p[1:]) - histories = append(histories, &sql.History{ - Type: 1, - Op: op, - Title: filepath.Base(asset), - Path: p, - Created: created, - }) - } - - tx, txErr := sql.BeginHistoryTx() - if nil != txErr { - logging.LogErrorf("begin transaction failed: %s", txErr) - return - } - if err = sql.InsertHistories(tx, histories); nil != err { - logging.LogErrorf("insert histories failed: %s", err) - sql.RollbackTx(tx) - return - } - if err = sql.CommitTx(tx); nil != err { - logging.LogErrorf("commit transaction failed: %s", err) + err = indexHistoryDir(name, lutEngine) + if nil != err { return } } } + +var validOps = []string{HistoryOpClean, HistoryOpUpdate, HistoryOpDelete, HistoryOpFormat} + +func indexHistoryDir(name string, luteEngine *lute.Lute) (err error) { + op := name[strings.LastIndex(name, "-")+1:] + if !gulu.Str.Contains(op, validOps) { + logging.LogWarnf("invalid history op [%s]", op) + return + } + t := name[:strings.LastIndex(name, "-")] + tt, parseErr := time.Parse("2006-01-02-150405", t) + if nil != parseErr { + logging.LogWarnf("parse history dir time [%s] failed: %s", t, parseErr) + return + } + created := fmt.Sprintf("%d", tt.Unix()) + + entryPath := filepath.Join(util.HistoryDir, name) + var docs, assets []string + filepath.Walk(entryPath, func(path string, info os.FileInfo, err error) error { + if strings.HasSuffix(info.Name(), ".sy") { + docs = append(docs, path) + } else if strings.Contains(path, "assets/") { + assets = append(assets, path) + } + return nil + }) + + var histories []*sql.History + for _, doc := range docs { + tree, loadErr := loadTree(doc, luteEngine) + if nil != loadErr { + logging.LogErrorf("load tree [%s] failed: %s", doc, loadErr) + continue + } + + title := tree.Root.IALAttr("title") + content := tree.Root.Content() + p := strings.TrimPrefix(doc, util.HistoryDir) + p = filepath.ToSlash(p[1:]) + histories = append(histories, &sql.History{ + Type: 0, + Op: op, + Title: title, + Content: content, + Path: p, + Created: created, + }) + } + + for _, asset := range assets { + p := strings.TrimPrefix(asset, util.HistoryDir) + p = filepath.ToSlash(p[1:]) + histories = append(histories, &sql.History{ + Type: 1, + Op: op, + Title: filepath.Base(asset), + Path: p, + Created: created, + }) + } + + tx, txErr := sql.BeginHistoryTx() + if nil != txErr { + msg := fmt.Sprintf("begin transaction failed: %s", txErr) + err = errors.New(msg) + return + } + if err = sql.InsertHistories(tx, histories); nil != err { + msg := fmt.Sprintf("insert histories failed: %s", err) + err = errors.New(msg) + sql.RollbackTx(tx) + return + } + if err = sql.CommitTx(tx); nil != err { + msg := fmt.Sprintf("commit transaction failed: %s", err) + err = errors.New(msg) + return + } + return +}