Generate random avatar based on e-mail when disable Gravatar

This commit is contained in:
Unknwon 2015-08-09 11:46:10 +08:00
parent 56a8d573b0
commit 4b43ffc96c
4 changed files with 59 additions and 4 deletions

View File

@ -14,6 +14,7 @@ github.com/go-xorm/core =
github.com/go-xorm/xorm = github.com/go-xorm/xorm =
github.com/gogits/chardet = commit:2404f77725 github.com/gogits/chardet = commit:2404f77725
github.com/gogits/go-gogs-client = commit:92e76d616a github.com/gogits/go-gogs-client = commit:92e76d616a
github.com/issue9/identicon =
github.com/lib/pq = commit:0dad96c0b9 github.com/lib/pq = commit:0dad96c0b9
github.com/macaron-contrib/binding = commit:de6ed78668 github.com/macaron-contrib/binding = commit:de6ed78668
github.com/macaron-contrib/cache = commit:cd824f6f2d github.com/macaron-contrib/cache = commit:cd824f6f2d

View File

@ -13,7 +13,9 @@ import (
"fmt" "fmt"
"image" "image"
"image/jpeg" "image/jpeg"
_ "image/jpeg"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
@ -116,11 +118,39 @@ func (u *User) HomeLink() string {
// AvatarLink returns user gravatar link. // AvatarLink returns user gravatar link.
func (u *User) AvatarLink() string { func (u *User) AvatarLink() string {
defaultImgUrl := setting.AppSubUrl + "/img/avatar_default.jpg"
imgPath := path.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
switch { switch {
case u.UseCustomAvatar: case u.UseCustomAvatar:
if !com.IsExist(imgPath) {
return defaultImgUrl
}
return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id) return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id)
case setting.DisableGravatar, setting.OfflineMode: 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: case setting.Service.EnableCacheAvatar:
return setting.AppSubUrl + "/avatar/" + u.Avatar return setting.AppSubUrl + "/avatar/" + u.Avatar
} }

View File

@ -19,9 +19,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"image" "image"
"image/color/palette"
"image/jpeg" "image/jpeg"
"image/png" "image/png"
"io" "io"
"math/rand"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -30,6 +32,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/issue9/identicon"
"github.com/nfnt/resize" "github.com/nfnt/resize"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
@ -59,6 +62,27 @@ func HashEmail(email string) string {
return hex.EncodeToString(h.Sum(nil)) 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. // Avatar represents the avatar object.
type Avatar struct { type Avatar struct {
Hash string Hash string

View File

@ -14,19 +14,19 @@
<div class="ui selection dropdown"> <div class="ui selection dropdown">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.Id}}" required> <input type="hidden" id="uid" name="uid" value="{{.ContextUser.Id}}" required>
<span class="text"> <span class="text">
<img class="ui mini avatar image" src="{{.ContextUser.AvatarLink}}"> <img class="ui mini image" src="{{.ContextUser.AvatarLink}}">
{{.ContextUser.Name}} {{.ContextUser.Name}}
</span> </span>
<i class="dropdown icon"></i> <i class="dropdown icon"></i>
<div class="menu"> <div class="menu">
<div class="item" data-value="{{.SignedUser.Id}}"> <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}} {{.SignedUser.Name}}
</div> </div>
{{range .Orgs}} {{range .Orgs}}
{{if .IsOwnedBy $.SignedUser.Id}} {{if .IsOwnedBy $.SignedUser.Id}}
<div class="item" data-value="{{.Id}}"> <div class="item" data-value="{{.Id}}">
<img class="ui mini avatar image" src="{{.AvatarLink}}"> <img class="ui mini image" src="{{.AvatarLink}}">
{{.Name}} {{.Name}}
</div> </div>
{{end}} {{end}}