mirror of https://github.com/usememos/memos
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
9.2 KiB
Go
246 lines
9.2 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
|
|
storepb "github.com/usememos/memos/proto/gen/store"
|
|
)
|
|
|
|
type InstanceSetting struct {
|
|
Name string
|
|
Value string
|
|
Description string
|
|
}
|
|
|
|
type FindInstanceSetting struct {
|
|
Name string
|
|
}
|
|
|
|
type DeleteInstanceSetting struct {
|
|
Name string
|
|
}
|
|
|
|
func (s *Store) UpsertInstanceSetting(ctx context.Context, upsert *storepb.InstanceSetting) (*storepb.InstanceSetting, error) {
|
|
instanceSettingRaw := &InstanceSetting{
|
|
Name: upsert.Key.String(),
|
|
}
|
|
var valueBytes []byte
|
|
var err error
|
|
if upsert.Key == storepb.InstanceSettingKey_BASIC {
|
|
valueBytes, err = protojson.Marshal(upsert.GetBasicSetting())
|
|
} else if upsert.Key == storepb.InstanceSettingKey_GENERAL {
|
|
valueBytes, err = protojson.Marshal(upsert.GetGeneralSetting())
|
|
} else if upsert.Key == storepb.InstanceSettingKey_STORAGE {
|
|
valueBytes, err = protojson.Marshal(upsert.GetStorageSetting())
|
|
} else if upsert.Key == storepb.InstanceSettingKey_MEMO_RELATED {
|
|
valueBytes, err = protojson.Marshal(upsert.GetMemoRelatedSetting())
|
|
} else {
|
|
return nil, errors.Errorf("unsupported instance setting key: %v", upsert.Key)
|
|
}
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to marshal instance setting value")
|
|
}
|
|
valueString := string(valueBytes)
|
|
instanceSettingRaw.Value = valueString
|
|
instanceSettingRaw, err = s.driver.UpsertInstanceSetting(ctx, instanceSettingRaw)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Failed to upsert instance setting")
|
|
}
|
|
instanceSetting, err := convertInstanceSettingFromRaw(instanceSettingRaw)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Failed to convert instance setting")
|
|
}
|
|
s.instanceSettingCache.Set(ctx, instanceSetting.Key.String(), instanceSetting)
|
|
return instanceSetting, nil
|
|
}
|
|
|
|
func (s *Store) ListInstanceSettings(ctx context.Context, find *FindInstanceSetting) ([]*storepb.InstanceSetting, error) {
|
|
list, err := s.driver.ListInstanceSettings(ctx, find)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
instanceSettings := []*storepb.InstanceSetting{}
|
|
for _, instanceSettingRaw := range list {
|
|
instanceSetting, err := convertInstanceSettingFromRaw(instanceSettingRaw)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Failed to convert instance setting")
|
|
}
|
|
if instanceSetting == nil {
|
|
continue
|
|
}
|
|
s.instanceSettingCache.Set(ctx, instanceSetting.Key.String(), instanceSetting)
|
|
instanceSettings = append(instanceSettings, instanceSetting)
|
|
}
|
|
return instanceSettings, nil
|
|
}
|
|
|
|
func (s *Store) GetInstanceSetting(ctx context.Context, find *FindInstanceSetting) (*storepb.InstanceSetting, error) {
|
|
if cache, ok := s.instanceSettingCache.Get(ctx, find.Name); ok {
|
|
instanceSetting, ok := cache.(*storepb.InstanceSetting)
|
|
if ok {
|
|
return instanceSetting, nil
|
|
}
|
|
}
|
|
|
|
list, err := s.ListInstanceSettings(ctx, find)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(list) == 0 {
|
|
return nil, nil
|
|
}
|
|
if len(list) > 1 {
|
|
return nil, errors.Errorf("found multiple instance settings with key %s", find.Name)
|
|
}
|
|
return list[0], nil
|
|
}
|
|
|
|
func (s *Store) GetInstanceBasicSetting(ctx context.Context) (*storepb.InstanceBasicSetting, error) {
|
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
|
Name: storepb.InstanceSettingKey_BASIC.String(),
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get instance basic setting")
|
|
}
|
|
|
|
instanceBasicSetting := &storepb.InstanceBasicSetting{}
|
|
if instanceSetting != nil {
|
|
instanceBasicSetting = instanceSetting.GetBasicSetting()
|
|
}
|
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_BASIC.String(), &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey_BASIC,
|
|
Value: &storepb.InstanceSetting_BasicSetting{BasicSetting: instanceBasicSetting},
|
|
})
|
|
return instanceBasicSetting, nil
|
|
}
|
|
|
|
func (s *Store) GetInstanceGeneralSetting(ctx context.Context) (*storepb.InstanceGeneralSetting, error) {
|
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
|
Name: storepb.InstanceSettingKey_GENERAL.String(),
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get instance general setting")
|
|
}
|
|
|
|
instanceGeneralSetting := &storepb.InstanceGeneralSetting{}
|
|
if instanceSetting != nil {
|
|
instanceGeneralSetting = instanceSetting.GetGeneralSetting()
|
|
}
|
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_GENERAL.String(), &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey_GENERAL,
|
|
Value: &storepb.InstanceSetting_GeneralSetting{GeneralSetting: instanceGeneralSetting},
|
|
})
|
|
return instanceGeneralSetting, nil
|
|
}
|
|
|
|
// DefaultContentLengthLimit is the default limit of content length in bytes. 8KB.
|
|
const DefaultContentLengthLimit = 8 * 1024
|
|
|
|
// DefaultReactions is the default reactions for memo related setting.
|
|
var DefaultReactions = []string{"👍", "👎", "❤️", "🎉", "😄", "😕", "😢", "😡"}
|
|
|
|
// DefaultNsfwTags is the default tags that mark content as NSFW for blurring.
|
|
var DefaultNsfwTags = []string{"nsfw"}
|
|
|
|
func (s *Store) GetInstanceMemoRelatedSetting(ctx context.Context) (*storepb.InstanceMemoRelatedSetting, error) {
|
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
|
Name: storepb.InstanceSettingKey_MEMO_RELATED.String(),
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get instance general setting")
|
|
}
|
|
|
|
instanceMemoRelatedSetting := &storepb.InstanceMemoRelatedSetting{}
|
|
if instanceSetting != nil {
|
|
instanceMemoRelatedSetting = instanceSetting.GetMemoRelatedSetting()
|
|
}
|
|
if instanceMemoRelatedSetting.ContentLengthLimit < DefaultContentLengthLimit {
|
|
instanceMemoRelatedSetting.ContentLengthLimit = DefaultContentLengthLimit
|
|
}
|
|
if len(instanceMemoRelatedSetting.Reactions) == 0 {
|
|
instanceMemoRelatedSetting.Reactions = append(instanceMemoRelatedSetting.Reactions, DefaultReactions...)
|
|
}
|
|
if len(instanceMemoRelatedSetting.NsfwTags) == 0 {
|
|
instanceMemoRelatedSetting.NsfwTags = append(instanceMemoRelatedSetting.NsfwTags, DefaultNsfwTags...)
|
|
}
|
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_MEMO_RELATED.String(), &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey_MEMO_RELATED,
|
|
Value: &storepb.InstanceSetting_MemoRelatedSetting{MemoRelatedSetting: instanceMemoRelatedSetting},
|
|
})
|
|
return instanceMemoRelatedSetting, nil
|
|
}
|
|
|
|
const (
|
|
defaultInstanceStorageType = storepb.InstanceStorageSetting_DATABASE
|
|
defaultInstanceUploadSizeLimitMb = 30
|
|
defaultInstanceFilepathTemplate = "assets/{timestamp}_{filename}"
|
|
)
|
|
|
|
func (s *Store) GetInstanceStorageSetting(ctx context.Context) (*storepb.InstanceStorageSetting, error) {
|
|
instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{
|
|
Name: storepb.InstanceSettingKey_STORAGE.String(),
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get instance storage setting")
|
|
}
|
|
|
|
instanceStorageSetting := &storepb.InstanceStorageSetting{}
|
|
if instanceSetting != nil {
|
|
instanceStorageSetting = instanceSetting.GetStorageSetting()
|
|
}
|
|
if instanceStorageSetting.StorageType == storepb.InstanceStorageSetting_STORAGE_TYPE_UNSPECIFIED {
|
|
instanceStorageSetting.StorageType = defaultInstanceStorageType
|
|
}
|
|
if instanceStorageSetting.UploadSizeLimitMb == 0 {
|
|
instanceStorageSetting.UploadSizeLimitMb = defaultInstanceUploadSizeLimitMb
|
|
}
|
|
if instanceStorageSetting.FilepathTemplate == "" {
|
|
instanceStorageSetting.FilepathTemplate = defaultInstanceFilepathTemplate
|
|
}
|
|
s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_STORAGE.String(), &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey_STORAGE,
|
|
Value: &storepb.InstanceSetting_StorageSetting{StorageSetting: instanceStorageSetting},
|
|
})
|
|
return instanceStorageSetting, nil
|
|
}
|
|
|
|
func convertInstanceSettingFromRaw(instanceSettingRaw *InstanceSetting) (*storepb.InstanceSetting, error) {
|
|
instanceSetting := &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey(storepb.InstanceSettingKey_value[instanceSettingRaw.Name]),
|
|
}
|
|
switch instanceSettingRaw.Name {
|
|
case storepb.InstanceSettingKey_BASIC.String():
|
|
basicSetting := &storepb.InstanceBasicSetting{}
|
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), basicSetting); err != nil {
|
|
return nil, err
|
|
}
|
|
instanceSetting.Value = &storepb.InstanceSetting_BasicSetting{BasicSetting: basicSetting}
|
|
case storepb.InstanceSettingKey_GENERAL.String():
|
|
generalSetting := &storepb.InstanceGeneralSetting{}
|
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), generalSetting); err != nil {
|
|
return nil, err
|
|
}
|
|
instanceSetting.Value = &storepb.InstanceSetting_GeneralSetting{GeneralSetting: generalSetting}
|
|
case storepb.InstanceSettingKey_STORAGE.String():
|
|
storageSetting := &storepb.InstanceStorageSetting{}
|
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), storageSetting); err != nil {
|
|
return nil, err
|
|
}
|
|
instanceSetting.Value = &storepb.InstanceSetting_StorageSetting{StorageSetting: storageSetting}
|
|
case storepb.InstanceSettingKey_MEMO_RELATED.String():
|
|
memoRelatedSetting := &storepb.InstanceMemoRelatedSetting{}
|
|
if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), memoRelatedSetting); err != nil {
|
|
return nil, err
|
|
}
|
|
instanceSetting.Value = &storepb.InstanceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting}
|
|
default:
|
|
// Skip unsupported instance setting key.
|
|
return nil, nil
|
|
}
|
|
return instanceSetting, nil
|
|
}
|