workspace_setting.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. const (
  125. // DefaultContentLengthLimit is the default limit of content length in bytes. 8KB.
  126. DefaultContentLengthLimit = 8 * 1024
  127. )
  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. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_MEMO_RELATED.String(), &storepb.WorkspaceSetting{
  143. Key: storepb.WorkspaceSettingKey_MEMO_RELATED,
  144. Value: &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: workspaceMemoRelatedSetting},
  145. })
  146. return workspaceMemoRelatedSetting, nil
  147. }
  148. const (
  149. defaultWorkspaceStorageType = storepb.WorkspaceStorageSetting_DATABASE
  150. defaultWorkspaceUploadSizeLimitMb = 30
  151. defaultWorkspaceFilepathTemplate = "assets/{timestamp}_{filename}"
  152. )
  153. func (s *Store) GetWorkspaceStorageSetting(ctx context.Context) (*storepb.WorkspaceStorageSetting, error) {
  154. workspaceSetting, err := s.GetWorkspaceSetting(ctx, &FindWorkspaceSetting{
  155. Name: storepb.WorkspaceSettingKey_STORAGE.String(),
  156. })
  157. if err != nil {
  158. return nil, errors.Wrap(err, "failed to get workspace storage setting")
  159. }
  160. workspaceStorageSetting := &storepb.WorkspaceStorageSetting{}
  161. if workspaceSetting != nil {
  162. workspaceStorageSetting = workspaceSetting.GetStorageSetting()
  163. }
  164. if workspaceStorageSetting.StorageType == storepb.WorkspaceStorageSetting_STORAGE_TYPE_UNSPECIFIED {
  165. workspaceStorageSetting.StorageType = defaultWorkspaceStorageType
  166. }
  167. if workspaceStorageSetting.UploadSizeLimitMb == 0 {
  168. workspaceStorageSetting.UploadSizeLimitMb = defaultWorkspaceUploadSizeLimitMb
  169. }
  170. if workspaceStorageSetting.FilepathTemplate == "" {
  171. workspaceStorageSetting.FilepathTemplate = defaultWorkspaceFilepathTemplate
  172. }
  173. s.workspaceSettingCache.Store(storepb.WorkspaceSettingKey_STORAGE.String(), &storepb.WorkspaceSetting{
  174. Key: storepb.WorkspaceSettingKey_STORAGE,
  175. Value: &storepb.WorkspaceSetting_StorageSetting{StorageSetting: workspaceStorageSetting},
  176. })
  177. return workspaceStorageSetting, nil
  178. }
  179. func convertWorkspaceSettingFromRaw(workspaceSettingRaw *WorkspaceSetting) (*storepb.WorkspaceSetting, error) {
  180. workspaceSetting := &storepb.WorkspaceSetting{
  181. Key: storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[workspaceSettingRaw.Name]),
  182. }
  183. switch workspaceSettingRaw.Name {
  184. case storepb.WorkspaceSettingKey_BASIC.String():
  185. basicSetting := &storepb.WorkspaceBasicSetting{}
  186. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), basicSetting); err != nil {
  187. return nil, err
  188. }
  189. workspaceSetting.Value = &storepb.WorkspaceSetting_BasicSetting{BasicSetting: basicSetting}
  190. case storepb.WorkspaceSettingKey_GENERAL.String():
  191. generalSetting := &storepb.WorkspaceGeneralSetting{}
  192. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), generalSetting); err != nil {
  193. return nil, err
  194. }
  195. workspaceSetting.Value = &storepb.WorkspaceSetting_GeneralSetting{GeneralSetting: generalSetting}
  196. case storepb.WorkspaceSettingKey_STORAGE.String():
  197. storageSetting := &storepb.WorkspaceStorageSetting{}
  198. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), storageSetting); err != nil {
  199. return nil, err
  200. }
  201. workspaceSetting.Value = &storepb.WorkspaceSetting_StorageSetting{StorageSetting: storageSetting}
  202. case storepb.WorkspaceSettingKey_MEMO_RELATED.String():
  203. memoRelatedSetting := &storepb.WorkspaceMemoRelatedSetting{}
  204. if err := protojsonUnmarshaler.Unmarshal([]byte(workspaceSettingRaw.Value), memoRelatedSetting); err != nil {
  205. return nil, err
  206. }
  207. workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting}
  208. default:
  209. // Skip unsupported workspace setting key.
  210. return nil, nil
  211. }
  212. return workspaceSetting, nil
  213. }