mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Show custom avatars in commits
This commit is contained in:
		| @@ -5,7 +5,7 @@ Gogs - Go Git Service [ | ||||
|  | ||||
| ##### Current version: 0.7.7 Beta | ||||
| ##### Current version: 0.7.8 Beta | ||||
|  | ||||
| <table> | ||||
|     <tr> | ||||
|   | ||||
| @@ -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, | ||||
| 	})) | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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()) | ||||
|   | ||||
| @@ -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") { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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], " ", " ") | ||||
| @@ -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 | ||||
| @@ -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 @@ | ||||
| 0.7.7.1113 Beta | ||||
| 0.7.8.1113 Beta | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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}} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user