2016-07-16 00:36:39 +08:00
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"fmt"
"github.com/Unknwon/com"
2016-11-10 17:24:48 +01:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markdown"
"code.gitea.io/gitea/modules/setting"
2016-07-16 00:36:39 +08:00
)
2016-11-25 09:11:12 +01:00
func ( issue * Issue ) mailSubject ( ) string {
2016-08-14 03:32:24 -07:00
return fmt . Sprintf ( "[%s] %s (#%d)" , issue . Repo . Name , issue . Title , issue . Index )
2016-07-16 00:36:39 +08:00
}
// mailIssueCommentToParticipants can be used for both new issue creation and comment.
2017-03-16 02:34:24 +01:00
// This function sends two list of emails:
// 1. Repository watchers and users who are participated in comments.
// 2. Users who are not in 1. but get mentioned in current issue/comment.
2017-08-30 12:31:33 +08:00
func mailIssueCommentToParticipants ( e Engine , issue * Issue , doer * User , comment * Comment , mentions [ ] string ) error {
2016-07-16 00:36:39 +08:00
if ! setting . Service . EnableNotifyMail {
return nil
}
2017-08-30 12:31:33 +08:00
watchers , err := getWatchers ( e , issue . RepoID )
2016-07-16 00:36:39 +08:00
if err != nil {
2017-08-30 12:31:33 +08:00
return fmt . Errorf ( "getWatchers [repo_id: %d]: %v" , issue . RepoID , err )
2017-03-16 02:34:24 +01:00
}
2017-08-30 12:31:33 +08:00
participants , err := getParticipantsByIssueID ( e , issue . ID )
2017-03-16 02:34:24 +01:00
if err != nil {
2017-08-30 12:31:33 +08:00
return fmt . Errorf ( "getParticipantsByIssueID [issue_id: %d]: %v" , issue . ID , err )
2017-03-16 02:34:24 +01:00
}
2017-09-16 02:18:25 +02:00
// In case the issue poster is not watching the repository and is active,
2017-03-16 02:34:24 +01:00
// even if we have duplicated in watchers, can be safely filtered out.
2017-09-16 02:18:25 +02:00
poster , err := GetUserByID ( issue . PosterID )
if err != nil {
return fmt . Errorf ( "GetUserByID [%d]: %v" , issue . PosterID , err )
}
if issue . PosterID != doer . ID && poster . IsActive && ! poster . ProhibitLogin {
2017-03-16 02:34:24 +01:00
participants = append ( participants , issue . Poster )
2016-07-16 00:36:39 +08:00
}
2017-06-23 15:43:37 +02:00
// Assignee must receive any communications
if issue . Assignee != nil && issue . AssigneeID > 0 && issue . AssigneeID != doer . ID {
participants = append ( participants , issue . Assignee )
}
2016-07-16 00:36:39 +08:00
tos := make ( [ ] string , 0 , len ( watchers ) ) // List of email addresses.
names := make ( [ ] string , 0 , len ( watchers ) )
for i := range watchers {
2016-07-24 01:08:22 +08:00
if watchers [ i ] . UserID == doer . ID {
2016-07-16 00:36:39 +08:00
continue
}
2017-08-30 12:31:33 +08:00
to , err := getUserByID ( e , watchers [ i ] . UserID )
2016-07-16 00:36:39 +08:00
if err != nil {
return fmt . Errorf ( "GetUserByID [%d]: %v" , watchers [ i ] . UserID , err )
}
if to . IsOrganization ( ) {
continue
}
tos = append ( tos , to . Email )
names = append ( names , to . Name )
}
2017-03-16 02:34:24 +01:00
for i := range participants {
if participants [ i ] . ID == doer . ID {
continue
} else if com . IsSliceContainsStr ( names , participants [ i ] . Name ) {
continue
}
tos = append ( tos , participants [ i ] . Email )
names = append ( names , participants [ i ] . Name )
}
2017-05-25 04:38:56 +02:00
SendIssueCommentMail ( issue , doer , comment , tos )
2016-07-16 00:36:39 +08:00
// Mail mentioned people and exclude watchers.
names = append ( names , doer . Name )
tos = make ( [ ] string , 0 , len ( mentions ) ) // list of user names.
for i := range mentions {
if com . IsSliceContainsStr ( names , mentions [ i ] ) {
continue
}
tos = append ( tos , mentions [ i ] )
}
2017-08-30 12:31:33 +08:00
SendIssueMentionMail ( issue , doer , comment , getUserEmailsByNames ( e , tos ) )
2016-07-16 00:36:39 +08:00
return nil
}
// MailParticipants sends new issue thread created emails to repository watchers
// and mentioned people.
func ( issue * Issue ) MailParticipants ( ) ( err error ) {
2017-08-30 12:31:33 +08:00
return issue . mailParticipants ( x )
}
func ( issue * Issue ) mailParticipants ( e Engine ) ( err error ) {
2016-07-16 00:36:39 +08:00
mentions := markdown . FindAllMentions ( issue . Content )
2017-08-30 12:31:33 +08:00
if err = UpdateIssueMentions ( e , issue . ID , mentions ) ; err != nil {
2016-07-16 00:36:39 +08:00
return fmt . Errorf ( "UpdateIssueMentions [%d]: %v" , issue . ID , err )
}
2017-08-30 12:31:33 +08:00
if err = mailIssueCommentToParticipants ( e , issue , issue . Poster , nil , mentions ) ; err != nil {
2016-07-16 00:36:39 +08:00
log . Error ( 4 , "mailIssueCommentToParticipants: %v" , err )
}
return nil
}