Browse Source

Show custom avatars in commits

Unknwon 9 years ago
parent
commit
1d57f0d64f

+ 1 - 1
README.md

@@ -5,7 +5,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
 
 ![](public/img/gogs-large-resize.png)
 
-##### Current version: 0.7.7 Beta
+##### Current version: 0.7.8 Beta
 
 <table>
     <tr>

+ 3 - 3
cmd/web.go

@@ -7,7 +7,7 @@ package cmd
 import (
 	"crypto/tls"
 	"fmt"
-	"html/template"
+	gotmpl "html/template"
 	"io/ioutil"
 	"net/http"
 	"net/http/fcgi"
@@ -35,11 +35,11 @@ import (
 	"github.com/gogits/gogs/modules/auth"
 	"github.com/gogits/gogs/modules/auth/apiv1"
 	"github.com/gogits/gogs/modules/avatar"
-	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/bindata"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/middleware"
 	"github.com/gogits/gogs/modules/setting"
+	"github.com/gogits/gogs/modules/template"
 	"github.com/gogits/gogs/routers"
 	"github.com/gogits/gogs/routers/admin"
 	"github.com/gogits/gogs/routers/api/v1"
@@ -124,7 +124,7 @@ func newMacaron() *macaron.Macaron {
 	))
 	m.Use(macaron.Renderer(macaron.RenderOptions{
 		Directory:  path.Join(setting.StaticRootPath, "templates"),
-		Funcs:      []template.FuncMap{base.TemplateFuncs},
+		Funcs:      []gotmpl.FuncMap{template.Funcs},
 		IndentJSON: macaron.Env != macaron.PROD,
 	}))
 

+ 1 - 1
gogs.go

@@ -17,7 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.7.7.1113 Beta"
+const APP_VER = "0.7.8.1113 Beta"
 
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())

+ 43 - 3
models/action.go

@@ -208,8 +208,48 @@ func issueIndexTrimRight(c rune) bool {
 	return !unicode.IsDigit(c)
 }
 
+type PushCommit struct {
+	Sha1        string
+	Message     string
+	AuthorEmail string
+	AuthorName  string
+}
+
+type PushCommits struct {
+	Len        int
+	Commits    []*PushCommit
+	CompareUrl string
+
+	avatars map[string]string
+}
+
+func NewPushCommits() *PushCommits {
+	return &PushCommits{
+		avatars: make(map[string]string),
+	}
+}
+
+// AvatarLink tries to match user in database with e-mail
+// in order to show custom avatar, and falls back to general avatar link.
+func (push *PushCommits) AvatarLink(email string) string {
+	_, ok := push.avatars[email]
+	if !ok {
+		u, err := GetUserByEmail(email)
+		if err != nil {
+			push.avatars[email] = base.AvatarLink(email)
+			if !IsErrUserNotExist(err) {
+				log.Error(4, "GetUserByEmail: %v", err)
+			}
+		} else {
+			push.avatars[email] = u.AvatarLink()
+		}
+	}
+
+	return push.avatars[email]
+}
+
 // updateIssuesCommit checks if issues are manipulated by commit message.
-func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*base.PushCommit) error {
+func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*PushCommit) error {
 	// Commits are appended in the reverse order.
 	for i := len(commits) - 1; i >= 0; i-- {
 		c := commits[i]
@@ -343,7 +383,7 @@ func CommitRepoAction(
 	repoID int64,
 	repoUserName, repoName string,
 	refFullName string,
-	commit *base.PushCommits,
+	commit *PushCommits,
 	oldCommitID string, newCommitID string) error {
 
 	u, err := GetUserByID(userID)
@@ -369,7 +409,7 @@ func CommitRepoAction(
 	// Check it's tag push or branch.
 	if strings.HasPrefix(refFullName, "refs/tags/") {
 		opType = PUSH_TAG
-		commit = &base.PushCommits{}
+		commit = &PushCommits{}
 	} else {
 		// if not the first commit, set the compareUrl
 		if !strings.HasPrefix(oldCommitID, "0000000") {

+ 4 - 5
models/update.go

@@ -10,7 +10,6 @@ import (
 	"os/exec"
 	"strings"
 
-	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/git"
 	"github.com/gogits/gogs/modules/log"
 )
@@ -100,7 +99,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
 			actEmail = cmt.Committer.Email
 		}
 
-		commit := &base.PushCommits{}
+		commit := &PushCommits{}
 
 		if err = CommitRepoAction(userID, user.Id, userName, actEmail,
 			repo.ID, repoUserName, repoName, refName, commit, oldCommitID, newCommitID); err != nil {
@@ -133,7 +132,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
 	}
 
 	// Push commits.
-	commits := make([]*base.PushCommit, 0)
+	commits := make([]*PushCommit, 0)
 	var actEmail string
 	for e := l.Front(); e != nil; e = e.Next() {
 		commit := e.Value.(*git.Commit)
@@ -141,7 +140,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
 			actEmail = commit.Committer.Email
 		}
 		commits = append(commits,
-			&base.PushCommit{commit.ID.String(),
+			&PushCommit{commit.ID.String(),
 				commit.Message(),
 				commit.Author.Email,
 				commit.Author.Name,
@@ -149,7 +148,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
 	}
 
 	if err = CommitRepoAction(userID, user.Id, userName, actEmail,
-		repo.ID, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitID, newCommitID); err != nil {
+		repo.ID, repoUserName, repoName, refName, &PushCommits{l.Len(), commits, "", nil}, oldCommitID, newCommitID); err != nil {
 		return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
 	}
 	return nil

+ 1 - 1
models/user.go

@@ -991,7 +991,7 @@ func GetUserByEmail(email string) (*User, error) {
 		return GetUserByID(emailAddress.UID)
 	}
 
-	return nil, ErrUserNotExist{0, "email"}
+	return nil, ErrUserNotExist{0, email}
 }
 
 // SearchUserByName returns given number of users whose name contains keyword.

+ 18 - 0
modules/base/tool.go

@@ -23,6 +23,8 @@ import (
 	"github.com/Unknwon/i18n"
 	"github.com/microcosm-cc/bluemonday"
 
+	"github.com/gogits/chardet"
+
 	"github.com/gogits/gogs/modules/avatar"
 	"github.com/gogits/gogs/modules/setting"
 )
@@ -43,6 +45,22 @@ func EncodeSha1(str string) string {
 	return hex.EncodeToString(h.Sum(nil))
 }
 
+func ShortSha(sha1 string) string {
+	if len(sha1) == 40 {
+		return sha1[:10]
+	}
+	return sha1
+}
+
+func DetectEncoding(content []byte) (string, error) {
+	detector := chardet.NewTextDetector()
+	result, err := detector.DetectBest(content)
+	if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
+		return setting.Repository.AnsiCharset, err
+	}
+	return result.Charset, err
+}
+
 func BasicAuthDecode(encoded string) (string, string, error) {
 	s, err := base64.StdEncoding.DecodeString(encoded)
 	if err != nil {

+ 18 - 46
modules/base/template.go → modules/template/template.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-package base
+package template
 
 import (
 	"container/list"
@@ -16,7 +16,8 @@ import (
 	"golang.org/x/net/html/charset"
 	"golang.org/x/text/transform"
 
-	"github.com/gogits/chardet"
+	"github.com/gogits/gogs/models"
+	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/setting"
 )
 
@@ -25,7 +26,7 @@ func Safe(raw string) template.HTML {
 }
 
 func Str2html(raw string) template.HTML {
-	return template.HTML(Sanitizer.Sanitize(raw))
+	return template.HTML(base.Sanitizer.Sanitize(raw))
 }
 
 func Range(l int) []int {
@@ -46,27 +47,11 @@ func List(l *list.List) chan interface{} {
 }
 
 func Sha1(str string) string {
-	return EncodeSha1(str)
-}
-
-func ShortSha(sha1 string) string {
-	if len(sha1) == 40 {
-		return sha1[:10]
-	}
-	return sha1
-}
-
-func DetectEncoding(content []byte) (string, error) {
-	detector := chardet.NewTextDetector()
-	result, err := detector.DetectBest(content)
-	if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
-		return setting.Repository.AnsiCharset, err
-	}
-	return result.Charset, err
+	return base.EncodeSha1(str)
 }
 
 func ToUtf8WithErr(content []byte) (error, string) {
-	charsetLabel, err := DetectEncoding(content)
+	charsetLabel, err := base.DetectEncoding(content)
 	if err != nil {
 		return err, ""
 	}
@@ -124,7 +109,7 @@ func ReplaceLeft(s, old, new string) string {
 // RenderCommitMessage renders commit message with XSS-safe and special links.
 func RenderCommitMessage(msg, urlPrefix string) template.HTML {
 	cleanMsg := template.HTMLEscapeString(msg)
-	fullMessage := string(RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
+	fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
 	msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
 	for i := range msgLines {
 		msgLines[i] = ReplaceLeft(msgLines[i], " ", "&nbsp;")
@@ -134,7 +119,7 @@ func RenderCommitMessage(msg, urlPrefix string) template.HTML {
 	return template.HTML(fullMessage)
 }
 
-var TemplateFuncs template.FuncMap = map[string]interface{}{
+var Funcs template.FuncMap = map[string]interface{}{
 	"GoVer": func() string {
 		return strings.Title(runtime.Version())
 	},
@@ -156,13 +141,13 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
 	"LoadTimes": func(startTime time.Time) string {
 		return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
 	},
-	"AvatarLink":   AvatarLink,
+	"AvatarLink":   base.AvatarLink,
 	"Safe":         Safe,
 	"Str2html":     Str2html,
-	"TimeSince":    TimeSince,
-	"RawTimeSince": RawTimeSince,
-	"FileSize":     FileSize,
-	"Subtract":     Subtract,
+	"TimeSince":    base.TimeSince,
+	"RawTimeSince": base.RawTimeSince,
+	"FileSize":     base.FileSize,
+	"Subtract":     base.Subtract,
 	"Add": func(a, b int) int {
 		return a + b
 	},
@@ -197,8 +182,8 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
 	"DiffTypeToStr":     DiffTypeToStr,
 	"DiffLineTypeToStr": DiffLineTypeToStr,
 	"Sha1":              Sha1,
-	"ShortSha":          ShortSha,
-	"Md5":               EncodeMd5,
+	"ShortSha":          base.ShortSha,
+	"Md5":               base.EncodeMd5,
 	"ActionContent2Commits": ActionContent2Commits,
 	"Oauth2Icon":            Oauth2Icon,
 	"Oauth2Name":            Oauth2Name,
@@ -240,22 +225,9 @@ func ActionIcon(opType int) string {
 	}
 }
 
-type PushCommit struct {
-	Sha1        string
-	Message     string
-	AuthorEmail string
-	AuthorName  string
-}
-
-type PushCommits struct {
-	Len        int
-	Commits    []*PushCommit
-	CompareUrl string
-}
-
-func ActionContent2Commits(act Actioner) *PushCommits {
-	var push *PushCommits
-	if err := json.Unmarshal([]byte(act.GetContent()), &push); err != nil {
+func ActionContent2Commits(act Actioner) *models.PushCommits {
+	push := models.NewPushCommits()
+	if err := json.Unmarshal([]byte(act.GetContent()), push); err != nil {
 		return nil
 	}
 	return push

+ 2 - 1
routers/repo/view.go

@@ -16,6 +16,7 @@ import (
 	"github.com/gogits/gogs/modules/git"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/middleware"
+	"github.com/gogits/gogs/modules/template"
 )
 
 const (
@@ -105,7 +106,7 @@ func Home(ctx *middleware.Context) {
 				if readmeExist {
 					ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink)))
 				} else {
-					if err, content := base.ToUtf8WithErr(buf); err != nil {
+					if err, content := template.ToUtf8WithErr(buf); err != nil {
 						if err != nil {
 							log.Error(4, "Convert content encoding: %s", err)
 						}

+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.7.7.1113 Beta
+0.7.8.1113 Beta

+ 4 - 4
templates/user/dashboard/dashboard.tmpl

@@ -26,7 +26,7 @@
               {{range .Repos}}
               <li {{if .IsPrivate}}class="private"{{end}}>
                 <a href="{{AppSubUrl}}/{{$.ContextUser.Name}}/{{.Name}}">
-                  <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
+                  <i class="icon octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
                   <strong>{{.Name}}</strong>
                   <span class="ui right text light grey">
                     <i class="octicon octicon-star"></i>{{.NumStars}}
@@ -46,7 +46,7 @@
               {{range .CollaborativeRepos}}
               <li {{if .IsPrivate}}class="private"{{end}}>
                 <a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">
-                  <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
+                  <i class="icon octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
                   {{.Owner.Name}} / <strong>{{.Name}}</strong>
                   <span class="ui right text light grey">
                     <i class="octicon octicon-star"></i>{{.NumStars}}
@@ -72,7 +72,7 @@
               {{range .ContextUser.Orgs}}
               <li>
                 <a href="{{AppSubUrl}}/{{.Name}}">
-                  <i class="octicon octicon-organization"></i>
+                  <i class="icon octicon octicon-organization"></i>
                   <strong>{{.Name}}</strong>
                   <span class="ui right text light grey">
                     <i class="octicon octicon-repo"></i>{{.NumRepos}}
@@ -94,7 +94,7 @@
               {{range .Mirrors}}
               <li {{if .IsPrivate}}class="private"{{end}}>
                 <a href="{{AppSubUrl}}/{{$.ContextUser.Name}}/{{.Name}}">
-                  <i class="octicon octicon-repo-clone"></i>
+                  <i class="icon octicon octicon-repo-clone"></i>
                   <strong>{{.Name}}</strong>
                   <span class="ui right text light grey">
                     <i class="octicon octicon-sync"></i>{{.Interval}}H

+ 1 - 1
templates/user/dashboard/feeds.tmpl

@@ -39,7 +39,7 @@
             {{ $repoLink := .GetRepoLink}}
             {{if $push.Commits}}
             {{range $push.Commits}}
-            <li><img class="img-8" src="{{AvatarLink .AuthorEmail}}"> <a href="{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text truncate light grey">{{.Message}}</span></li>
+            <li><img class="img-8" src="{{$push.AvatarLink .AuthorEmail}}"> <a href="{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text truncate light grey">{{.Message}}</span></li>
             {{end}}
             {{end}}
             {{if $push.CompareUrl}}<li><a href="{{AppSubUrl}}/{{$push.CompareUrl}}">{{$.i18n.Tr "action.compare_2_commits"}} »</a></li>{{end}}