@@ -22,6 +22,7 @@ import (
22
22
"code.gitea.io/gitea/modules/markup/markdown"
23
23
"code.gitea.io/gitea/modules/setting"
24
24
"code.gitea.io/gitea/modules/timeutil"
25
+ "code.gitea.io/gitea/modules/translation"
25
26
26
27
"gopkg.in/gomail.v2"
27
28
)
@@ -57,17 +58,21 @@ func SendTestMail(email string) error {
57
58
return gomail .Send (Sender , NewMessage ([]string {email }, "Gitea Test Email!" , "Gitea Test Email!" ).ToMessage ())
58
59
}
59
60
60
- // SendUserMail sends a mail to the user
61
- func SendUserMail (language string , u * models.User , tpl base.TplName , code , subject , info string ) {
61
+ // sendUserMail sends a mail to the user
62
+ func sendUserMail (language string , u * models.User , tpl base.TplName , code , subject , info string ) {
63
+ locale := translation .NewLocale (language )
62
64
data := map [string ]interface {}{
63
65
"DisplayName" : u .DisplayName (),
64
66
"ActiveCodeLives" : timeutil .MinutesToFriendly (setting .Service .ActiveCodeLives , language ),
65
67
"ResetPwdCodeLives" : timeutil .MinutesToFriendly (setting .Service .ResetPwdCodeLives , language ),
66
68
"Code" : code ,
69
+ "i18n" : locale ,
70
+ "Language" : locale .Language (),
67
71
}
68
72
69
73
var content bytes.Buffer
70
74
75
+ // TODO: i18n templates?
71
76
if err := bodyTemplates .ExecuteTemplate (& content , string (tpl ), data ); err != nil {
72
77
log .Error ("Template: %v" , err )
73
78
return
@@ -79,33 +84,32 @@ func SendUserMail(language string, u *models.User, tpl base.TplName, code, subje
79
84
SendAsync (msg )
80
85
}
81
86
82
- // Locale represents an interface to translation
83
- type Locale interface {
84
- Language () string
85
- Tr (string , ... interface {}) string
86
- }
87
-
88
87
// SendActivateAccountMail sends an activation mail to the user (new user registration)
89
- func SendActivateAccountMail (locale Locale , u * models.User ) {
90
- SendUserMail (locale .Language (), u , mailAuthActivate , u .GenerateActivateCode ( ), locale .Tr ("mail.activate_account" ), "activate account" )
88
+ func SendActivateAccountMail (locale translation. Locale , u * models.User ) {
89
+ sendUserMail (locale .Language (), u , mailAuthActivate , u .GenerateEmailActivateCode ( u . Email ), locale .Tr ("mail.activate_account" ), "activate account" )
91
90
}
92
91
93
92
// SendResetPasswordMail sends a password reset mail to the user
94
- func SendResetPasswordMail (locale Locale , u * models.User ) {
95
- SendUserMail (locale .Language (), u , mailAuthResetPassword , u .GenerateActivateCode (), locale .Tr ("mail.reset_password" ), "recover account" )
93
+ func SendResetPasswordMail (u * models.User ) {
94
+ locale := translation .NewLocale (u .Language )
95
+ sendUserMail (u .Language , u , mailAuthResetPassword , u .GenerateEmailActivateCode (u .Email ), locale .Tr ("mail.reset_password" ), "recover account" )
96
96
}
97
97
98
98
// SendActivateEmailMail sends confirmation email to confirm new email address
99
- func SendActivateEmailMail (locale Locale , u * models.User , email * models.EmailAddress ) {
99
+ func SendActivateEmailMail (u * models.User , email * models.EmailAddress ) {
100
+ locale := translation .NewLocale (u .Language )
100
101
data := map [string ]interface {}{
101
102
"DisplayName" : u .DisplayName (),
102
103
"ActiveCodeLives" : timeutil .MinutesToFriendly (setting .Service .ActiveCodeLives , locale .Language ()),
103
104
"Code" : u .GenerateEmailActivateCode (email .Email ),
104
105
"Email" : email .Email ,
106
+ "i18n" : locale ,
107
+ "Language" : locale .Language (),
105
108
}
106
109
107
110
var content bytes.Buffer
108
111
112
+ // TODO: i18n templates?
109
113
if err := bodyTemplates .ExecuteTemplate (& content , string (mailAuthActivateEmail ), data ); err != nil {
110
114
log .Error ("Template: %v" , err )
111
115
return
@@ -118,19 +122,19 @@ func SendActivateEmailMail(locale Locale, u *models.User, email *models.EmailAdd
118
122
}
119
123
120
124
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
121
- func SendRegisterNotifyMail (locale Locale , u * models.User ) {
122
- if setting .MailService == nil {
123
- log .Warn ("SendRegisterNotifyMail is being invoked but mail service hasn't been initialized" )
124
- return
125
- }
125
+ func SendRegisterNotifyMail (u * models.User ) {
126
+ locale := translation .NewLocale (u .Language )
126
127
127
128
data := map [string ]interface {}{
128
129
"DisplayName" : u .DisplayName (),
129
130
"Username" : u .Name ,
131
+ "i18n" : locale ,
132
+ "Language" : locale .Language (),
130
133
}
131
134
132
135
var content bytes.Buffer
133
136
137
+ // TODO: i18n templates?
134
138
if err := bodyTemplates .ExecuteTemplate (& content , string (mailAuthRegisterNotify ), data ); err != nil {
135
139
log .Error ("Template: %v" , err )
136
140
return
@@ -144,17 +148,21 @@ func SendRegisterNotifyMail(locale Locale, u *models.User) {
144
148
145
149
// SendCollaboratorMail sends mail notification to new collaborator.
146
150
func SendCollaboratorMail (u , doer * models.User , repo * models.Repository ) {
151
+ locale := translation .NewLocale (u .Language )
147
152
repoName := repo .FullName ()
148
- subject := fmt .Sprintf ("%s added you to %s" , doer .DisplayName (), repoName )
149
153
154
+ subject := locale .Tr ("mail.repo.collaborator.added.subject" , doer .DisplayName (), repoName )
150
155
data := map [string ]interface {}{
151
156
"Subject" : subject ,
152
157
"RepoName" : repoName ,
153
158
"Link" : repo .HTMLURL (),
159
+ "i18n" : locale ,
160
+ "Language" : locale .Language (),
154
161
}
155
162
156
163
var content bytes.Buffer
157
164
165
+ // TODO: i18n templates?
158
166
if err := bodyTemplates .ExecuteTemplate (& content , string (mailNotifyCollaborator ), data ); err != nil {
159
167
log .Error ("Template: %v" , err )
160
168
return
@@ -166,7 +174,7 @@ func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) {
166
174
SendAsync (msg )
167
175
}
168
176
169
- func composeIssueCommentMessages (ctx * mailCommentContext , tos []string , fromMention bool , info string ) []* Message {
177
+ func composeIssueCommentMessages (ctx * mailCommentContext , lang string , tos []string , fromMention bool , info string ) []* Message {
170
178
171
179
var (
172
180
subject string
@@ -192,7 +200,6 @@ func composeIssueCommentMessages(ctx *mailCommentContext, tos []string, fromMent
192
200
193
201
// This is the body of the new issue or comment, not the mail body
194
202
body := string (markup .RenderByType (markdown .MarkupName , []byte (ctx .Content ), ctx .Issue .Repo .HTMLURL (), ctx .Issue .Repo .ComposeMetas ()))
195
-
196
203
actType , actName , tplName := actionToTemplate (ctx .Issue , ctx .ActionType , commentType , reviewType )
197
204
198
205
if actName != "new" {
@@ -208,6 +215,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, tos []string, fromMent
208
215
}
209
216
}
210
217
}
218
+ locale := translation .NewLocale (lang )
211
219
212
220
mailMeta := map [string ]interface {}{
213
221
"FallbackSubject" : fallback ,
@@ -224,13 +232,16 @@ func composeIssueCommentMessages(ctx *mailCommentContext, tos []string, fromMent
224
232
"ActionType" : actType ,
225
233
"ActionName" : actName ,
226
234
"ReviewComments" : reviewComments ,
235
+ "i18n" : locale ,
236
+ "Language" : locale .Language (),
227
237
}
228
238
229
239
var mailSubject bytes.Buffer
240
+ // TODO: i18n templates?
230
241
if err := subjectTemplates .ExecuteTemplate (& mailSubject , string (tplName ), mailMeta ); err == nil {
231
242
subject = sanitizeSubject (mailSubject .String ())
232
243
} else {
233
- log .Error ("ExecuteTemplate [%s]: %v" , string ( tplName ) + "/subject" , err )
244
+ log .Error ("ExecuteTemplate [%s]: %v" , tplName + "/subject" , err )
234
245
}
235
246
236
247
if subject == "" {
@@ -243,6 +254,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, tos []string, fromMent
243
254
244
255
var mailBody bytes.Buffer
245
256
257
+ // TODO: i18n templates?
246
258
if err := bodyTemplates .ExecuteTemplate (& mailBody , string (tplName ), mailMeta ); err != nil {
247
259
log .Error ("ExecuteTemplate [%s]: %v" , string (tplName )+ "/body" , err )
248
260
}
@@ -276,14 +288,21 @@ func sanitizeSubject(subject string) string {
276
288
}
277
289
278
290
// SendIssueAssignedMail composes and sends issue assigned email
279
- func SendIssueAssignedMail (issue * models.Issue , doer * models.User , content string , comment * models.Comment , tos []string ) {
280
- SendAsyncs (composeIssueCommentMessages (& mailCommentContext {
281
- Issue : issue ,
282
- Doer : doer ,
283
- ActionType : models .ActionType (0 ),
284
- Content : content ,
285
- Comment : comment ,
286
- }, tos , false , "issue assigned" ))
291
+ func SendIssueAssignedMail (issue * models.Issue , doer * models.User , content string , comment * models.Comment , recipients []* models.User ) {
292
+ langMap := make (map [string ][]string )
293
+ for _ , user := range recipients {
294
+ langMap [user .Language ] = append (langMap [user .Language ], user .Email )
295
+ }
296
+
297
+ for lang , tos := range langMap {
298
+ SendAsyncs (composeIssueCommentMessages (& mailCommentContext {
299
+ Issue : issue ,
300
+ Doer : doer ,
301
+ ActionType : models .ActionType (0 ),
302
+ Content : content ,
303
+ Comment : comment ,
304
+ }, lang , tos , false , "issue assigned" ))
305
+ }
287
306
}
288
307
289
308
// actionToTemplate returns the type and name of the action facing the user
0 commit comments