diff options
Diffstat (limited to 'models/user/avatar.go')
-rw-r--r-- | models/user/avatar.go | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/models/user/avatar.go b/models/user/avatar.go new file mode 100644 index 0000000000..c881642b56 --- /dev/null +++ b/models/user/avatar.go @@ -0,0 +1,113 @@ +// Copyright 2020 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 user + +import ( + "context" + "crypto/md5" + "fmt" + "image/png" + "io" + "strings" + + "code.gitea.io/gitea/models/avatars" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/avatar" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/storage" +) + +// CustomAvatarRelativePath returns user custom avatar relative path. +func (u *User) CustomAvatarRelativePath() string { + return u.Avatar +} + +// GenerateRandomAvatar generates a random avatar for user. +func GenerateRandomAvatar(u *User) error { + return GenerateRandomAvatarCtx(db.DefaultContext, u) +} + +// GenerateRandomAvatarCtx generates a random avatar for user. +func GenerateRandomAvatarCtx(ctx context.Context, u *User) error { + seed := u.Email + if len(seed) == 0 { + seed = u.Name + } + + img, err := avatar.RandomImage([]byte(seed)) + if err != nil { + return fmt.Errorf("RandomImage: %v", err) + } + + u.Avatar = avatars.HashEmail(seed) + + // Don't share the images so that we can delete them easily + if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error { + if err := png.Encode(w, img); err != nil { + log.Error("Encode: %v", err) + } + return err + }); err != nil { + return fmt.Errorf("Failed to create dir %s: %v", u.CustomAvatarRelativePath(), err) + } + + if _, err := db.GetEngine(ctx).ID(u.ID).Cols("avatar").Update(u); err != nil { + return err + } + + log.Info("New random avatar created: %d", u.ID) + return nil +} + +// AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size +func (u *User) AvatarLinkWithSize(size int) string { + if u.ID == -1 { + // ghost user + return avatars.DefaultAvatarLink() + } + + useLocalAvatar := false + autoGenerateAvatar := false + + switch { + case u.UseCustomAvatar: + useLocalAvatar = true + case setting.DisableGravatar, setting.OfflineMode: + useLocalAvatar = true + autoGenerateAvatar = true + } + + if useLocalAvatar { + if u.Avatar == "" && autoGenerateAvatar { + if err := GenerateRandomAvatar(u); err != nil { + log.Error("GenerateRandomAvatar: %v", err) + } + } + if u.Avatar == "" { + return avatars.DefaultAvatarLink() + } + return avatars.GenerateUserAvatarImageLink(u.Avatar, size) + } + return avatars.GenerateEmailAvatarFastLink(u.AvatarEmail, size) +} + +// AvatarLink returns the full avatar link with http host +func (u *User) AvatarLink() string { + link := u.AvatarLinkWithSize(0) + if !strings.HasPrefix(link, "//") && !strings.Contains(link, "://") { + return setting.AppURL + strings.TrimPrefix(link, setting.AppSubURL+"/") + } + return link +} + +// IsUploadAvatarChanged returns true if the current user's avatar would be changed with the provided data +func (u *User) IsUploadAvatarChanged(data []byte) bool { + if !u.UseCustomAvatar || len(u.Avatar) == 0 { + return true + } + avatarID := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d-%x", u.ID, md5.Sum(data))))) + return u.Avatar != avatarID +} |