summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2015-08-09 11:46:10 +0800
committerUnknwon <u@gogs.io>2015-08-09 11:46:10 +0800
commit4b43ffc96cf16cd49b5796feca8ad853f3e3a8ee (patch)
tree85306f0d5e79394a0dcc4dca4c1cd5e3256471ce
parent56a8d573b0346dce9f6843d61997e5794bc16e4e (diff)
downloadgitea-4b43ffc96cf16cd49b5796feca8ad853f3e3a8ee.tar.gz
gitea-4b43ffc96cf16cd49b5796feca8ad853f3e3a8ee.zip
Generate random avatar based on e-mail when disable Gravatar
-rw-r--r--.gopmfile1
-rw-r--r--models/user.go32
-rw-r--r--modules/avatar/avatar.go24
-rw-r--r--templates/repo/pulls/fork.tmpl6
4 files changed, 59 insertions, 4 deletions
diff --git a/.gopmfile b/.gopmfile
index d59b474eec..ad090603e2 100644
--- a/.gopmfile
+++ b/.gopmfile
@@ -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
diff --git a/models/user.go b/models/user.go
index 6dd31536fb..65b23f791a 100644
--- a/models/user.go
+++ b/models/user.go
@@ -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
}
diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go
index 73daa213c9..5aef6e02cd 100644
--- a/modules/avatar/avatar.go
+++ b/modules/avatar/avatar.go
@@ -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
diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl
index 2f76cf002a..01bbe9b797 100644
--- a/templates/repo/pulls/fork.tmpl
+++ b/templates/repo/pulls/fork.tmpl
@@ -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}}