@@ -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}} | |||