diff --git a/internal/db/setting.go b/internal/db/setting.go index a39c7095..750e0a96 100644 --- a/internal/db/setting.go +++ b/internal/db/setting.go @@ -4,8 +4,40 @@ import ( "fmt" "github.com/alist-org/alist/v3/internal/model" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) +var settingsMap map[string]string +var publicSettingsMap map[string]string + +func GetPublicSettingsMap() map[string]string { + if settingsMap == nil { + publicSettingsMap = make(map[string]string) + settings, err := GetPublicSettings() + if err != nil { + log.Errorf("failed to get settings: %+v", err) + } + for _, setting := range settings { + publicSettingsMap[setting.Key] = setting.Value + } + } + return publicSettingsMap +} + +func GetSettingsMap() map[string]string { + if settingsMap == nil { + settingsMap = make(map[string]string) + settings, err := GetSettings() + if err != nil { + log.Errorf("failed to get settings: %+v", err) + } + for _, setting := range settings { + settingsMap[setting.Key] = setting.Value + } + } + return settingsMap +} + func GetSettings() ([]model.SettingItem, error) { var items []model.SettingItem if err := db.Find(&items).Error; err != nil { @@ -39,10 +71,12 @@ func GetSettingsByGroup(group int) ([]model.SettingItem, error) { } func SaveSettings(items []model.SettingItem) error { + settingsMap = nil return errors.WithStack(db.Save(items).Error) } func SaveSetting(item model.SettingItem) error { + settingsMap = nil return errors.WithStack(db.Save(item).Error) } @@ -50,5 +84,13 @@ func DeleteSettingByKey(key string) error { setting := model.SettingItem{ Key: key, } + old, err := GetSettingByKey(key) + if err != nil { + return errors.WithMessage(err, "failed to get setting") + } + if !old.IsDeprecated() { + return errors.Errorf("setting [%s] is not deprecated", key) + } + settingsMap = nil return errors.WithStack(db.Delete(&setting).Error) } diff --git a/internal/model/setting.go b/internal/model/setting.go index b619e110..8e431176 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -21,5 +21,9 @@ type SettingItem struct { Type string `json:"type"` // string, number, bool, select Values string `json:"values"` // values for select Group int `json:"group"` // use to group setting in frontend - Flag int `json:"flag"` // 0 = public, 1 = private, 2 = deprecated, etc. + Flag int `json:"flag"` // 0 = public, 1 = private, 2 = readonly, 3 = deprecated, etc. +} + +func (s SettingItem) IsDeprecated() bool { + return s.Flag == DEPRECATED } diff --git a/server/controllers/setting.go b/server/controllers/setting.go new file mode 100644 index 00000000..6e59bddd --- /dev/null +++ b/server/controllers/setting.go @@ -0,0 +1,54 @@ +package controllers + +import ( + "github.com/alist-org/alist/v3/internal/db" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/server/common" + "github.com/gin-gonic/gin" + "strconv" +) + +func SaveSettings(c *gin.Context) { + var req []model.SettingItem + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := db.SaveSettings(req); err != nil { + common.ErrorResp(c, err, 500) + } else { + common.SuccessResp(c) + } +} + +func ListSettings(c *gin.Context) { + groupStr := c.Query("group") + var settings []model.SettingItem + var err error + if groupStr == "" { + settings, err = db.GetSettings() + } else { + group, err := strconv.Atoi(groupStr) + if err == nil { + settings, err = db.GetSettingsByGroup(group) + } + } + if err != nil { + common.ErrorResp(c, err, 400) + return + } + common.SuccessResp(c, settings) +} + +func DeleteSetting(c *gin.Context) { + key := c.Query("key") + if err := db.DeleteSettingByKey(key); err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c) +} + +func PublicSettings(c *gin.Context) { + common.SuccessResp(c, db.GetPublicSettingsMap()) +} diff --git a/server/router.go b/server/router.go index e4f0b229..6f81427f 100644 --- a/server/router.go +++ b/server/router.go @@ -41,6 +41,14 @@ func Init(r *gin.Engine) { driver.GET("/list", controllers.ListDriverItems) driver.GET("/names", controllers.ListDriverNames) driver.GET("/items", controllers.GetDriverItems) + + setting := admin.Group("/setting") + setting.GET("/list", controllers.ListSettings) + setting.POST("/save", controllers.SaveSettings) + setting.POST("/delete", controllers.DeleteSetting) + + public := api.Group("/public") + public.GET("/settings", controllers.PublicSettings) } func Cors(r *gin.Engine) {