forked from gitea/gitea
		
	Fix dashboard ignored system setting cache (#21621)
This is a performance regression from #18058 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
		
							parent
							
								
									ce5aafbc69
								
							
						
					
					
						commit
						385462d36c
					
				| @ -150,10 +150,11 @@ func generateEmailAvatarLink(email string, size int, final bool) string { | ||||
| 		return DefaultAvatarLink() | ||||
| 	} | ||||
| 
 | ||||
| 	enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar) | ||||
| 	enableFederatedAvatarSetting, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar) | ||||
| 	enableFederatedAvatar := enableFederatedAvatarSetting.GetValueBool() | ||||
| 
 | ||||
| 	var err error | ||||
| 	if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil { | ||||
| 	if enableFederatedAvatar && system_model.LibravatarService != nil { | ||||
| 		emailHash := saveEmailHash(email) | ||||
| 		if final { | ||||
| 			// for final link, we can spend more time on slow external query | ||||
| @ -171,8 +172,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string { | ||||
| 		return urlStr | ||||
| 	} | ||||
| 
 | ||||
| 	disableGravatar, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) | ||||
| 	if disableGravatar != nil && !disableGravatar.GetValueBool() { | ||||
| 	disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) | ||||
| 
 | ||||
| 	disableGravatar := disableGravatarSetting.GetValueBool() | ||||
| 	if !disableGravatar { | ||||
| 		// copy GravatarSourceURL, because we will modify its Path. | ||||
| 		avatarURLCopy := *system_model.GravatarSourceURL | ||||
| 		avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email)) | ||||
|  | ||||
| @ -12,6 +12,7 @@ import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/modules/cache" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 
 | ||||
| @ -35,6 +36,10 @@ func (s *Setting) TableName() string { | ||||
| } | ||||
| 
 | ||||
| func (s *Setting) GetValueBool() bool { | ||||
| 	if s == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	b, _ := strconv.ParseBool(s.SettingValue) | ||||
| 	return b | ||||
| } | ||||
| @ -75,8 +80,8 @@ func IsErrDataExpired(err error) bool { | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| // GetSetting returns specific setting | ||||
| func GetSetting(key string) (*Setting, error) { | ||||
| // GetSettingNoCache returns specific setting without using the cache | ||||
| func GetSettingNoCache(key string) (*Setting, error) { | ||||
| 	v, err := GetSettings([]string{key}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @ -87,6 +92,24 @@ func GetSetting(key string) (*Setting, error) { | ||||
| 	return v[key], nil | ||||
| } | ||||
| 
 | ||||
| // GetSetting returns the setting value via the key | ||||
| func GetSetting(key string) (*Setting, error) { | ||||
| 	return cache.Get(genSettingCacheKey(key), func() (*Setting, error) { | ||||
| 		res, err := GetSettingNoCache(key) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return res, nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // GetSettingBool return bool value of setting, | ||||
| // none existing keys and errors are ignored and result in false | ||||
| func GetSettingBool(key string) bool { | ||||
| 	s, _ := GetSetting(key) | ||||
| 	return s.GetValueBool() | ||||
| } | ||||
| 
 | ||||
| // GetSettings returns specific settings | ||||
| func GetSettings(keys []string) (map[string]*Setting, error) { | ||||
| 	for i := 0; i < len(keys); i++ { | ||||
| @ -139,12 +162,13 @@ func GetAllSettings() (AllSettings, error) { | ||||
| 
 | ||||
| // DeleteSetting deletes a specific setting for a user | ||||
| func DeleteSetting(setting *Setting) error { | ||||
| 	cache.Remove(genSettingCacheKey(setting.SettingKey)) | ||||
| 	_, err := db.GetEngine(db.DefaultContext).Delete(setting) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func SetSettingNoVersion(key, value string) error { | ||||
| 	s, err := GetSetting(key) | ||||
| 	s, err := GetSettingNoCache(key) | ||||
| 	if IsErrSettingIsNotExist(err) { | ||||
| 		return SetSetting(&Setting{ | ||||
| 			SettingKey:   key, | ||||
| @ -160,9 +184,13 @@ func SetSettingNoVersion(key, value string) error { | ||||
| 
 | ||||
| // SetSetting updates a users' setting for a specific key | ||||
| func SetSetting(setting *Setting) error { | ||||
| 	if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil { | ||||
| 	_, err := cache.Set(genSettingCacheKey(setting.SettingKey), func() (*Setting, error) { | ||||
| 		return setting, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version) | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	setting.Version++ | ||||
| 	return nil | ||||
| } | ||||
| @ -213,7 +241,7 @@ var ( | ||||
| 
 | ||||
| func Init() error { | ||||
| 	var disableGravatar bool | ||||
| 	disableGravatarSetting, err := GetSetting(KeyPictureDisableGravatar) | ||||
| 	disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar) | ||||
| 	if IsErrSettingIsNotExist(err) { | ||||
| 		disableGravatar = setting.GetDefaultDisableGravatar() | ||||
| 		disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)} | ||||
| @ -224,7 +252,7 @@ func Init() error { | ||||
| 	} | ||||
| 
 | ||||
| 	var enableFederatedAvatar bool | ||||
| 	enableFederatedAvatarSetting, err := GetSetting(KeyPictureEnableFederatedAvatar) | ||||
| 	enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar) | ||||
| 	if IsErrSettingIsNotExist(err) { | ||||
| 		enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar) | ||||
| 		enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)} | ||||
|  | ||||
| @ -9,3 +9,8 @@ const ( | ||||
| 	KeyPictureDisableGravatar       = "picture.disable_gravatar" | ||||
| 	KeyPictureEnableFederatedAvatar = "picture.enable_federated_avatar" | ||||
| ) | ||||
| 
 | ||||
| // genSettingCacheKey returns the cache key for some configuration | ||||
| func genSettingCacheKey(key string) string { | ||||
| 	return "system.setting." + key | ||||
| } | ||||
|  | ||||
| @ -68,11 +68,9 @@ func (u *User) AvatarLinkWithSize(size int) string { | ||||
| 	useLocalAvatar := false | ||||
| 	autoGenerateAvatar := false | ||||
| 
 | ||||
| 	var disableGravatar bool | ||||
| 	disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) | ||||
| 	if disableGravatarSetting != nil { | ||||
| 		disableGravatar = disableGravatarSetting.GetValueBool() | ||||
| 	} | ||||
| 
 | ||||
| 	disableGravatar := disableGravatarSetting.GetValueBool() | ||||
| 
 | ||||
| 	switch { | ||||
| 	case u.UseCustomAvatar: | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/modules/cache" | ||||
| 
 | ||||
| 	"xorm.io/builder" | ||||
| ) | ||||
| @ -47,9 +48,25 @@ func IsErrUserSettingIsNotExist(err error) bool { | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| // GetSetting returns specific setting | ||||
| // genSettingCacheKey returns the cache key for some configuration | ||||
| func genSettingCacheKey(userID int64, key string) string { | ||||
| 	return fmt.Sprintf("user_%d.setting.%s", userID, key) | ||||
| } | ||||
| 
 | ||||
| // GetSetting returns the setting value via the key | ||||
| func GetSetting(uid int64, key string) (*Setting, error) { | ||||
| 	v, err := GetUserSettings(uid, []string{key}) | ||||
| 	return cache.Get(genSettingCacheKey(uid, key), func() (*Setting, error) { | ||||
| 		res, err := GetSettingNoCache(uid, key) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return res, nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // GetSettingNoCache returns specific setting without using the cache | ||||
| func GetSettingNoCache(uid int64, key string) (*Setting, error) { | ||||
| 	v, err := GetSettings(uid, []string{key}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @ -59,8 +76,8 @@ func GetSetting(uid int64, key string) (*Setting, error) { | ||||
| 	return v[key], nil | ||||
| } | ||||
| 
 | ||||
| // GetUserSettings returns specific settings from user | ||||
| func GetUserSettings(uid int64, keys []string) (map[string]*Setting, error) { | ||||
| // GetSettings returns specific settings from user | ||||
| func GetSettings(uid int64, keys []string) (map[string]*Setting, error) { | ||||
| 	settings := make([]*Setting, 0, len(keys)) | ||||
| 	if err := db.GetEngine(db.DefaultContext). | ||||
| 		Where("user_id=?", uid). | ||||
| @ -105,6 +122,7 @@ func GetUserSetting(userID int64, key string, def ...string) (string, error) { | ||||
| 	if err := validateUserSettingKey(key); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	setting := &Setting{UserID: userID, SettingKey: key} | ||||
| 	has, err := db.GetEngine(db.DefaultContext).Get(setting) | ||||
| 	if err != nil { | ||||
| @ -124,7 +142,10 @@ func DeleteUserSetting(userID int64, key string) error { | ||||
| 	if err := validateUserSettingKey(key); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	cache.Remove(genSettingCacheKey(userID, key)) | ||||
| 	_, err := db.GetEngine(db.DefaultContext).Delete(&Setting{UserID: userID, SettingKey: key}) | ||||
| 
 | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| @ -133,7 +154,12 @@ func SetUserSetting(userID int64, key, value string) error { | ||||
| 	if err := validateUserSettingKey(key); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return upsertUserSettingValue(userID, key, value) | ||||
| 
 | ||||
| 	_, err := cache.Set(genSettingCacheKey(userID, key), func() (string, error) { | ||||
| 		return value, upsertUserSettingValue(userID, key, value) | ||||
| 	}) | ||||
| 
 | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func upsertUserSettingValue(userID int64, key, value string) error { | ||||
|  | ||||
| @ -27,7 +27,7 @@ func TestSettings(t *testing.T) { | ||||
| 	assert.NoError(t, err) | ||||
| 
 | ||||
| 	// get specific setting | ||||
| 	settings, err := user_model.GetUserSettings(99, []string{keyName}) | ||||
| 	settings, err := user_model.GetSettings(99, []string{keyName}) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Len(t, settings, 1) | ||||
| 	assert.EqualValues(t, newSetting.SettingValue, settings[keyName].SettingValue) | ||||
|  | ||||
| @ -11,7 +11,7 @@ import ( | ||||
| // GetKeyPair function returns a user's private and public keys | ||||
| func GetKeyPair(user *user_model.User) (pub, priv string, err error) { | ||||
| 	var settings map[string]*user_model.Setting | ||||
| 	settings, err = user_model.GetUserSettings(user.ID, []string{user_model.UserActivityPubPrivPem, user_model.UserActivityPubPubPem}) | ||||
| 	settings, err = user_model.GetSettings(user.ID, []string{user_model.UserActivityPubPrivPem, user_model.UserActivityPubPubPem}) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} else if len(settings) == 0 { | ||||
|  | ||||
							
								
								
									
										131
									
								
								modules/cache/cache.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								modules/cache/cache.go
									
									
									
									
										vendored
									
									
								
							| @ -46,32 +46,64 @@ func GetCache() mc.Cache { | ||||
| 	return conn | ||||
| } | ||||
| 
 | ||||
| // Get returns the key value from cache with callback when no key exists in cache | ||||
| func Get[V interface{}](key string, getFunc func() (V, error)) (V, error) { | ||||
| 	if conn == nil || setting.CacheService.TTL == 0 { | ||||
| 		return getFunc() | ||||
| 	} | ||||
| 
 | ||||
| 	cached := conn.Get(key) | ||||
| 	if value, ok := cached.(V); ok { | ||||
| 		return value, nil | ||||
| 	} | ||||
| 
 | ||||
| 	value, err := getFunc() | ||||
| 	if err != nil { | ||||
| 		return value, err | ||||
| 	} | ||||
| 
 | ||||
| 	return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| } | ||||
| 
 | ||||
| // Set updates and returns the key value in the cache with callback. The old value is only removed if the updateFunc() is successful | ||||
| func Set[V interface{}](key string, valueFunc func() (V, error)) (V, error) { | ||||
| 	if conn == nil || setting.CacheService.TTL == 0 { | ||||
| 		return valueFunc() | ||||
| 	} | ||||
| 
 | ||||
| 	value, err := valueFunc() | ||||
| 	if err != nil { | ||||
| 		return value, err | ||||
| 	} | ||||
| 
 | ||||
| 	return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| } | ||||
| 
 | ||||
| // GetString returns the key value from cache with callback when no key exists in cache | ||||
| func GetString(key string, getFunc func() (string, error)) (string, error) { | ||||
| 	if conn == nil || setting.CacheService.TTL == 0 { | ||||
| 		return getFunc() | ||||
| 	} | ||||
| 	if !conn.IsExist(key) { | ||||
| 		var ( | ||||
| 			value string | ||||
| 			err   error | ||||
| 		) | ||||
| 		if value, err = getFunc(); err != nil { | ||||
| 
 | ||||
| 	cached := conn.Get(key) | ||||
| 
 | ||||
| 	if cached == nil { | ||||
| 		value, err := getFunc() | ||||
| 		if err != nil { | ||||
| 			return value, err | ||||
| 		} | ||||
| 		err = conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 	} | ||||
| 	value := conn.Get(key) | ||||
| 	if v, ok := value.(string); ok { | ||||
| 		return v, nil | ||||
| 
 | ||||
| 	if value, ok := cached.(string); ok { | ||||
| 		return value, nil | ||||
| 	} | ||||
| 	if v, ok := value.(fmt.Stringer); ok { | ||||
| 		return v.String(), nil | ||||
| 
 | ||||
| 	if stringer, ok := cached.(fmt.Stringer); ok { | ||||
| 		return stringer.String(), nil | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s", conn.Get(key)), nil | ||||
| 
 | ||||
| 	return fmt.Sprintf("%s", cached), nil | ||||
| } | ||||
| 
 | ||||
| // GetInt returns key value from cache with callback when no key exists in cache | ||||
| @ -79,30 +111,33 @@ func GetInt(key string, getFunc func() (int, error)) (int, error) { | ||||
| 	if conn == nil || setting.CacheService.TTL == 0 { | ||||
| 		return getFunc() | ||||
| 	} | ||||
| 	if !conn.IsExist(key) { | ||||
| 		var ( | ||||
| 			value int | ||||
| 			err   error | ||||
| 		) | ||||
| 		if value, err = getFunc(); err != nil { | ||||
| 
 | ||||
| 	cached := conn.Get(key) | ||||
| 
 | ||||
| 	if cached == nil { | ||||
| 		value, err := getFunc() | ||||
| 		if err != nil { | ||||
| 			return value, err | ||||
| 		} | ||||
| 		err = conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 
 | ||||
| 		return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 	} | ||||
| 	switch value := conn.Get(key).(type) { | ||||
| 
 | ||||
| 	switch v := cached.(type) { | ||||
| 	case int: | ||||
| 		return value, nil | ||||
| 		return v, nil | ||||
| 	case string: | ||||
| 		v, err := strconv.Atoi(value) | ||||
| 		value, err := strconv.Atoi(v) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return v, nil | ||||
| 		return value, nil | ||||
| 	default: | ||||
| 		return 0, fmt.Errorf("Unsupported cached value type: %v", value) | ||||
| 		value, err := getFunc() | ||||
| 		if err != nil { | ||||
| 			return value, err | ||||
| 		} | ||||
| 		return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -111,30 +146,34 @@ func GetInt64(key string, getFunc func() (int64, error)) (int64, error) { | ||||
| 	if conn == nil || setting.CacheService.TTL == 0 { | ||||
| 		return getFunc() | ||||
| 	} | ||||
| 	if !conn.IsExist(key) { | ||||
| 		var ( | ||||
| 			value int64 | ||||
| 			err   error | ||||
| 		) | ||||
| 		if value, err = getFunc(); err != nil { | ||||
| 
 | ||||
| 	cached := conn.Get(key) | ||||
| 
 | ||||
| 	if cached == nil { | ||||
| 		value, err := getFunc() | ||||
| 		if err != nil { | ||||
| 			return value, err | ||||
| 		} | ||||
| 		err = conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 
 | ||||
| 		return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 	} | ||||
| 	switch value := conn.Get(key).(type) { | ||||
| 
 | ||||
| 	switch v := conn.Get(key).(type) { | ||||
| 	case int64: | ||||
| 		return value, nil | ||||
| 		return v, nil | ||||
| 	case string: | ||||
| 		v, err := strconv.ParseInt(value, 10, 64) | ||||
| 		value, err := strconv.ParseInt(v, 10, 64) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return v, nil | ||||
| 		return value, nil | ||||
| 	default: | ||||
| 		return 0, fmt.Errorf("Unsupported cached value type: %v", value) | ||||
| 		value, err := getFunc() | ||||
| 		if err != nil { | ||||
| 			return value, err | ||||
| 		} | ||||
| 
 | ||||
| 		return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,46 +0,0 @@ | ||||
| // Copyright 2021 The Gitea Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package system | ||||
| 
 | ||||
| import ( | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/system" | ||||
| 	"code.gitea.io/gitea/modules/cache" | ||||
| ) | ||||
| 
 | ||||
| func genKey(key string) string { | ||||
| 	return "system.setting." + key | ||||
| } | ||||
| 
 | ||||
| // GetSetting returns the setting value via the key | ||||
| func GetSetting(key string) (string, error) { | ||||
| 	return cache.GetString(genKey(key), func() (string, error) { | ||||
| 		res, err := system.GetSetting(key) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		return res.SettingValue, nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // GetSettingBool return bool value of setting, | ||||
| // none existing keys and errors are ignored and result in false | ||||
| func GetSettingBool(key string) bool { | ||||
| 	s, _ := GetSetting(key) | ||||
| 	b, _ := strconv.ParseBool(s) | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| // SetSetting sets the setting value | ||||
| func SetSetting(key, value string, version int) error { | ||||
| 	cache.Remove(genKey(key)) | ||||
| 
 | ||||
| 	return system.SetSetting(&system.Setting{ | ||||
| 		SettingKey:   key, | ||||
| 		SettingValue: value, | ||||
| 		Version:      version, | ||||
| 	}) | ||||
| } | ||||
| @ -1,34 +0,0 @@ | ||||
| // Copyright 2021 The Gitea Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package system | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/cache" | ||||
| ) | ||||
| 
 | ||||
| func genUserKey(userID int64, key string) string { | ||||
| 	return fmt.Sprintf("user_%d.setting.%s", userID, key) | ||||
| } | ||||
| 
 | ||||
| // GetUserSetting returns the user setting value via the key | ||||
| func GetUserSetting(userID int64, key string) (string, error) { | ||||
| 	return cache.GetString(genUserKey(userID, key), func() (string, error) { | ||||
| 		res, err := user.GetSetting(userID, key) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		return res.SettingValue, nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // SetUserSetting sets the user setting value | ||||
| func SetUserSetting(userID int64, key, value string) error { | ||||
| 	cache.Remove(genUserKey(userID, key)) | ||||
| 
 | ||||
| 	return user.SetUserSetting(userID, key, value) | ||||
| } | ||||
| @ -43,7 +43,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/svg" | ||||
| 	system_module "code.gitea.io/gitea/modules/system" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/services/gitdiff" | ||||
| @ -88,7 +87,7 @@ func NewFuncMap() []template.FuncMap { | ||||
| 			return setting.AssetVersion | ||||
| 		}, | ||||
| 		"DisableGravatar": func() bool { | ||||
| 			return system_module.GetSettingBool(system_model.KeyPictureDisableGravatar) | ||||
| 			return system_model.GetSettingBool(system_model.KeyPictureDisableGravatar) | ||||
| 		}, | ||||
| 		"DefaultShowFullName": func() bool { | ||||
| 			return setting.UI.DefaultShowFullName | ||||
|  | ||||
| @ -18,7 +18,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	system_module "code.gitea.io/gitea/modules/system" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/services/mailer" | ||||
| 
 | ||||
| @ -203,7 +202,11 @@ func ChangeConfig(ctx *context.Context) { | ||||
| 	value := ctx.FormString("value") | ||||
| 	version := ctx.FormInt("version") | ||||
| 
 | ||||
| 	if err := system_module.SetSetting(key, value, version); err != nil { | ||||
| 	if err := system_model.SetSetting(&system_model.Setting{ | ||||
| 		SettingKey:   key, | ||||
| 		SettingValue: value, | ||||
| 		Version:      version, | ||||
| 	}); err != nil { | ||||
| 		log.Error("set setting failed: %v", err) | ||||
| 		ctx.JSON(http.StatusOK, map[string]string{ | ||||
| 			"err": ctx.Tr("admin.config.set_setting_failed", key), | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 GitHub
							GitHub