Unverified Commit 9ef0f8a9 authored by boojack's avatar boojack Committed by GitHub

feat: add user setting field (#2054)

parent 470fe1df
......@@ -23,7 +23,6 @@ func NewUserService(store *store.Store) *UserService {
}
func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserRequest) (*apiv2pb.GetUserResponse, error) {
println("GetUser", request.Name)
user, err := s.Store.GetUser(ctx, &store.FindUser{
Username: &request.Name,
})
......@@ -38,6 +37,18 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque
// Data desensitization.
userMessage.OpenId = ""
userUID := int(userMessage.Id)
userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{
UserID: &userUID,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err)
}
// TODO: check the access permission for user settings.
for _, userSetting := range userSettings {
userMessage.Settings = append(userMessage.Settings, convertUserSettingFromStore(userSetting))
}
response := &apiv2pb.GetUserResponse{
User: userMessage,
}
......@@ -56,6 +67,7 @@ func convertUserFromStore(user *store.User) *apiv2pb.User {
Nickname: user.Nickname,
OpenId: user.OpenID,
AvatarUrl: user.AvatarURL,
Settings: []*apiv2pb.UserSetting{},
}
}
......@@ -71,3 +83,46 @@ func convertUserRoleFromStore(role store.Role) apiv2pb.Role {
return apiv2pb.Role_ROLE_UNSPECIFIED
}
}
func convertUserSettingFromStore(userSetting *store.UserSetting) *apiv2pb.UserSetting {
userSettingKey := apiv2pb.UserSetting_KEY_UNSPECIFIED
userSettingValue := &apiv2pb.UserSettingValue{}
switch userSetting.Key {
case "locale":
userSettingKey = apiv2pb.UserSetting_LOCALE
userSettingValue.Value = &apiv2pb.UserSettingValue_StringValue{
StringValue: userSetting.Value,
}
case "appearance":
userSettingKey = apiv2pb.UserSetting_APPEARANCE
userSettingValue.Value = &apiv2pb.UserSettingValue_StringValue{
StringValue: userSetting.Value,
}
case "memo-visibility":
userSettingKey = apiv2pb.UserSetting_MEMO_VISIBILITY
userSettingValue.Value = &apiv2pb.UserSettingValue_VisibilityValue{
VisibilityValue: convertVisibilityFromString(userSetting.Value),
}
case "telegram-user-id":
userSettingKey = apiv2pb.UserSetting_TELEGRAM_USER_ID
userSettingValue.Value = &apiv2pb.UserSettingValue_StringValue{
StringValue: userSetting.Value,
}
}
return &apiv2pb.UserSetting{
UserId: int32(userSetting.UserID),
Key: userSettingKey,
Value: userSettingValue,
}
}
func convertVisibilityFromString(visibility string) apiv2pb.Visibility {
switch visibility {
case "public":
return apiv2pb.Visibility_PUBLIC
case "private":
return apiv2pb.Visibility_PRIVATE
default:
return apiv2pb.Visibility_VISIBILITY_UNSPECIFIED
}
}
......@@ -35,6 +35,8 @@ message User {
string open_id = 9;
string avatar_url = 10;
repeated UserSetting settings = 11;
}
enum Role {
......@@ -54,3 +56,43 @@ message GetUserRequest {
message GetUserResponse {
User user = 1;
}
message UserSetting {
// The user id of the setting.
int32 user_id = 1;
enum Key {
KEY_UNSPECIFIED = 0;
// The preferred locale.
LOCALE = 1;
// The preferred appearance.
APPEARANCE = 2;
// The default visibility of the memo when creating a new memo.
MEMO_VISIBILITY = 3;
// User's telegram id
TELEGRAM_USER_ID = 4;
}
// The key of the setting.
Key key = 2;
// The value of the setting.
UserSettingValue value = 3;
}
message UserSettingValue {
oneof value {
// Default value as a string.
string string_value = 1;
Visibility visibility_value = 2;
}
}
enum Visibility {
VISIBILITY_UNSPECIFIED = 0;
PRIVATE = 1;
PROTECTED = 2;
PUBLIC = 3;
}
......@@ -17,8 +17,12 @@
- [GetUserRequest](#memos-api-v2-GetUserRequest)
- [GetUserResponse](#memos-api-v2-GetUserResponse)
- [User](#memos-api-v2-User)
- [UserSetting](#memos-api-v2-UserSetting)
- [UserSettingValue](#memos-api-v2-UserSettingValue)
- [Role](#memos-api-v2-Role)
- [UserSetting.Key](#memos-api-v2-UserSetting-Key)
- [Visibility](#memos-api-v2-Visibility)
- [UserService](#memos-api-v2-UserService)
......@@ -182,6 +186,40 @@
| nickname | [string](#string) | | |
| open_id | [string](#string) | | |
| avatar_url | [string](#string) | | |
| settings | [UserSetting](#memos-api-v2-UserSetting) | repeated | |
<a name="memos-api-v2-UserSetting"></a>
### UserSetting
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| user_id | [int32](#int32) | | The user id of the setting. |
| key | [UserSetting.Key](#memos-api-v2-UserSetting-Key) | | The key of the setting. |
| value | [UserSettingValue](#memos-api-v2-UserSettingValue) | | The value of the setting. |
<a name="memos-api-v2-UserSettingValue"></a>
### UserSettingValue
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| string_value | [string](#string) | | Default value as a string. |
| visibility_value | [Visibility](#memos-api-v2-Visibility) | | |
......@@ -203,6 +241,35 @@
| USER | 3 | |
<a name="memos-api-v2-UserSetting-Key"></a>
### UserSetting.Key
| Name | Number | Description |
| ---- | ------ | ----------- |
| KEY_UNSPECIFIED | 0 | |
| LOCALE | 1 | The preferred locale. |
| APPEARANCE | 2 | The preferred appearance. |
| MEMO_VISIBILITY | 3 | The default visibility of the memo when creating a new memo. |
| TELEGRAM_USER_ID | 4 | User&#39;s telegram id |
<a name="memos-api-v2-Visibility"></a>
### Visibility
| Name | Number | Description |
| ---- | ------ | ----------- |
| VISIBILITY_UNSPECIFIED | 0 | |
| PRIVATE | 1 | |
| PROTECTED | 2 | |
| PUBLIC | 3 | |
......
This diff is collapsed.
......@@ -12,8 +12,18 @@ import (
"go.uber.org/zap"
)
func autoBackup(ctx context.Context, s *store.Store) {
intervalStr := s.GetSystemSettingValueWithDefault(&ctx, apiv1.SystemSettingAutoBackupIntervalName.String(), "")
type BackupRunner struct {
Store *store.Store
}
func NewBackupRunner(store *store.Store) *BackupRunner {
return &BackupRunner{
Store: store,
}
}
func (r *BackupRunner) Run(ctx context.Context) {
intervalStr := r.Store.GetSystemSettingValueWithDefault(&ctx, apiv1.SystemSettingAutoBackupIntervalName.String(), "")
if intervalStr == "" {
log.Info("no SystemSettingAutoBackupIntervalName setting, disable auto backup")
return
......@@ -38,9 +48,9 @@ func autoBackup(ctx context.Context, s *store.Store) {
case t = <-ticker.C:
}
filename := s.Profile.DSN + t.Format("-20060102-150405.bak")
filename := r.Store.Profile.DSN + t.Format("-20060102-150405.bak")
log.Info(fmt.Sprintf("create backup to %s", filename))
err := s.BackupTo(ctx, filename)
err := r.Store.BackupTo(ctx, filename)
if err != nil {
log.Error("fail to create backup", zap.Error(err))
}
......
......@@ -32,7 +32,9 @@ type Server struct {
Profile *profile.Profile
Store *store.Store
telegramBot *telegram.Bot
// Asynchronous runners.
backupRunner *BackupRunner
telegramBot *telegram.Bot
}
func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store) (*Server, error) {
......@@ -45,10 +47,11 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
e: e,
Store: store,
Profile: profile,
}
telegramBotHandler := newTelegramHandler(store)
s.telegramBot = telegram.NewBotWithHandler(telegramBotHandler)
// Asynchronous runners.
backupRunner: NewBackupRunner(store),
telegramBot: telegram.NewBotWithHandler(newTelegramHandler(store)),
}
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: `{"time":"${time_rfc3339}",` +
......@@ -116,7 +119,7 @@ func (s *Server) Start(ctx context.Context) error {
}
go s.telegramBot.Start(ctx)
go autoBackup(ctx, s.Store)
go s.backupRunner.Run(ctx)
// Start gRPC server.
listen, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Profile.Port+1))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment