diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-10-05 09:08:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-05 09:08:19 +0800 |
commit | 9f8d59858af581a2c278a4896a301339991ece5b (patch) | |
tree | 577a395a442ccd9579dfd2726750301e6a934ef3 /models/avatars/avatar.go | |
parent | 976d1760ac483a6f5fa8fa5ad24d94cae58497eb (diff) | |
download | gitea-9f8d59858af581a2c278a4896a301339991ece5b.tar.gz gitea-9f8d59858af581a2c278a4896a301339991ece5b.zip |
Refactor system setting (#27000)
This PR reduces the complexity of the system setting system.
It only needs one line to introduce a new option, and the option can be
used anywhere out-of-box.
It is still high-performant (and more performant) because the config
values are cached in the config system.
Diffstat (limited to 'models/avatars/avatar.go')
-rw-r--r-- | models/avatars/avatar.go | 81 |
1 files changed, 58 insertions, 23 deletions
diff --git a/models/avatars/avatar.go b/models/avatars/avatar.go index e40aa3f542..b0bfa44089 100644 --- a/models/avatars/avatar.go +++ b/models/avatars/avatar.go @@ -5,18 +5,20 @@ package avatars import ( "context" + "fmt" "net/url" "path" "strconv" "strings" - "sync" + "sync/atomic" "code.gitea.io/gitea/models/db" - system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + + "strk.kbt.io/projects/go/libravatar" ) const ( @@ -36,24 +38,54 @@ func init() { db.RegisterModel(new(EmailHash)) } -var ( +type avatarSettingStruct struct { defaultAvatarLink string - once sync.Once -) + gravatarSource string + gravatarSourceURL *url.URL + libravatar *libravatar.Libravatar +} -// DefaultAvatarLink the default avatar link -func DefaultAvatarLink() string { - once.Do(func() { +var avatarSettingAtomic atomic.Pointer[avatarSettingStruct] + +func loadAvatarSetting() (*avatarSettingStruct, error) { + s := avatarSettingAtomic.Load() + if s == nil || s.gravatarSource != setting.GravatarSource { + s = &avatarSettingStruct{} u, err := url.Parse(setting.AppSubURL) if err != nil { - log.Error("Can not parse AppSubURL: %v", err) - return + return nil, fmt.Errorf("unable to parse AppSubURL: %w", err) } u.Path = path.Join(u.Path, "/assets/img/avatar_default.png") - defaultAvatarLink = u.String() - }) - return defaultAvatarLink + s.defaultAvatarLink = u.String() + + s.gravatarSourceURL, err = url.Parse(setting.GravatarSource) + if err != nil { + return nil, fmt.Errorf("unable to parse GravatarSource %q: %w", setting.GravatarSource, err) + } + + s.libravatar = libravatar.New() + if s.gravatarSourceURL.Scheme == "https" { + s.libravatar.SetUseHTTPS(true) + s.libravatar.SetSecureFallbackHost(s.gravatarSourceURL.Host) + } else { + s.libravatar.SetUseHTTPS(false) + s.libravatar.SetFallbackHost(s.gravatarSourceURL.Host) + } + + avatarSettingAtomic.Store(s) + } + return s, nil +} + +// DefaultAvatarLink the default avatar link +func DefaultAvatarLink() string { + a, err := loadAvatarSetting() + if err != nil { + log.Error("Failed to loadAvatarSetting: %v", err) + return "" + } + return a.defaultAvatarLink } // HashEmail hashes email address to MD5 string. https://en.gravatar.com/site/implement/hash/ @@ -76,7 +108,11 @@ func GetEmailForHash(md5Sum string) (string, error) { // LibravatarURL returns the URL for the given email. Slow due to the DNS lookup. // This function should only be called if a federated avatar service is enabled. func LibravatarURL(email string) (*url.URL, error) { - urlStr, err := system_model.LibravatarService.FromEmail(email) + a, err := loadAvatarSetting() + if err != nil { + return nil, err + } + urlStr, err := a.libravatar.FromEmail(email) if err != nil { log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err) return nil, err @@ -153,15 +189,13 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final return DefaultAvatarLink() } - disableGravatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar, - setting.GetDefaultDisableGravatar(), - ) - - enableFederatedAvatar := system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureEnableFederatedAvatar, - setting.GetDefaultEnableFederatedAvatar(disableGravatar)) + avatarSetting, err := loadAvatarSetting() + if err != nil { + return DefaultAvatarLink() + } - var err error - if enableFederatedAvatar && system_model.LibravatarService != nil { + enableFederatedAvatar := setting.Config().Picture.EnableFederatedAvatar.Value(ctx) + if enableFederatedAvatar { emailHash := saveEmailHash(email) if final { // for final link, we can spend more time on slow external query @@ -179,9 +213,10 @@ func generateEmailAvatarLink(ctx context.Context, email string, size int, final return urlStr } + disableGravatar := setting.Config().Picture.DisableGravatar.Value(ctx) if !disableGravatar { // copy GravatarSourceURL, because we will modify its Path. - avatarURLCopy := *system_model.GravatarSourceURL + avatarURLCopy := *avatarSetting.gravatarSourceURL avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email)) return generateRecognizedAvatarURL(avatarURLCopy, size) } |