mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Generate random avatar based on e-mail when disable Gravatar
This commit is contained in:
		@@ -14,6 +14,7 @@ github.com/go-xorm/core =
 | 
			
		||||
github.com/go-xorm/xorm = 
 | 
			
		||||
github.com/gogits/chardet = commit:2404f77725
 | 
			
		||||
github.com/gogits/go-gogs-client = commit:92e76d616a
 | 
			
		||||
github.com/issue9/identicon = 
 | 
			
		||||
github.com/lib/pq = commit:0dad96c0b9
 | 
			
		||||
github.com/macaron-contrib/binding = commit:de6ed78668
 | 
			
		||||
github.com/macaron-contrib/cache = commit:cd824f6f2d
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,9 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/jpeg"
 | 
			
		||||
	_ "image/jpeg"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -116,11 +118,39 @@ func (u *User) HomeLink() string {
 | 
			
		||||
 | 
			
		||||
// AvatarLink returns user gravatar link.
 | 
			
		||||
func (u *User) AvatarLink() string {
 | 
			
		||||
	defaultImgUrl := setting.AppSubUrl + "/img/avatar_default.jpg"
 | 
			
		||||
	imgPath := path.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
 | 
			
		||||
	switch {
 | 
			
		||||
	case u.UseCustomAvatar:
 | 
			
		||||
		if !com.IsExist(imgPath) {
 | 
			
		||||
			return defaultImgUrl
 | 
			
		||||
		}
 | 
			
		||||
		return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id)
 | 
			
		||||
	case setting.DisableGravatar, setting.OfflineMode:
 | 
			
		||||
		return setting.AppSubUrl + "/img/avatar_default.jpg"
 | 
			
		||||
		if !com.IsExist(imgPath) {
 | 
			
		||||
			img, err := avatar.RandomImage([]byte(u.Email))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error(3, "RandomImage: %v", err)
 | 
			
		||||
				return defaultImgUrl
 | 
			
		||||
			}
 | 
			
		||||
			if err = os.MkdirAll(path.Dir(imgPath), os.ModePerm); err != nil {
 | 
			
		||||
				log.Error(3, "Create: %v", err)
 | 
			
		||||
				return defaultImgUrl
 | 
			
		||||
			}
 | 
			
		||||
			fw, err := os.Create(imgPath)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error(3, "Create: %v", err)
 | 
			
		||||
				return defaultImgUrl
 | 
			
		||||
			}
 | 
			
		||||
			defer fw.Close()
 | 
			
		||||
 | 
			
		||||
			if err = jpeg.Encode(fw, img, nil); err != nil {
 | 
			
		||||
				log.Error(3, "Encode: %v", err)
 | 
			
		||||
				return defaultImgUrl
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id)
 | 
			
		||||
	case setting.Service.EnableCacheAvatar:
 | 
			
		||||
		return setting.AppSubUrl + "/avatar/" + u.Avatar
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,11 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/color/palette"
 | 
			
		||||
	"image/jpeg"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	"io"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
@@ -30,6 +32,7 @@ import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/issue9/identicon"
 | 
			
		||||
	"github.com/nfnt/resize"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
@@ -59,6 +62,27 @@ func HashEmail(email string) string {
 | 
			
		||||
	return hex.EncodeToString(h.Sum(nil))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _RANDOM_AVATAR_SIZE = 200
 | 
			
		||||
 | 
			
		||||
// RandomImage generates and returns a random avatar image.
 | 
			
		||||
func RandomImage(data []byte) (image.Image, error) {
 | 
			
		||||
	randExtent := len(palette.WebSafe) - 32
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	colorIndex := rand.Intn(randExtent)
 | 
			
		||||
	backColorIndex := colorIndex - 1
 | 
			
		||||
	if backColorIndex < 0 {
 | 
			
		||||
		backColorIndex = randExtent - 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Size, background, forecolor
 | 
			
		||||
	imgMaker, err := identicon.New(_RANDOM_AVATAR_SIZE,
 | 
			
		||||
		palette.WebSafe[backColorIndex], palette.WebSafe[colorIndex:colorIndex+32]...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return imgMaker.Make(data), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Avatar represents the avatar object.
 | 
			
		||||
type Avatar struct {
 | 
			
		||||
	Hash           string
 | 
			
		||||
 
 | 
			
		||||
@@ -14,19 +14,19 @@
 | 
			
		||||
			      <div class="ui selection dropdown">
 | 
			
		||||
			        <input type="hidden" id="uid" name="uid" value="{{.ContextUser.Id}}" required>
 | 
			
		||||
			        <span class="text">
 | 
			
		||||
			        	<img class="ui mini avatar image" src="{{.ContextUser.AvatarLink}}">
 | 
			
		||||
			        	<img class="ui mini image" src="{{.ContextUser.AvatarLink}}">
 | 
			
		||||
            		{{.ContextUser.Name}}
 | 
			
		||||
            	</span>
 | 
			
		||||
			        <i class="dropdown icon"></i>
 | 
			
		||||
			        <div class="menu">
 | 
			
		||||
			        	<div class="item" data-value="{{.SignedUser.Id}}">
 | 
			
		||||
				        	<img class="ui mini avatar image" src="{{.SignedUser.AvatarLink}}">
 | 
			
		||||
				        	<img class="ui mini image" src="{{.SignedUser.AvatarLink}}">
 | 
			
		||||
	            		{{.SignedUser.Name}}
 | 
			
		||||
			        	</div>
 | 
			
		||||
			        	{{range .Orgs}}
 | 
			
		||||
			        	{{if .IsOwnedBy $.SignedUser.Id}}
 | 
			
		||||
			        	<div class="item" data-value="{{.Id}}">
 | 
			
		||||
				        	<img class="ui mini avatar image" src="{{.AvatarLink}}">
 | 
			
		||||
				        	<img class="ui mini image" src="{{.AvatarLink}}">
 | 
			
		||||
	            		{{.Name}}
 | 
			
		||||
			        	</div>
 | 
			
		||||
			        	{{end}}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user