Generate random avatar based on e-mail when disable Gravatar
parent
56a8d573b0
commit
4b43ffc96c
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
Loading…
Reference in New Issue