memo_service_converter.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package v1
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "github.com/pkg/errors"
  7. "google.golang.org/protobuf/types/known/timestamppb"
  8. "github.com/usememos/gomark/parser"
  9. "github.com/usememos/gomark/parser/tokenizer"
  10. v1pb "github.com/usememos/memos/proto/gen/api/v1"
  11. storepb "github.com/usememos/memos/proto/gen/store"
  12. "github.com/usememos/memos/store"
  13. )
  14. func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Memo) (*v1pb.Memo, error) {
  15. displayTs := memo.CreatedTs
  16. workspaceMemoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
  17. if err != nil {
  18. return nil, errors.Wrap(err, "failed to get workspace memo related setting")
  19. }
  20. if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
  21. displayTs = memo.UpdatedTs
  22. }
  23. name := fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID)
  24. memoMessage := &v1pb.Memo{
  25. Name: name,
  26. State: convertStateFromStore(memo.RowStatus),
  27. Creator: fmt.Sprintf("%s%d", UserNamePrefix, memo.CreatorID),
  28. CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)),
  29. UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)),
  30. DisplayTime: timestamppb.New(time.Unix(displayTs, 0)),
  31. Content: memo.Content,
  32. Visibility: convertVisibilityFromStore(memo.Visibility),
  33. Pinned: memo.Pinned,
  34. }
  35. if memo.Payload != nil {
  36. memoMessage.Tags = memo.Payload.Tags
  37. memoMessage.Property = convertMemoPropertyFromStore(memo.Payload.Property)
  38. memoMessage.Location = convertLocationFromStore(memo.Payload.Location)
  39. }
  40. if memo.ParentID != nil {
  41. parent, err := s.Store.GetMemo(ctx, &store.FindMemo{
  42. ID: memo.ParentID,
  43. ExcludeContent: true,
  44. })
  45. if err != nil {
  46. return nil, errors.Wrap(err, "failed to get parent memo")
  47. }
  48. parentName := fmt.Sprintf("%s%s", MemoNamePrefix, parent.UID)
  49. memoMessage.Parent = &parentName
  50. }
  51. listMemoRelationsResponse, err := s.ListMemoRelations(ctx, &v1pb.ListMemoRelationsRequest{Name: name})
  52. if err != nil {
  53. return nil, errors.Wrap(err, "failed to list memo relations")
  54. }
  55. memoMessage.Relations = listMemoRelationsResponse.Relations
  56. listMemoResourcesResponse, err := s.ListMemoResources(ctx, &v1pb.ListMemoResourcesRequest{Name: name})
  57. if err != nil {
  58. return nil, errors.Wrap(err, "failed to list memo resources")
  59. }
  60. memoMessage.Resources = listMemoResourcesResponse.Resources
  61. listMemoReactionsResponse, err := s.ListMemoReactions(ctx, &v1pb.ListMemoReactionsRequest{Name: name})
  62. if err != nil {
  63. return nil, errors.Wrap(err, "failed to list memo reactions")
  64. }
  65. memoMessage.Reactions = listMemoReactionsResponse.Reactions
  66. nodes, err := parser.Parse(tokenizer.Tokenize(memo.Content))
  67. if err != nil {
  68. return nil, errors.Wrap(err, "failed to parse content")
  69. }
  70. memoMessage.Nodes = convertFromASTNodes(nodes)
  71. snippet, err := getMemoContentSnippet(memo.Content)
  72. if err != nil {
  73. return nil, errors.Wrap(err, "failed to get memo content snippet")
  74. }
  75. memoMessage.Snippet = snippet
  76. return memoMessage, nil
  77. }
  78. func convertMemoPropertyFromStore(property *storepb.MemoPayload_Property) *v1pb.MemoProperty {
  79. if property == nil {
  80. return nil
  81. }
  82. return &v1pb.MemoProperty{
  83. HasLink: property.HasLink,
  84. HasTaskList: property.HasTaskList,
  85. HasCode: property.HasCode,
  86. HasIncompleteTasks: property.HasIncompleteTasks,
  87. }
  88. }
  89. func convertLocationFromStore(location *storepb.MemoPayload_Location) *v1pb.Location {
  90. if location == nil {
  91. return nil
  92. }
  93. return &v1pb.Location{
  94. Placeholder: location.Placeholder,
  95. Latitude: location.Latitude,
  96. Longitude: location.Longitude,
  97. }
  98. }
  99. func convertLocationToStore(location *v1pb.Location) *storepb.MemoPayload_Location {
  100. if location == nil {
  101. return nil
  102. }
  103. return &storepb.MemoPayload_Location{
  104. Placeholder: location.Placeholder,
  105. Latitude: location.Latitude,
  106. Longitude: location.Longitude,
  107. }
  108. }
  109. func convertVisibilityFromStore(visibility store.Visibility) v1pb.Visibility {
  110. switch visibility {
  111. case store.Private:
  112. return v1pb.Visibility_PRIVATE
  113. case store.Protected:
  114. return v1pb.Visibility_PROTECTED
  115. case store.Public:
  116. return v1pb.Visibility_PUBLIC
  117. default:
  118. return v1pb.Visibility_VISIBILITY_UNSPECIFIED
  119. }
  120. }
  121. func convertVisibilityToStore(visibility v1pb.Visibility) store.Visibility {
  122. switch visibility {
  123. case v1pb.Visibility_PRIVATE:
  124. return store.Private
  125. case v1pb.Visibility_PROTECTED:
  126. return store.Protected
  127. case v1pb.Visibility_PUBLIC:
  128. return store.Public
  129. default:
  130. return store.Private
  131. }
  132. }