2020-10-14 16:07:51 +03:00
// 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.
2021-11-24 12:49:20 +03:00
package user
2020-10-14 16:07:51 +03:00
import (
2021-11-24 12:49:20 +03:00
"context"
2020-10-14 16:07:51 +03:00
"crypto/md5"
"fmt"
"image/png"
"io"
2021-10-25 08:01:16 +03:00
"strings"
2020-10-14 16:07:51 +03:00
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
"code.gitea.io/gitea/models/avatars"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2020-10-14 16:07:51 +03:00
"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.
2022-05-20 17:08:52 +03:00
func GenerateRandomAvatar ( ctx context . Context , u * User ) error {
2020-10-14 16:07:51 +03:00
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 )
}
2020-10-23 20:55:10 +03:00
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
u . Avatar = avatars . HashEmail ( seed )
2020-10-14 16:07:51 +03:00
2021-01-02 21:01:09 +03:00
// Don't share the images so that we can delete them easily
2020-10-14 16:07:51 +03:00
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 )
}
2021-11-24 12:49:20 +03:00
if _ , err := db . GetEngine ( ctx ) . ID ( u . ID ) . Cols ( "avatar" ) . Update ( u ) ; err != nil {
2020-10-14 16:07:51 +03:00
return err
}
log . Info ( "New random avatar created: %d" , u . ID )
return nil
}
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
// AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size
func ( u * User ) AvatarLinkWithSize ( size int ) string {
2020-10-14 16:07:51 +03:00
if u . ID == - 1 {
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
// ghost user
return avatars . DefaultAvatarLink ( )
2020-10-14 16:07:51 +03:00
}
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
useLocalAvatar := false
autoGenerateAvatar := false
2020-10-14 16:07:51 +03:00
switch {
case u . UseCustomAvatar :
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
useLocalAvatar = true
2020-10-14 16:07:51 +03:00
case setting . DisableGravatar , setting . OfflineMode :
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
useLocalAvatar = true
autoGenerateAvatar = true
}
if useLocalAvatar {
if u . Avatar == "" && autoGenerateAvatar {
2022-05-20 17:08:52 +03:00
if err := GenerateRandomAvatar ( db . DefaultContext , u ) ; err != nil {
2020-10-14 16:07:51 +03:00
log . Error ( "GenerateRandomAvatar: %v" , err )
}
}
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
if u . Avatar == "" {
return avatars . DefaultAvatarLink ( )
2021-04-17 01:22:25 +03:00
}
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
return avatars . GenerateUserAvatarImageLink ( u . Avatar , size )
2020-10-14 16:07:51 +03:00
}
Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
Why this refactor
The goal is to move most files from `models` package to `models.xxx` package. Many models depend on avatar model, so just move this first.
And the existing logic is not clear, there are too many function like `AvatarLink`, `RelAvatarLink`, `SizedRelAvatarLink`, `SizedAvatarLink`, `MakeFinalAvatarURL`, `HashedAvatarLink`, etc. This refactor make everything clear:
* user.AvatarLink()
* user.AvatarLinkWithSize(size)
* avatars.GenerateEmailAvatarFastLink(email, size)
* avatars.GenerateEmailAvatarFinalLink(email, size)
And many duplicated code are deleted in route handler, the handler and the model share the same avatar logic now.
2021-10-06 02:25:46 +03:00
return avatars . GenerateEmailAvatarFastLink ( u . AvatarEmail , size )
2020-10-14 16:07:51 +03:00
}
2021-10-25 08:01:16 +03:00
// AvatarLink returns the full avatar link with http host
2020-10-14 16:07:51 +03:00
func ( u * User ) AvatarLink ( ) string {
2021-10-25 08:01:16 +03:00
link := u . AvatarLinkWithSize ( 0 )
if ! strings . HasPrefix ( link , "//" ) && ! strings . Contains ( link , "://" ) {
return setting . AppURL + strings . TrimPrefix ( link , setting . AppSubURL + "/" )
}
return link
2020-10-14 16:07:51 +03:00
}
2021-09-27 05:39:36 +03:00
// 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
}