refactor: move tags from property to payload (#4229)

* refactor: move tags from property to payload

* chore: fix tests

* chore: drop memo tags

* chore: update

---------

Co-authored-by: Steven <stevenlgtm@gmail.com>
This commit is contained in:
Johnny
2024-12-24 23:23:15 +08:00
committed by GitHub
parent f15346e615
commit e913271f15
38 changed files with 1483 additions and 1441 deletions

View File

@ -21,11 +21,10 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/webhook"
v1pb "github.com/usememos/memos/proto/gen/api/v1"
storepb "github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/server/runner/memoproperty"
"github.com/usememos/memos/server/runner/memopayload"
"github.com/usememos/memos/store"
)
@ -60,12 +59,8 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR
if len(create.Content) > contentLengthLimit {
return nil, status.Errorf(codes.InvalidArgument, "content too long (max %d characters)", contentLengthLimit)
}
property, err := memoproperty.GetMemoPropertyFromContent(create.Content)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
}
create.Payload = &storepb.MemoPayload{
Property: property,
if err := memopayload.RebuildMemoPayload(create); err != nil {
return nil, status.Errorf(codes.Internal, "failed to rebuild memo payload: %v", err)
}
if request.Location != nil {
create.Payload.Location = convertLocationToStore(request.Location)
@ -269,20 +264,12 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
if len(request.Memo.Content) > contentLengthLimit {
return nil, status.Errorf(codes.InvalidArgument, "content too long (max %d characters)", contentLengthLimit)
}
update.Content = &request.Memo.Content
property, err := memoproperty.GetMemoPropertyFromContent(*update.Content)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
}
payload := memo.Payload
payload.Property = property
update.Payload = payload
} else if path == "uid" {
update.UID = &request.Memo.Uid
if !util.UIDMatcher.MatchString(*update.UID) {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource name")
memo.Content = request.Memo.Content
if err := memopayload.RebuildMemoPayload(memo); err != nil {
return nil, status.Errorf(codes.Internal, "failed to rebuild memo payload: %v", err)
}
update.Content = &memo.Content
update.Payload = memo.Payload
} else if path == "visibility" {
workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
if err != nil {
@ -565,23 +552,19 @@ func (s *APIV1Service) RenameMemoTag(ctx context.Context, request *v1pb.RenameMe
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to parse memo: %v", err)
}
memoproperty.TraverseASTNodes(nodes, func(node ast.Node) {
memopayload.TraverseASTNodes(nodes, func(node ast.Node) {
if tag, ok := node.(*ast.Tag); ok && tag.Content == request.OldTag {
tag.Content = request.NewTag
}
})
content := restore.Restore(nodes)
property, err := memoproperty.GetMemoPropertyFromContent(content)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
memo.Content = restore.Restore(nodes)
if err := memopayload.RebuildMemoPayload(memo); err != nil {
return nil, status.Errorf(codes.Internal, "failed to rebuild memo payload: %v", err)
}
payload := memo.Payload
payload.Property = property
if err := s.Store.UpdateMemo(ctx, &store.UpdateMemo{
ID: memo.ID,
Content: &content,
Payload: payload,
Content: &memo.Content,
Payload: memo.Payload,
}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to update memo: %v", err)
}
@ -658,6 +641,7 @@ func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Mem
Content: memo.Content,
Visibility: convertVisibilityFromStore(memo.Visibility),
Pinned: memo.Pinned,
Tags: memo.Payload.Tags,
}
if memo.Payload != nil {
memoMessage.Property = convertMemoPropertyFromStore(memo.Payload.Property)
@ -709,7 +693,6 @@ func convertMemoPropertyFromStore(property *storepb.MemoPayload_Property) *v1pb.
return nil
}
return &v1pb.MemoProperty{
Tags: property.Tags,
HasLink: property.HasLink,
HasTaskList: property.HasTaskList,
HasCode: property.HasCode,

View File

@ -1,4 +1,4 @@
package memoproperty
package memopayload
import (
"context"
@ -43,24 +43,17 @@ func (r *Runner) Run(ctx context.Context) {
}
func (r *Runner) RunOnce(ctx context.Context) {
emptyPayload := "{}"
memos, err := r.Store.ListMemos(ctx, &store.FindMemo{
PayloadFind: &store.FindMemoPayload{
Raw: &emptyPayload,
},
})
memos, err := r.Store.ListMemos(ctx, &store.FindMemo{})
if err != nil {
slog.Error("failed to list memos", "err", err)
return
}
for _, memo := range memos {
property, err := GetMemoPropertyFromContent(memo.Content)
if err != nil {
slog.Error("failed to get memo property", "err", err)
if err := RebuildMemoPayload(memo); err != nil {
slog.Error("failed to rebuild memo payload", "err", err)
continue
}
memo.Payload.Property = property
if err := r.Store.UpdateMemo(ctx, &store.UpdateMemo{
ID: memo.ID,
Payload: memo.Payload,
@ -70,19 +63,23 @@ func (r *Runner) RunOnce(ctx context.Context) {
}
}
func GetMemoPropertyFromContent(content string) (*storepb.MemoPayload_Property, error) {
nodes, err := parser.Parse(tokenizer.Tokenize(content))
func RebuildMemoPayload(memo *store.Memo) error {
nodes, err := parser.Parse(tokenizer.Tokenize(memo.Content))
if err != nil {
return nil, errors.Wrap(err, "failed to parse content")
return errors.Wrap(err, "failed to parse content")
}
if memo.Payload == nil {
memo.Payload = &storepb.MemoPayload{}
}
tags := []string{}
property := &storepb.MemoPayload_Property{}
TraverseASTNodes(nodes, func(node ast.Node) {
switch n := node.(type) {
case *ast.Tag:
tag := n.Content
if !slices.Contains(property.Tags, tag) {
property.Tags = append(property.Tags, tag)
if !slices.Contains(tags, tag) {
tags = append(tags, tag)
}
case *ast.Link, *ast.AutoLink:
property.HasLink = true
@ -95,7 +92,9 @@ func GetMemoPropertyFromContent(content string) (*storepb.MemoPayload_Property,
property.HasCode = true
}
})
return property, nil
memo.Payload.Tags = tags
memo.Payload.Property = property
return nil
}
func TraverseASTNodes(nodes []ast.Node, fn func(ast.Node)) {

View File

@ -22,7 +22,7 @@ import (
apiv1 "github.com/usememos/memos/server/router/api/v1"
"github.com/usememos/memos/server/router/frontend"
"github.com/usememos/memos/server/router/rss"
"github.com/usememos/memos/server/runner/memoproperty"
"github.com/usememos/memos/server/runner/memopayload"
"github.com/usememos/memos/server/runner/s3presign"
"github.com/usememos/memos/server/runner/version"
"github.com/usememos/memos/store"
@ -146,12 +146,12 @@ func (s *Server) StartBackgroundRunners(ctx context.Context) {
s3presignRunner.RunOnce(ctx)
versionRunner := version.NewRunner(s.Store, s.Profile)
versionRunner.RunOnce(ctx)
memopropertyRunner := memoproperty.NewRunner(s.Store)
memopropertyRunner.RunOnce(ctx)
memopayloadRunner := memopayload.NewRunner(s.Store)
memopayloadRunner.RunOnce(ctx)
go s3presignRunner.Run(ctx)
go versionRunner.Run(ctx)
go memopropertyRunner.Run(ctx)
go memopayloadRunner.Run(ctx)
}
func (s *Server) getOrUpsertWorkspaceBasicSetting(ctx context.Context) (*storepb.WorkspaceBasicSetting, error) {