workspace_setting.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package store
  2. import (
  3. "context"
  4. "github.com/pkg/errors"
  5. "google.golang.org/protobuf/encoding/protojson"
  6. storepb "github.com/usememos/memos/proto/gen/store"
  7. )
  8. type WorkspaceSetting struct {
  9. Name string
  10. Value string
  11. Description string
  12. }
  13. type FindWorkspaceSetting struct {
  14. Name string
  15. }
  16. type DeleteWorkspaceSetting struct {
  17. Name string
  18. }
  19. func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) {
  20. workspaceSettingRaw := &WorkspaceSetting{
  21. Name: upsert.Key.String(),
  22. }
  23. var valueBytes []byte
  24. var err error
  25. if upsert.Key == storepb.WorkspaceSettingKey_BASIC {
  26. valueBytes, err = protojson.Marshal(upsert.GetBasicSetting())
  27. } else if upsert.Key == storepb.WorkspaceSettingKey_GENERAL {
  28. valueBytes, err = protojson.Marshal(upsert.GetGeneralSetting())
  29. } else if upsert.Key == storepb.WorkspaceSettingKey_STORAGE {
  30. valueBytes, err = protojson.Marshal(upsert.GetStorageSetting())
  31. } else if upsert.Key == storepb.WorkspaceSettingKey_MEMO_RELATED {
  32. valueBytes, err = protojson.Marshal(upsert.GetMemoRelatedSetting())
  33. } else {
  34. return nil, errors.Errorf("unsupported workspace setting key: %v", upsert.Key)
  35. }
  36. if err != nil {
  37. return nil, errors.Wrap(err, "failed to marshal workspace setting value")
  38. }
  39. valueString := string(valueBytes)
  40. workspaceSettingRaw.Value = valueString
  41. workspaceSettingRaw, err = s.driver.UpsertWorkspaceSetting(ctx, workspaceSettingRaw)
  42. if err != nil {
  43. return nil, errors.Wrap(err, "Failed to upsert workspace setting")
  44. }
  45. workspaceSetting, err := convertWorkspaceSettingFromRaw(workspaceSettingRaw)
  46. if err != nil {
  47. return nil, errors.Wrap(err, "Failed to convert workspace setting")
  48. }
  49. s.workspaceSettingCache.Store(workspaceSetting.Key.String(), workspaceSetting)
  50. return workspaceSetting, nil
  51. }
  52. func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*storepb.WorkspaceSetting, error) {
  53. list, err := s.driver.ListWorkspaceSettings(ctx, find)
  54. if err != nil {
  55. return nil, err
  56. }
  57. workspaceSettings := []*storepb.WorkspaceSetting{}
  58. for _, workspaceSettingRaw := range list {
  59. workspaceSetting, err := convertWorkspaceSettingFromRaw(workspaceSettingRaw)
  60. if err != nil {
  61. return nil, errors.Wrap(err, "Failed to convert workspace setting")
  62. }
  63. if workspaceSetting == nil {
  64. continue
  65. }
  66. s.workspaceSettingCache.Store(workspaceSetting.Key.String(), workspaceSetting)
  67. workspaceSettings = append(workspaceSettings, workspaceSetting)
  68. }
  69. return workspaceSettings, nil
  70. }
  71. func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*storepb.WorkspaceSetting, error) {
  72. if cache, ok := s.workspaceSettingCache.Load(find.Name); ok {
  73. workspaceSetting, ok := cache.(*storepb.WorkspaceSetting)
  74. if ok {
  75. return workspaceSetting, nil
  76. }
  77. }
  78. list, err := s.ListWorkspaceSettings(ctx, find)
  79. if err != nil {
  80. return nil, err
  81. }
  82. if len(list) == 0 {
  83. return nil, nil
  84. }
  85. if len(list) > 1 {
  86. return nil, errors.Errorf("found multiple workspace settings with key %s", find.Name)
  87. }
  88. return list[0], nil
  89. }
  90. func (s *Store) GetWorkspaceBasicSetting(ctx context.Context) (*storepb.WorkspaceBasicSetting, error) {
  91. workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
  92. Name: storepb.WorkspaceSettingKey_BASIC.String(),
  93. })
  94. if err != nil {
  95. return nil, errors.Wrap(err, "failed to get workspace basic setting")
  96. }
  97. workspaceBasicSetting := &storepb.WorkspaceBasicSetting{}
  98. if workspaceSetting != nil {
  99. workspaceBasicSetting = workspaceSetting.GetBasicSetting()
  100. }
  101. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_BASIC.String(), &storepb.WorkspaceSetting{
  102. Key: storepb.WorkspaceSettingKey_BASIC,
  103. Value: &storepb.WorkspaceSetting_BasicSetting{BasicSetting: workspaceBasicSetting},
  104. })
  105. return workspaceBasicSetting, nil
  106. }
  107. func (s *Store) GetWorkspaceGeneralSetting(ctx context.Context) (*storepb.WorkspaceGeneralSetting, error) {
  108. workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
  109. Name: storepb.WorkspaceSettingKey_GENERAL.String(),
  110. })
  111. if err != nil {
  112. return nil, errors.Wrap(err, "failed to get workspace general setting")
  113. }
  114. workspaceGeneralSetting := &storepb.WorkspaceGeneralSetting{}
  115. if workspaceSetting != nil {
  116. workspaceGeneralSetting = workspaceSetting.GetGeneralSetting()
  117. }
  118. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_GENERAL.String(), &storepb.WorkspaceSetting{
  119. Key: storepb.WorkspaceSettingKey_GENERAL,
  120. Value: &storepb.WorkspaceSetting_GeneralSetting{GeneralSetting: workspaceGeneralSetting},
  121. })
  122. return workspaceGeneralSetting, nil
  123. }
  124. // DefaultContentLengthLimit is the default limit of content length in bytes. 8KB.
  125. const DefaultContentLengthLimit = 8 * 1024
  126. // DefaultReactions is the default reactions for memo related setting.
  127. var DefaultReactions = []string{"👍", "👎", "❤️", "🎉", "😄", "😕", "😢", "😡"}
  128. func (s *Store) GetWorkspaceMemoRelatedSetting(ctx context.Context) (*storepb.WorkspaceMemoRelatedSetting, error) {
  129. workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
  130. Name: storepb.WorkspaceSettingKey_MEMO_RELATED.String(),
  131. })
  132. if err != nil {
  133. return nil, errors.Wrap(err, "failed to get workspace general setting")
  134. }
  135. workspaceMemoRelatedSetting := &storepb.WorkspaceMemoRelatedSetting{}
  136. if workspaceSetting != nil {
  137. workspaceMemoRelatedSetting = workspaceSetting.GetMemoRelatedSetting()
  138. }
  139. if workspaceMemoRelatedSetting.ContentLengthLimit < DefaultContentLengthLimit {
  140. workspaceMemoRelatedSetting.ContentLengthLimit = DefaultContentLengthLimit
  141. }
  142. if len(workspaceMemoRelatedSetting.Reactions) == 0 {
  143. workspaceMemoRelatedSetting.Reactions = append(workspaceMemoRelatedSetting.Reactions, DefaultReactions...)
  144. }
  145. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_MEMO_RELATED.String(), &storepb.WorkspaceSetting{
  146. Key: storepb.WorkspaceSettingKey_MEMO_RELATED,
  147. Value: &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: workspaceMemoRelatedSetting},
  148. })
  149. return workspaceMemoRelatedSetting, nil
  150. }
  151. const (
  152. defaultWorkspaceStorageType = storepb.WorkspaceStorageSetting_DATABASE
  153. defaultWorkspaceUploadSizeLimitMb = 30
  154. defaultWorkspaceFilepathTemplate = "assets/{timestamp}_{filename}"
  155. )
  156. func (s *Store) GetWorkspaceStorageSetting(ctx context.Context) (*storepb.WorkspaceStorageSetting, error) {
  157. workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
  158. Name: storepb.WorkspaceSettingKey_STORAGE.String(),
  159. })
  160. if err != nil {
  161. return nil, errors.Wrap(err, "failed to get workspace storage setting")
  162. }
  163. workspaceStorageSetting := &storepb.WorkspaceStorageSetting{}
  164. if workspaceSetting != nil {
  165. workspaceStorageSetting = workspaceSetting.GetStorageSetting()
  166. }
  167. if workspaceStorageSetting.StorageType == storepb.WorkspaceStorageSetting_STORAGE_TYPE_UNSPECIFIED {
  168. workspaceStorageSetting.StorageType = defaultWorkspaceStorageType
  169. }
  170. if workspaceStorageSetting.UploadSizeLimitMb == 0 {
  171. workspaceStorageSetting.UploadSizeLimitMb = defaultWorkspaceUploadSizeLimitMb
  172. }
  173. if workspaceStorageSetting.FilepathTemplate == "" {
  174. workspaceStorageSetting.FilepathTemplate = defaultWorkspaceFilepathTemplate
  175. }
  176. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_STORAGE.String(), &storepb.WorkspaceSetting{
  177. Key: storepb.WorkspaceSettingKey_STORAGE,
  178. Value: &storepb.WorkspaceSetting_StorageSetting{StorageSetting: workspaceStorageSetting},
  179. })
  180. return workspaceStorageSetting, nil
  181. }
  182. func convertWorkspaceSettingFromRaw(workspaceSettingRaw *WorkspaceSetting) (*storepb.WorkspaceSetting, error) {
  183. workspaceSetting := &storepb.WorkspaceSetting{
  184. Key: storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[workspaceSettingRaw.Name]),
  185. }
  186. switch workspaceSettingRaw.Name {
  187. case storepb.WorkspaceSettingKey_BASIC.String():
  188. basicSetting := &storepb.WorkspaceBasicSetting{}
  189. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), basicSetting); err != nil {
  190. return nil, err
  191. }
  192. workspaceSetting.Value = &storepb.WorkspaceSetting_BasicSetting{BasicSetting: basicSetting}
  193. case storepb.WorkspaceSettingKey_GENERAL.String():
  194. generalSetting := &storepb.WorkspaceGeneralSetting{}
  195. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), generalSetting); err != nil {
  196. return nil, err
  197. }
  198. workspaceSetting.Value = &storepb.WorkspaceSetting_GeneralSetting{GeneralSetting: generalSetting}
  199. case storepb.WorkspaceSettingKey_STORAGE.String():
  200. storageSetting := &storepb.WorkspaceStorageSetting{}
  201. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), storageSetting); err != nil {
  202. return nil, err
  203. }
  204. workspaceSetting.Value = &storepb.WorkspaceSetting_StorageSetting{StorageSetting: storageSetting}
  205. case storepb.WorkspaceSettingKey_MEMO_RELATED.String():
  206. memoRelatedSetting := &storepb.WorkspaceMemoRelatedSetting{}
  207. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), memoRelatedSetting); err != nil {
  208. return nil, err
  209. }
  210. workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting}
  211. default:
  212. // Skip unsupported workspace setting key.
  213. return nil, nil
  214. }
  215. return workspaceSetting, nil
  216. }