From 6d7ad91f136f7d81d7eb732f05e283472773c01e Mon Sep 17 00:00:00 2001 From: zijiren233 Date: Tue, 24 Oct 2023 22:19:00 +0800 Subject: [PATCH] Feat: add setting cmd --- cmd/root.go | 2 + cmd/setting/fix.go | 47 +++++++++ cmd/setting/setting.go | 9 ++ cmd/setting/show.go | 47 +++++++++ internal/bootstrap/setting.go | 4 +- internal/model/setting.go | 4 + internal/setting/bool.go | 90 ----------------- internal/setting/var.go | 7 -- internal/settings/bool.go | 115 ++++++++++++++++++++++ internal/{setting => settings}/setting.go | 15 +-- internal/settings/var.go | 7 ++ server/handlers/admin.go | 6 +- server/handlers/room.go | 4 +- 13 files changed, 247 insertions(+), 110 deletions(-) create mode 100644 cmd/setting/fix.go create mode 100644 cmd/setting/setting.go create mode 100644 cmd/setting/show.go delete mode 100644 internal/setting/bool.go delete mode 100644 internal/setting/var.go create mode 100644 internal/settings/bool.go rename internal/{setting => settings}/setting.go (92%) create mode 100644 internal/settings/var.go diff --git a/cmd/root.go b/cmd/root.go index 4695f84..8e963b6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/synctv-org/synctv/cmd/admin" "github.com/synctv-org/synctv/cmd/flags" + "github.com/synctv-org/synctv/cmd/setting" "github.com/synctv-org/synctv/cmd/user" "github.com/synctv-org/synctv/internal/version" ) @@ -44,4 +45,5 @@ func init() { func init() { RootCmd.AddCommand(admin.AdminCmd) RootCmd.AddCommand(user.UserCmd) + RootCmd.AddCommand(setting.SettingCmd) } diff --git a/cmd/setting/fix.go b/cmd/setting/fix.go new file mode 100644 index 0000000..2d57eb3 --- /dev/null +++ b/cmd/setting/fix.go @@ -0,0 +1,47 @@ +package setting + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/synctv-org/synctv/internal/bootstrap" + "github.com/synctv-org/synctv/internal/settings" +) + +var FixCmd = &cobra.Command{ + Use: "fix", + Short: "fix setting", + Long: `fix setting`, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return bootstrap.New(bootstrap.WithContext(cmd.Context())).Add( + bootstrap.InitDiscardLog, + bootstrap.InitConfig, + bootstrap.InitDatabase, + bootstrap.InitSetting, + ).Run() + }, + RunE: func(cmd *cobra.Command, args []string) error { + count := 0 + errorCount := 0 + for k, s := range settings.Settings { + _, err := s.Interface() + if err != nil { + fmt.Printf("setting %s, interface error: %v\n", k, err) + err = s.SetString(s.DefaultString()) + if err != nil { + errorCount++ + fmt.Printf("setting %s fix error: %v\n", k, err) + } else { + count++ + fmt.Printf("setting %s fix success\n", k) + } + } + } + fmt.Printf("fix success: %d, fix error: %d\n", count, errorCount) + return nil + }, +} + +func init() { + SettingCmd.AddCommand(FixCmd) +} diff --git a/cmd/setting/setting.go b/cmd/setting/setting.go new file mode 100644 index 0000000..a09e9da --- /dev/null +++ b/cmd/setting/setting.go @@ -0,0 +1,9 @@ +package setting + +import "github.com/spf13/cobra" + +var SettingCmd = &cobra.Command{ + Use: "setting", + Short: "setting", + Long: `you must first shut down the server, otherwise the changes will not take effect.`, +} diff --git a/cmd/setting/show.go b/cmd/setting/show.go new file mode 100644 index 0000000..5747b0c --- /dev/null +++ b/cmd/setting/show.go @@ -0,0 +1,47 @@ +package setting + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/synctv-org/synctv/internal/bootstrap" + "github.com/synctv-org/synctv/internal/model" + "github.com/synctv-org/synctv/internal/settings" + "gopkg.in/yaml.v3" +) + +var ShowCmd = &cobra.Command{ + Use: "show", + Short: "show setting", + Long: `show setting`, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return bootstrap.New(bootstrap.WithContext(cmd.Context())).Add( + bootstrap.InitDiscardLog, + bootstrap.InitConfig, + bootstrap.InitDatabase, + bootstrap.InitSetting, + ).Run() + }, + RunE: func(cmd *cobra.Command, args []string) error { + m := make(map[model.SettingGroup]map[string]any) + for g, s := range settings.GroupSettings { + if _, ok := m[g]; !ok { + m[g] = make(map[string]any) + } + for _, v := range s { + i, err := v.Interface() + if err != nil { + fmt.Printf("parse setting %s error: %v\ntry to fix setting\n", v.Name(), err) + return nil + } + m[g][v.Name()] = i + } + } + return yaml.NewEncoder(os.Stdout).Encode(m) + }, +} + +func init() { + SettingCmd.AddCommand(ShowCmd) +} diff --git a/internal/bootstrap/setting.go b/internal/bootstrap/setting.go index 3968ae5..aa0c24e 100644 --- a/internal/bootstrap/setting.go +++ b/internal/bootstrap/setting.go @@ -3,9 +3,9 @@ package bootstrap import ( "context" - "github.com/synctv-org/synctv/internal/setting" + "github.com/synctv-org/synctv/internal/settings" ) func InitSetting(ctx context.Context) error { - return setting.Init() + return settings.Init() } diff --git a/internal/model/setting.go b/internal/model/setting.go index 72eac47..cdd47d3 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -11,6 +11,10 @@ const ( type SettingGroup string +func (s SettingGroup) String() string { + return string(s) +} + const ( SettingGroupRoom SettingGroup = "room" SettingGroupUser SettingGroup = "user" diff --git a/internal/setting/bool.go b/internal/setting/bool.go deleted file mode 100644 index 064519a..0000000 --- a/internal/setting/bool.go +++ /dev/null @@ -1,90 +0,0 @@ -package setting - -import ( - log "github.com/sirupsen/logrus" - "github.com/synctv-org/synctv/internal/db" - "github.com/synctv-org/synctv/internal/model" -) - -type BoolSetting interface { - Setting - Set(bool) error - Get() (bool, error) -} - -type Bool struct { - name string - value string - group model.SettingGroup -} - -func NewBool(name, value string, group model.SettingGroup) *Bool { - return &Bool{ - name: name, - value: value, - group: group, - } -} - -func (b *Bool) Name() string { - return b.name -} - -func (b *Bool) InitRaw(s string) { - if b.value == s { - return - } - b.value = s -} - -func (b *Bool) Set(value bool) error { - if value { - if b.value == "1" { - return nil - } - b.value = "1" - } else { - if b.value == "0" { - return nil - } - b.value = "0" - } - return db.UpdateSettingItemValue(b.name, b.value) -} - -func (b *Bool) Get() (bool, error) { - return b.value == "1", nil -} - -func (b *Bool) Raw() string { - return b.value -} - -func (b *Bool) Type() model.SettingType { - return model.SettingTypeBool -} - -func (b *Bool) Group() model.SettingGroup { - return b.group -} - -func (b *Bool) Interface() (any, error) { - return b.Get() -} - -func newBoolSetting(k, v string, g model.SettingGroup) BoolSetting { - if Settings == nil { - Settings = make(map[string]Setting) - } - if GroupsSetting == nil { - GroupsSetting = make(map[model.SettingGroup][]Setting) - } - _, loaded := Settings[k] - if loaded { - log.Fatalf("setting %s already exists", k) - } - b := NewBool(k, v, g) - Settings[k] = b - GroupsSetting[g] = append(GroupsSetting[g], b) - return b -} diff --git a/internal/setting/var.go b/internal/setting/var.go deleted file mode 100644 index 498d03c..0000000 --- a/internal/setting/var.go +++ /dev/null @@ -1,7 +0,0 @@ -package setting - -import "github.com/synctv-org/synctv/internal/model" - -var ( - DisableCreateRoom = newBoolSetting("disable_create_room", "0", model.SettingGroupRoom) -) diff --git a/internal/settings/bool.go b/internal/settings/bool.go new file mode 100644 index 0000000..f2cbfd2 --- /dev/null +++ b/internal/settings/bool.go @@ -0,0 +1,115 @@ +package settings + +import ( + log "github.com/sirupsen/logrus" + "github.com/synctv-org/synctv/internal/db" + "github.com/synctv-org/synctv/internal/model" +) + +type BoolSetting interface { + Setting + Set(bool) error + Get() (bool, error) + Default() bool +} + +type Bool struct { + name string + value string + defaultValue bool + group model.SettingGroup +} + +func NewBool(name string, value bool, group model.SettingGroup) *Bool { + b := &Bool{ + name: name, + group: group, + defaultValue: value, + } + if value { + b.value = "1" + } else { + b.value = "0" + } + return b +} + +func (b *Bool) Name() string { + return b.name +} + +func (b *Bool) Init(s string) { + if b.value == s { + return + } + b.value = s +} + +func (b *Bool) Default() bool { + return b.defaultValue +} + +func (b *Bool) DefaultString() string { + if b.defaultValue { + return "1" + } else { + return "0" + } +} + +func (b *Bool) DefaultInterface() any { + return b.Default() +} + +func (b *Bool) SetString(value string) error { + if b.value == value { + return nil + } + b.value = value + return db.UpdateSettingItemValue(b.name, value) +} + +func (b *Bool) Set(value bool) error { + if value { + return b.SetString("1") + } else { + return b.SetString("0") + } +} + +func (b *Bool) Get() (bool, error) { + return b.value == "1", nil +} + +func (b *Bool) String() string { + return b.value +} + +func (b *Bool) Type() model.SettingType { + return model.SettingTypeBool +} + +func (b *Bool) Group() model.SettingGroup { + return b.group +} + +func (b *Bool) Interface() (any, error) { + return b.Get() +} + +func newBoolSetting(k string, v bool, g model.SettingGroup) BoolSetting { + if Settings == nil { + Settings = make(map[string]Setting) + } + if GroupSettings == nil { + GroupSettings = make(map[model.SettingGroup][]Setting) + } + _, loaded := Settings[k] + if loaded { + log.Fatalf("setting %s already exists", k) + } + b := NewBool(k, v, g) + Settings[k] = b + GroupSettings[g] = append(GroupSettings[g], b) + return b +} diff --git a/internal/setting/setting.go b/internal/settings/setting.go similarity index 92% rename from internal/setting/setting.go rename to internal/settings/setting.go index ded6c11..94530d3 100644 --- a/internal/setting/setting.go +++ b/internal/settings/setting.go @@ -1,4 +1,4 @@ -package setting +package settings import ( "fmt" @@ -10,15 +10,18 @@ import ( var ( Settings map[string]Setting - GroupsSetting map[model.SettingGroup][]Setting + GroupSettings map[model.SettingGroup][]Setting ) type Setting interface { Name() string - InitRaw(string) - Raw() string Type() model.SettingType Group() model.SettingGroup + Init(string) + String() string + SetString(string) error + DefaultString() string + DefaultInterface() any Interface() (any, error) } @@ -112,7 +115,7 @@ func initSettings(i ...Setting) error { for _, b := range i { s := &model.Setting{ Name: b.Name(), - Value: b.Raw(), + Value: b.String(), Type: b.Type(), Group: b.Group(), } @@ -120,7 +123,7 @@ func initSettings(i ...Setting) error { if err != nil { return err } - b.InitRaw(s.Value) + b.Init(s.Value) } return nil } diff --git a/internal/settings/var.go b/internal/settings/var.go new file mode 100644 index 0000000..7a63a6b --- /dev/null +++ b/internal/settings/var.go @@ -0,0 +1,7 @@ +package settings + +import "github.com/synctv-org/synctv/internal/model" + +var ( + DisableCreateRoom = newBoolSetting("disable_create_room", false, model.SettingGroupRoom) +) diff --git a/server/handlers/admin.go b/server/handlers/admin.go index ecd2a72..756c9b6 100644 --- a/server/handlers/admin.go +++ b/server/handlers/admin.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" dbModel "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/op" - "github.com/synctv-org/synctv/internal/setting" + "github.com/synctv-org/synctv/internal/settings" "github.com/synctv-org/synctv/server/model" ) @@ -20,7 +20,7 @@ func EditAdminSettings(ctx *gin.Context) { } for k, v := range req { - err := setting.SetValue(k, v) + err := settings.SetValue(k, v) if err != nil { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) return @@ -38,7 +38,7 @@ func AdminSettings(ctx *gin.Context) { return } - s, ok := setting.GroupsSetting[dbModel.SettingGroup(group)] + s, ok := settings.GroupSettings[dbModel.SettingGroup(group)] if !ok { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("group not found")) return diff --git a/server/handlers/room.go b/server/handlers/room.go index 085a523..8420977 100644 --- a/server/handlers/room.go +++ b/server/handlers/room.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/op" - "github.com/synctv-org/synctv/internal/setting" + "github.com/synctv-org/synctv/internal/settings" "github.com/synctv-org/synctv/server/middlewares" "github.com/synctv-org/synctv/server/model" "github.com/synctv-org/synctv/utils" @@ -32,7 +32,7 @@ func (e FormatErrNotSupportPosition) Error() string { func CreateRoom(ctx *gin.Context) { user := ctx.MustGet("user").(*op.User) - v, err := setting.DisableCreateRoom.Get() + v, err := settings.DisableCreateRoom.Get() if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return