Browse Source

Show custom avatars in commits

Unknwon 4 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
5 5
 
6 6
 ![](public/img/gogs-large-resize.png)
7 7
 
8
-##### Current version: 0.7.7 Beta
8
+##### Current version: 0.7.8 Beta
9 9
 
10 10
 <table>
11 11
     <tr>

+ 3 - 3
cmd/web.go

@@ -7,7 +7,7 @@ package cmd
7 7
 import (
8 8
 	"crypto/tls"
9 9
 	"fmt"
10
-	"html/template"
10
+	gotmpl "html/template"
11 11
 	"io/ioutil"
12 12
 	"net/http"
13 13
 	"net/http/fcgi"
@@ -35,11 +35,11 @@ import (
35 35
 	"github.com/gogits/gogs/modules/auth"
36 36
 	"github.com/gogits/gogs/modules/auth/apiv1"
37 37
 	"github.com/gogits/gogs/modules/avatar"
38
-	"github.com/gogits/gogs/modules/base"
39 38
 	"github.com/gogits/gogs/modules/bindata"
40 39
 	"github.com/gogits/gogs/modules/log"
41 40
 	"github.com/gogits/gogs/modules/middleware"
42 41
 	"github.com/gogits/gogs/modules/setting"
42
+	"github.com/gogits/gogs/modules/template"
43 43
 	"github.com/gogits/gogs/routers"
44 44
 	"github.com/gogits/gogs/routers/admin"
45 45
 	"github.com/gogits/gogs/routers/api/v1"
@@ -124,7 +124,7 @@ func newMacaron() *macaron.Macaron {
124 124
 	))
125 125
 	m.Use(macaron.Renderer(macaron.RenderOptions{
126 126
 		Directory:  path.Join(setting.StaticRootPath, "templates"),
127
-		Funcs:      []template.FuncMap{base.TemplateFuncs},
127
+		Funcs:      []gotmpl.FuncMap{template.Funcs},
128 128
 		IndentJSON: macaron.Env != macaron.PROD,
129 129
 	}))
130 130
 

+ 1 - 1
gogs.go

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

+ 43 - 3
models/action.go

@@ -208,8 +208,48 @@ func issueIndexTrimRight(c rune) bool {
208 208
 	return !unicode.IsDigit(c)
209 209
 }
210 210
 
211
+type PushCommit struct {
212
+	Sha1        string
213
+	Message     string
214
+	AuthorEmail string
215
+	AuthorName  string
216
+}
217
+
218
+type PushCommits struct {
219
+	Len        int
220
+	Commits    []*PushCommit
221
+	CompareUrl string
222
+
223
+	avatars map[string]string
224
+}
225
+
226
+func NewPushCommits() *PushCommits {
227
+	return &PushCommits{
228
+		avatars: make(map[string]string),
229
+	}
230
+}
231
+
232
+// AvatarLink tries to match user in database with e-mail
233
+// in order to show custom avatar, and falls back to general avatar link.
234
+func (push *PushCommits) AvatarLink(email string) string {
235
+	_, ok := push.avatars[email]
236
+	if !ok {
237
+		u, err := GetUserByEmail(email)
238
+		if err != nil {
239
+			push.avatars[email] = base.AvatarLink(email)
240
+			if !IsErrUserNotExist(err) {
241
+				log.Error(4, "GetUserByEmail: %v", err)
242
+			}
243
+		} else {
244
+			push.avatars[email] = u.AvatarLink()
245
+		}
246
+	}
247
+
248
+	return push.avatars[email]
249
+}
250
+
211 251
 // updateIssuesCommit checks if issues are manipulated by commit message.
212
-func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*base.PushCommit) error {
252
+func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*PushCommit) error {
213 253
 	// Commits are appended in the reverse order.
214 254
 	for i := len(commits) - 1; i >= 0; i-- {
215 255
 		c := commits[i]
@@ -343,7 +383,7 @@ func CommitRepoAction(
343 383
 	repoID int64,
344 384
 	repoUserName, repoName string,
345 385
 	refFullName string,
346
-	commit *base.PushCommits,
386
+	commit *PushCommits,
347 387
 	oldCommitID string, newCommitID string) error {
348 388
 
349 389
 	u, err := GetUserByID(userID)
@@ -369,7 +409,7 @@ func CommitRepoAction(
369 409
 	// Check it's tag push or branch.
370 410
 	if strings.HasPrefix(refFullName, "refs/tags/") {
371 411
 		opType = PUSH_TAG
372
-		commit = &base.PushCommits{}
412
+		commit = &PushCommits{}
373 413
 	} else {
374 414
 		// if not the first commit, set the compareUrl
375 415
 		if !strings.HasPrefix(oldCommitID, "0000000") {

+ 4 - 5
models/update.go

@@ -10,7 +10,6 @@ import (
10 10
 	"os/exec"
11 11
 	"strings"
12 12
 
13
-	"github.com/gogits/gogs/modules/base"
14 13
 	"github.com/gogits/gogs/modules/git"
15 14
 	"github.com/gogits/gogs/modules/log"
16 15
 )
@@ -100,7 +99,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
100 99
 			actEmail = cmt.Committer.Email
101 100
 		}
102 101
 
103
-		commit := &base.PushCommits{}
102
+		commit := &PushCommits{}
104 103
 
105 104
 		if err = CommitRepoAction(userID, user.Id, userName, actEmail,
106 105
 			repo.ID, repoUserName, repoName, refName, commit, oldCommitID, newCommitID); err != nil {
@@ -133,7 +132,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
133 132
 	}
134 133
 
135 134
 	// Push commits.
136
-	commits := make([]*base.PushCommit, 0)
135
+	commits := make([]*PushCommit, 0)
137 136
 	var actEmail string
138 137
 	for e := l.Front(); e != nil; e = e.Next() {
139 138
 		commit := e.Value.(*git.Commit)
@@ -141,7 +140,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
141 140
 			actEmail = commit.Committer.Email
142 141
 		}
143 142
 		commits = append(commits,
144
-			&base.PushCommit{commit.ID.String(),
143
+			&PushCommit{commit.ID.String(),
145 144
 				commit.Message(),
146 145
 				commit.Author.Email,
147 146
 				commit.Author.Name,
@@ -149,7 +148,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
149 148
 	}
150 149
 
151 150
 	if err = CommitRepoAction(userID, user.Id, userName, actEmail,
152
-		repo.ID, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitID, newCommitID); err != nil {
151
+		repo.ID, repoUserName, repoName, refName, &PushCommits{l.Len(), commits, "", nil}, oldCommitID, newCommitID); err != nil {
153 152
 		return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
154 153
 	}
155 154
 	return nil

+ 1 - 1
models/user.go

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

+ 18 - 0
modules/base/tool.go

@@ -23,6 +23,8 @@ import (
23 23
 	"github.com/Unknwon/i18n"
24 24
 	"github.com/microcosm-cc/bluemonday"
25 25
 
26
+	"github.com/gogits/chardet"
27
+
26 28
 	"github.com/gogits/gogs/modules/avatar"
27 29
 	"github.com/gogits/gogs/modules/setting"
28 30
 )
@@ -43,6 +45,22 @@ func EncodeSha1(str string) string {
43 45
 	return hex.EncodeToString(h.Sum(nil))
44 46
 }
45 47
 
48
+func ShortSha(sha1 string) string {
49
+	if len(sha1) == 40 {
50
+		return sha1[:10]
51
+	}
52
+	return sha1
53
+}
54
+
55
+func DetectEncoding(content []byte) (string, error) {
56
+	detector := chardet.NewTextDetector()
57
+	result, err := detector.DetectBest(content)
58
+	if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
59
+		return setting.Repository.AnsiCharset, err
60
+	}
61
+	return result.Charset, err
62
+}
63
+
46 64
 func BasicAuthDecode(encoded string) (string, string, error) {
47 65
 	s, err := base64.StdEncoding.DecodeString(encoded)
48 66
 	if err != nil {

+ 18 - 46
modules/base/template.go

@@ -2,7 +2,7 @@
2 2
 // Use of this source code is governed by a MIT-style
3 3
 // license that can be found in the LICENSE file.
4 4
 
5
-package base
5
+package template
6 6
 
7 7
 import (
8 8
 	"container/list"
@@ -16,7 +16,8 @@ import (
16 16
 	"golang.org/x/net/html/charset"
17 17
 	"golang.org/x/text/transform"
18 18
 
19
-	"github.com/gogits/chardet"
19
+	"github.com/gogits/gogs/models"
20
+	"github.com/gogits/gogs/modules/base"
20 21
 	"github.com/gogits/gogs/modules/setting"
21 22
 )
22 23
 
@@ -25,7 +26,7 @@ func Safe(raw string) template.HTML {
25 26
 }
26 27
 
27 28
 func Str2html(raw string) template.HTML {
28
-	return template.HTML(Sanitizer.Sanitize(raw))
29
+	return template.HTML(base.Sanitizer.Sanitize(raw))
29 30
 }
30 31
 
31 32
 func Range(l int) []int {
@@ -46,27 +47,11 @@ func List(l *list.List) chan interface{} {
46 47
 }
47 48
 
48 49
 func Sha1(str string) string {
49
-	return EncodeSha1(str)
50
-}
51
-
52
-func ShortSha(sha1 string) string {
53
-	if len(sha1) == 40 {
54
-		return sha1[:10]
55
-	}
56
-	return sha1
57
-}
58
-
59
-func DetectEncoding(content []byte) (string, error) {
60
-	detector := chardet.NewTextDetector()
61
-	result, err := detector.DetectBest(content)
62
-	if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
63
-		return setting.Repository.AnsiCharset, err
64
-	}
65
-	return result.Charset, err
50
+	return base.EncodeSha1(str)
66 51
 }
67 52
 
68 53
 func ToUtf8WithErr(content []byte) (error, string) {
69
-	charsetLabel, err := DetectEncoding(content)
54
+	charsetLabel, err := base.DetectEncoding(content)
70 55
 	if err != nil {
71 56
 		return err, ""
72 57
 	}
@@ -124,7 +109,7 @@ func ReplaceLeft(s, old, new string) string {
124 109
 // RenderCommitMessage renders commit message with XSS-safe and special links.
125 110
 func RenderCommitMessage(msg, urlPrefix string) template.HTML {
126 111
 	cleanMsg := template.HTMLEscapeString(msg)
127
-	fullMessage := string(RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
112
+	fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
128 113
 	msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
129 114
 	for i := range msgLines {
130 115
 		msgLines[i] = ReplaceLeft(msgLines[i], " ", "&nbsp;")
@@ -134,7 +119,7 @@ func RenderCommitMessage(msg, urlPrefix string) template.HTML {
134 119
 	return template.HTML(fullMessage)
135 120
 }
136 121
 
137
-var TemplateFuncs template.FuncMap = map[string]interface{}{
122
+var Funcs template.FuncMap = map[string]interface{}{
138 123
 	"GoVer": func() string {
139 124
 		return strings.Title(runtime.Version())
140 125
 	},
@@ -156,13 +141,13 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
156 141
 	"LoadTimes": func(startTime time.Time) string {
157 142
 		return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
158 143
 	},
159
-	"AvatarLink":   AvatarLink,
144
+	"AvatarLink":   base.AvatarLink,
160 145
 	"Safe":         Safe,
161 146
 	"Str2html":     Str2html,
162
-	"TimeSince":    TimeSince,
163
-	"RawTimeSince": RawTimeSince,
164
-	"FileSize":     FileSize,
165
-	"Subtract":     Subtract,
147
+	"TimeSince":    base.TimeSince,
148
+	"RawTimeSince": base.RawTimeSince,
149
+	"FileSize":     base.FileSize,
150
+	"Subtract":     base.Subtract,
166 151
 	"Add": func(a, b int) int {
167 152
 		return a + b
168 153
 	},
@@ -197,8 +182,8 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
197 182
 	"DiffTypeToStr":     DiffTypeToStr,
198 183
 	"DiffLineTypeToStr": DiffLineTypeToStr,
199 184
 	"Sha1":              Sha1,
200
-	"ShortSha":          ShortSha,
201
-	"Md5":               EncodeMd5,
185
+	"ShortSha":          base.ShortSha,
186
+	"Md5":               base.EncodeMd5,
202 187
 	"ActionContent2Commits": ActionContent2Commits,
203 188
 	"Oauth2Icon":            Oauth2Icon,
204 189
 	"Oauth2Name":            Oauth2Name,
@@ -240,22 +225,9 @@ func ActionIcon(opType int) string {
240 225
 	}
241 226
 }
242 227
 
243
-type PushCommit struct {
244
-	Sha1        string
245
-	Message     string
246
-	AuthorEmail string
247
-	AuthorName  string
248
-}
249
-
250
-type PushCommits struct {
251
-	Len        int
252
-	Commits    []*PushCommit
253
-	CompareUrl string
254
-}
255
-
256
-func ActionContent2Commits(act Actioner) *PushCommits {
257
-	var push *PushCommits
258
-	if err := json.Unmarshal([]byte(act.GetContent()), &push); err != nil {
228
+func ActionContent2Commits(act Actioner) *models.PushCommits {
229
+	push := models.NewPushCommits()
230
+	if err := json.Unmarshal([]byte(act.GetContent()), push); err != nil {
259 231
 		return nil
260 232
 	}
261 233
 	return push

+ 2 - 1
routers/repo/view.go

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

+ 1 - 1
templates/.VERSION

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

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

@@ -26,7 +26,7 @@
26 26
               {{range .Repos}}
27 27
               <li {{if .IsPrivate}}class="private"{{end}}>
28 28
                 <a href="{{AppSubUrl}}/{{$.ContextUser.Name}}/{{.Name}}">
29
-                  <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
29
+                  <i class="icon octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
30 30
                   <strong>{{.Name}}</strong>
31 31
                   <span class="ui right text light grey">
32 32
                     <i class="octicon octicon-star"></i>{{.NumStars}}
@@ -46,7 +46,7 @@
46 46
               {{range .CollaborativeRepos}}
47 47
               <li {{if .IsPrivate}}class="private"{{end}}>
48 48
                 <a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">
49
-                  <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
49
+                  <i class="icon octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
50 50
                   {{.Owner.Name}} / <strong>{{.Name}}</strong>
51 51
                   <span class="ui right text light grey">
52 52
                     <i class="octicon octicon-star"></i>{{.NumStars}}
@@ -72,7 +72,7 @@
72 72
               {{range .ContextUser.Orgs}}
73 73
               <li>
74 74
                 <a href="{{AppSubUrl}}/{{.Name}}">
75
-                  <i class="octicon octicon-organization"></i>
75
+                  <i class="icon octicon octicon-organization"></i>
76 76
                   <strong>{{.Name}}</strong>
77 77
                   <span class="ui right text light grey">
78 78
                     <i class="octicon octicon-repo"></i>{{.NumRepos}}
@@ -94,7 +94,7 @@
94 94
               {{range .Mirrors}}
95 95
               <li {{if .IsPrivate}}class="private"{{end}}>
96 96
                 <a href="{{AppSubUrl}}/{{$.ContextUser.Name}}/{{.Name}}">
97
-                  <i class="octicon octicon-repo-clone"></i>
97
+                  <i class="icon octicon octicon-repo-clone"></i>
98 98
                   <strong>{{.Name}}</strong>
99 99
                   <span class="ui right text light grey">
100 100
                     <i class="octicon octicon-sync"></i>{{.Interval}}H

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

@@ -39,7 +39,7 @@
39 39
             {{ $repoLink := .GetRepoLink}}
40 40
             {{if $push.Commits}}
41 41
             {{range $push.Commits}}
42
-            <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>
42
+            <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>
43 43
             {{end}}
44 44
             {{end}}
45 45
             {{if $push.CompareUrl}}<li><a href="{{AppSubUrl}}/{{$push.CompareUrl}}">{{$.i18n.Tr "action.compare_2_commits"}} »</a></li>{{end}}