2018-10-18 14:23:05 +03:00
// Copyright 2018 The Gitea 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 ui
import (
"code.gitea.io/gitea/models"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2020-02-16 03:29:43 +03:00
"code.gitea.io/gitea/modules/graceful"
2018-10-18 14:23:05 +03:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification/base"
2020-02-16 03:29:43 +03:00
"code.gitea.io/gitea/modules/queue"
2018-10-18 14:23:05 +03:00
)
type (
notificationService struct {
2019-01-13 17:42:55 +03:00
base . NullNotifier
2020-02-16 03:29:43 +03:00
issueQueue queue . Queue
2018-10-18 14:23:05 +03:00
}
issueNotificationOpts struct {
2020-02-18 11:52:57 +03:00
IssueID int64
CommentID int64
NotificationAuthorID int64
2020-04-06 19:33:34 +03:00
ReceiverID int64 // 0 -- ALL Watcher
2018-10-18 14:23:05 +03:00
}
)
var (
_ base . Notifier = & notificationService { }
)
// NewNotifier create a new notificationService notifier
func NewNotifier ( ) base . Notifier {
2020-02-16 03:29:43 +03:00
ns := & notificationService { }
ns . issueQueue = queue . CreateQueue ( "notification-service" , ns . handle , issueNotificationOpts { } )
return ns
2018-10-18 14:23:05 +03:00
}
2020-02-16 03:29:43 +03:00
func ( ns * notificationService ) handle ( data ... queue . Data ) {
for _ , datum := range data {
opts := datum . ( issueNotificationOpts )
2020-04-06 19:33:34 +03:00
if err := models . CreateOrUpdateIssueNotifications ( opts . IssueID , opts . CommentID , opts . NotificationAuthorID , opts . ReceiverID ) ; err != nil {
2019-06-12 22:41:28 +03:00
log . Error ( "Was unable to create issue notification: %v" , err )
2018-10-18 14:23:05 +03:00
}
}
}
2020-02-16 03:29:43 +03:00
func ( ns * notificationService ) Run ( ) {
graceful . GetManager ( ) . RunWithShutdownFns ( ns . issueQueue . Run )
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyCreateIssueComment ( doer * user_model . User , repo * models . Repository ,
issue * models . Issue , comment * models . Comment , mentions [ ] * user_model . User ) {
2019-11-12 11:33:34 +03:00
var opts = issueNotificationOpts {
2020-02-18 11:52:57 +03:00
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
2019-11-12 11:33:34 +03:00
}
if comment != nil {
2020-02-18 11:52:57 +03:00
opts . CommentID = comment . ID
2018-10-18 14:23:05 +03:00
}
2020-02-16 03:29:43 +03:00
_ = ns . issueQueue . Push ( opts )
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
var opts = issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
ReceiverID : mention . ID ,
}
if comment != nil {
opts . CommentID = comment . ID
}
_ = ns . issueQueue . Push ( opts )
}
2018-10-18 14:23:05 +03:00
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyNewIssue ( issue * models . Issue , mentions [ ] * user_model . User ) {
2020-02-16 03:29:43 +03:00
_ = ns . issueQueue . Push ( issueNotificationOpts {
2020-02-18 11:52:57 +03:00
IssueID : issue . ID ,
NotificationAuthorID : issue . Poster . ID ,
2020-02-16 03:29:43 +03:00
} )
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
_ = ns . issueQueue . Push ( issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : issue . Poster . ID ,
ReceiverID : mention . ID ,
} )
}
2018-10-18 14:23:05 +03:00
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyIssueChangeStatus ( doer * user_model . User , issue * models . Issue , actionComment * models . Comment , isClosed bool ) {
2020-02-16 03:29:43 +03:00
_ = ns . issueQueue . Push ( issueNotificationOpts {
2020-02-18 11:52:57 +03:00
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
2020-02-16 03:29:43 +03:00
} )
2018-10-18 14:23:05 +03:00
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyIssueChangeTitle ( doer * user_model . User , issue * models . Issue , oldTitle string ) {
2021-06-23 07:14:22 +03:00
if err := issue . LoadPullRequest ( ) ; err != nil {
log . Error ( "issue.LoadPullRequest: %v" , err )
return
}
if issue . IsPull && models . HasWorkInProgressPrefix ( oldTitle ) && ! issue . PullRequest . IsWorkInProgress ( ) {
_ = ns . issueQueue . Push ( issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
} )
}
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyMergePullRequest ( pr * models . PullRequest , doer * user_model . User ) {
2020-02-16 03:29:43 +03:00
_ = ns . issueQueue . Push ( issueNotificationOpts {
2020-02-18 11:52:57 +03:00
IssueID : pr . Issue . ID ,
NotificationAuthorID : doer . ID ,
2020-02-16 03:29:43 +03:00
} )
2018-10-18 14:23:05 +03:00
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyNewPullRequest ( pr * models . PullRequest , mentions [ ] * user_model . User ) {
2020-02-16 03:29:43 +03:00
if err := pr . LoadIssue ( ) ; err != nil {
log . Error ( "Unable to load issue: %d for pr: %d: Error: %v" , pr . IssueID , pr . ID , err )
return
}
2021-06-23 07:14:22 +03:00
toNotify := make ( map [ int64 ] struct { } , 32 )
repoWatchers , err := models . GetRepoWatchersIDs ( pr . Issue . RepoID )
if err != nil {
log . Error ( "GetRepoWatchersIDs: %v" , err )
return
}
for _ , id := range repoWatchers {
toNotify [ id ] = struct { } { }
}
issueParticipants , err := models . GetParticipantsIDsByIssueID ( pr . IssueID )
if err != nil {
log . Error ( "GetParticipantsIDsByIssueID: %v" , err )
return
}
for _ , id := range issueParticipants {
toNotify [ id ] = struct { } { }
}
delete ( toNotify , pr . Issue . PosterID )
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
2021-06-23 07:14:22 +03:00
toNotify [ mention . ID ] = struct { } { }
}
for receiverID := range toNotify {
2021-01-02 20:04:02 +03:00
_ = ns . issueQueue . Push ( issueNotificationOpts {
IssueID : pr . Issue . ID ,
NotificationAuthorID : pr . Issue . PosterID ,
2021-06-23 07:14:22 +03:00
ReceiverID : receiverID ,
2021-01-02 20:04:02 +03:00
} )
}
2018-10-18 14:23:05 +03:00
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyPullRequestReview ( pr * models . PullRequest , r * models . Review , c * models . Comment , mentions [ ] * user_model . User ) {
2019-11-12 11:33:34 +03:00
var opts = issueNotificationOpts {
2020-02-18 11:52:57 +03:00
IssueID : pr . Issue . ID ,
NotificationAuthorID : r . Reviewer . ID ,
2019-11-12 11:33:34 +03:00
}
if c != nil {
2020-02-18 11:52:57 +03:00
opts . CommentID = c . ID
2018-10-18 14:23:05 +03:00
}
2020-02-16 03:29:43 +03:00
_ = ns . issueQueue . Push ( opts )
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
var opts = issueNotificationOpts {
IssueID : pr . Issue . ID ,
NotificationAuthorID : r . Reviewer . ID ,
ReceiverID : mention . ID ,
}
if c != nil {
opts . CommentID = c . ID
}
_ = ns . issueQueue . Push ( opts )
}
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyPullRequestCodeComment ( pr * models . PullRequest , c * models . Comment , mentions [ ] * user_model . User ) {
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
_ = ns . issueQueue . Push ( issueNotificationOpts {
IssueID : pr . Issue . ID ,
NotificationAuthorID : c . Poster . ID ,
CommentID : c . ID ,
ReceiverID : mention . ID ,
} )
}
2018-10-18 14:23:05 +03:00
}
2020-04-06 19:33:34 +03:00
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyPullRequestPushCommits ( doer * user_model . User , pr * models . PullRequest , comment * models . Comment ) {
2020-05-20 15:47:24 +03:00
var opts = issueNotificationOpts {
IssueID : pr . IssueID ,
NotificationAuthorID : doer . ID ,
CommentID : comment . ID ,
}
_ = ns . issueQueue . Push ( opts )
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyPullRevieweDismiss ( doer * user_model . User , review * models . Review , comment * models . Comment ) {
2021-02-11 20:32:25 +03:00
var opts = issueNotificationOpts {
IssueID : review . IssueID ,
NotificationAuthorID : doer . ID ,
CommentID : comment . ID ,
}
_ = ns . issueQueue . Push ( opts )
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyIssueChangeAssignee ( doer * user_model . User , issue * models . Issue , assignee * user_model . User , removed bool , comment * models . Comment ) {
2020-04-06 19:33:34 +03:00
if ! removed {
var opts = issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
ReceiverID : assignee . ID ,
}
if comment != nil {
opts . CommentID = comment . ID
}
_ = ns . issueQueue . Push ( opts )
}
}
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyPullReviewRequest ( doer * user_model . User , issue * models . Issue , reviewer * user_model . User , isRequest bool , comment * models . Comment ) {
2020-04-06 19:33:34 +03:00
if isRequest {
var opts = issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
ReceiverID : reviewer . ID ,
}
if comment != nil {
opts . CommentID = comment . ID
}
_ = ns . issueQueue . Push ( opts )
}
}
2021-03-01 03:47:30 +03:00
2021-11-24 12:49:20 +03:00
func ( ns * notificationService ) NotifyRepoPendingTransfer ( doer , newOwner * user_model . User , repo * models . Repository ) {
2021-03-01 03:47:30 +03:00
if err := models . CreateRepoTransferNotification ( doer , newOwner , repo ) ; err != nil {
log . Error ( "NotifyRepoPendingTransfer: %v" , err )
}
}