2016-07-15 19:36:39 +03: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 19:24:48 +03:00
"code.gitea.io/gitea/modules/log"
2017-09-16 20:17:57 +03:00
"code.gitea.io/gitea/modules/markup"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/setting"
2016-07-15 19:36:39 +03:00
)
2016-11-25 11:11:12 +03:00
func ( issue * Issue ) mailSubject ( ) string {
2016-08-14 13:32:24 +03:00
return fmt . Sprintf ( "[%s] %s (#%d)" , issue . Repo . Name , issue . Title , issue . Index )
2016-07-15 19:36:39 +03:00
}
// mailIssueCommentToParticipants can be used for both new issue creation and comment.
2017-03-16 04:34:24 +03: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-11-03 12:23:17 +03:00
func mailIssueCommentToParticipants ( e Engine , issue * Issue , doer * User , content string , comment * Comment , mentions [ ] string ) error {
2016-07-15 19:36:39 +03:00
if ! setting . Service . EnableNotifyMail {
return nil
}
2017-08-30 07:31:33 +03:00
watchers , err := getWatchers ( e , issue . RepoID )
2016-07-15 19:36:39 +03:00
if err != nil {
2017-08-30 07:31:33 +03:00
return fmt . Errorf ( "getWatchers [repo_id: %d]: %v" , issue . RepoID , err )
2017-03-16 04:34:24 +03:00
}
2017-08-30 07:31:33 +03:00
participants , err := getParticipantsByIssueID ( e , issue . ID )
2017-03-16 04:34:24 +03:00
if err != nil {
2017-08-30 07:31:33 +03:00
return fmt . Errorf ( "getParticipantsByIssueID [issue_id: %d]: %v" , issue . ID , err )
2017-03-16 04:34:24 +03:00
}
2017-09-16 03:18:25 +03:00
// In case the issue poster is not watching the repository and is active,
2017-03-16 04:34:24 +03:00
// even if we have duplicated in watchers, can be safely filtered out.
2017-09-16 03:18:25 +03: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 04:34:24 +03:00
participants = append ( participants , issue . Poster )
2016-07-15 19:36:39 +03:00
}
2017-06-23 16:43:37 +03:00
// Assignee must receive any communications
if issue . Assignee != nil && issue . AssigneeID > 0 && issue . AssigneeID != doer . ID {
participants = append ( participants , issue . Assignee )
}
2016-07-15 19:36:39 +03:00
tos := make ( [ ] string , 0 , len ( watchers ) ) // List of email addresses.
names := make ( [ ] string , 0 , len ( watchers ) )
for i := range watchers {
2016-07-23 20:08:22 +03:00
if watchers [ i ] . UserID == doer . ID {
2016-07-15 19:36:39 +03:00
continue
}
2017-08-30 07:31:33 +03:00
to , err := getUserByID ( e , watchers [ i ] . UserID )
2016-07-15 19:36:39 +03: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 04:34:24 +03: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 05:38:56 +03:00
2017-11-03 12:23:17 +03:00
SendIssueCommentMail ( issue , doer , content , comment , tos )
2016-07-15 19:36:39 +03: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-11-03 12:23:17 +03:00
SendIssueMentionMail ( issue , doer , content , comment , getUserEmailsByNames ( e , tos ) )
2016-07-15 19:36:39 +03: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 07:31:33 +03:00
return issue . mailParticipants ( x )
}
func ( issue * Issue ) mailParticipants ( e Engine ) ( err error ) {
2017-09-16 20:17:57 +03:00
mentions := markup . FindAllMentions ( issue . Content )
2017-08-30 07:31:33 +03:00
if err = UpdateIssueMentions ( e , issue . ID , mentions ) ; err != nil {
2016-07-15 19:36:39 +03:00
return fmt . Errorf ( "UpdateIssueMentions [%d]: %v" , issue . ID , err )
}
2017-11-03 12:23:17 +03:00
if err = mailIssueCommentToParticipants ( e , issue , issue . Poster , issue . Content , nil , mentions ) ; err != nil {
2016-07-15 19:36:39 +03:00
log . Error ( 4 , "mailIssueCommentToParticipants: %v" , err )
}
return nil
}