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 (
2022-08-25 05:31:57 +03:00
activities_model "code.gitea.io/gitea/models/activities"
2021-12-12 18:48:20 +03:00
"code.gitea.io/gitea/models/db"
2022-06-13 12:37:59 +03:00
issues_model "code.gitea.io/gitea/models/issues"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2022-10-12 08:18:26 +03:00
"code.gitea.io/gitea/modules/container"
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
}
)
2022-01-20 20:46:10 +03:00
var _ base . Notifier = & notificationService { }
2018-10-18 14:23:05 +03:00
// 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
}
2022-01-23 00:22:14 +03:00
func ( ns * notificationService ) handle ( data ... queue . Data ) [ ] queue . Data {
2020-02-16 03:29:43 +03:00
for _ , datum := range data {
opts := datum . ( issueNotificationOpts )
2022-08-25 05:31:57 +03:00
if err := activities_model . 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
}
}
2022-01-23 00:22:14 +03:00
return nil
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-12-10 04:27:50 +03:00
func ( ns * notificationService ) NotifyCreateIssueComment ( doer * user_model . User , repo * repo_model . Repository ,
2022-06-13 12:37:59 +03:00
issue * issues_model . Issue , comment * issues_model . Comment , mentions [ ] * user_model . User ,
2022-02-23 23:16:07 +03:00
) {
2022-01-20 20:46:10 +03:00
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 {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2021-01-02 20:04:02 +03:00
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
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyNewIssue ( issue * issues_model . 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
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyIssueChangeStatus ( doer * user_model . User , issue * issues_model . Issue , actionComment * issues_model . 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
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyIssueChangeTitle ( doer * user_model . User , issue * issues_model . Issue , oldTitle string ) {
2021-06-23 07:14:22 +03:00
if err := issue . LoadPullRequest ( ) ; err != nil {
log . Error ( "issue.LoadPullRequest: %v" , err )
return
}
2022-06-13 12:37:59 +03:00
if issue . IsPull && issues_model . HasWorkInProgressPrefix ( oldTitle ) && ! issue . PullRequest . IsWorkInProgress ( ) {
2021-06-23 07:14:22 +03:00
_ = ns . issueQueue . Push ( issueNotificationOpts {
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
} )
}
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyMergePullRequest ( pr * issues_model . 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
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyNewPullRequest ( pr * issues_model . 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
}
2022-10-12 08:18:26 +03:00
toNotify := make ( container . Set [ int64 ] , 32 )
2021-12-12 18:48:20 +03:00
repoWatchers , err := repo_model . GetRepoWatchersIDs ( db . DefaultContext , pr . Issue . RepoID )
2021-06-23 07:14:22 +03:00
if err != nil {
log . Error ( "GetRepoWatchersIDs: %v" , err )
return
}
for _ , id := range repoWatchers {
2022-10-12 08:18:26 +03:00
toNotify . Add ( id )
2021-06-23 07:14:22 +03:00
}
2022-06-13 12:37:59 +03:00
issueParticipants , err := issues_model . GetParticipantsIDsByIssueID ( pr . IssueID )
2021-06-23 07:14:22 +03:00
if err != nil {
log . Error ( "GetParticipantsIDsByIssueID: %v" , err )
return
}
for _ , id := range issueParticipants {
2022-10-12 08:18:26 +03:00
toNotify . Add ( id )
2021-06-23 07:14:22 +03:00
}
delete ( toNotify , pr . Issue . PosterID )
2021-01-02 20:04:02 +03:00
for _ , mention := range mentions {
2022-10-12 08:18:26 +03:00
toNotify . Add ( mention . ID )
2021-06-23 07:14:22 +03:00
}
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
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyPullRequestReview ( pr * issues_model . PullRequest , r * issues_model . Review , c * issues_model . Comment , mentions [ ] * user_model . User ) {
2022-01-20 20:46:10 +03:00
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 {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2021-01-02 20:04:02 +03:00
IssueID : pr . Issue . ID ,
NotificationAuthorID : r . Reviewer . ID ,
ReceiverID : mention . ID ,
}
if c != nil {
opts . CommentID = c . ID
}
_ = ns . issueQueue . Push ( opts )
}
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyPullRequestCodeComment ( pr * issues_model . PullRequest , c * issues_model . 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
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyPullRequestPushCommits ( doer * user_model . User , pr * issues_model . PullRequest , comment * issues_model . Comment ) {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2020-05-20 15:47:24 +03:00
IssueID : pr . IssueID ,
NotificationAuthorID : doer . ID ,
CommentID : comment . ID ,
}
_ = ns . issueQueue . Push ( opts )
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyPullRevieweDismiss ( doer * user_model . User , review * issues_model . Review , comment * issues_model . Comment ) {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2021-02-11 20:32:25 +03:00
IssueID : review . IssueID ,
NotificationAuthorID : doer . ID ,
CommentID : comment . ID ,
}
_ = ns . issueQueue . Push ( opts )
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyIssueChangeAssignee ( doer * user_model . User , issue * issues_model . Issue , assignee * user_model . User , removed bool , comment * issues_model . Comment ) {
2022-02-18 09:06:57 +03:00
if ! removed && doer . ID != assignee . ID {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2020-04-06 19:33:34 +03:00
IssueID : issue . ID ,
NotificationAuthorID : doer . ID ,
ReceiverID : assignee . ID ,
}
if comment != nil {
opts . CommentID = comment . ID
}
_ = ns . issueQueue . Push ( opts )
}
}
2022-06-13 12:37:59 +03:00
func ( ns * notificationService ) NotifyPullReviewRequest ( doer * user_model . User , issue * issues_model . Issue , reviewer * user_model . User , isRequest bool , comment * issues_model . Comment ) {
2020-04-06 19:33:34 +03:00
if isRequest {
2022-01-20 20:46:10 +03:00
opts := issueNotificationOpts {
2020-04-06 19:33:34 +03:00
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-12-10 04:27:50 +03:00
func ( ns * notificationService ) NotifyRepoPendingTransfer ( doer , newOwner * user_model . User , repo * repo_model . Repository ) {
2022-08-25 05:31:57 +03:00
if err := activities_model . CreateRepoTransferNotification ( doer , newOwner , repo ) ; err != nil {
2021-03-01 03:47:30 +03:00
log . Error ( "NotifyRepoPendingTransfer: %v" , err )
}
}