gitea源码

notify.go 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package mailer
  4. import (
  5. "context"
  6. "fmt"
  7. actions_model "code.gitea.io/gitea/models/actions"
  8. activities_model "code.gitea.io/gitea/models/activities"
  9. issues_model "code.gitea.io/gitea/models/issues"
  10. repo_model "code.gitea.io/gitea/models/repo"
  11. user_model "code.gitea.io/gitea/models/user"
  12. "code.gitea.io/gitea/modules/log"
  13. issue_service "code.gitea.io/gitea/services/issue"
  14. notify_service "code.gitea.io/gitea/services/notify"
  15. )
  16. type mailNotifier struct {
  17. notify_service.NullNotifier
  18. }
  19. var _ notify_service.Notifier = &mailNotifier{}
  20. // NewNotifier create a new mailNotifier notifier
  21. func NewNotifier() notify_service.Notifier {
  22. return &mailNotifier{}
  23. }
  24. func (m *mailNotifier) CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
  25. issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
  26. ) {
  27. var act activities_model.ActionType
  28. switch comment.Type {
  29. case issues_model.CommentTypeClose:
  30. act = activities_model.ActionCloseIssue
  31. case issues_model.CommentTypeReopen:
  32. act = activities_model.ActionReopenIssue
  33. case issues_model.CommentTypeComment:
  34. act = activities_model.ActionCommentIssue
  35. case issues_model.CommentTypeCode:
  36. act = activities_model.ActionCommentIssue
  37. case issues_model.CommentTypePullRequestPush:
  38. act = 0
  39. }
  40. if err := MailParticipantsComment(ctx, comment, act, issue, mentions); err != nil {
  41. log.Error("MailParticipantsComment: %v", err)
  42. }
  43. }
  44. func (m *mailNotifier) NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
  45. if err := MailParticipants(ctx, issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil {
  46. log.Error("MailParticipants: %v", err)
  47. }
  48. }
  49. func (m *mailNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
  50. var actionType activities_model.ActionType
  51. if issue.IsPull {
  52. if isClosed {
  53. actionType = activities_model.ActionClosePullRequest
  54. } else {
  55. actionType = activities_model.ActionReopenPullRequest
  56. }
  57. } else {
  58. if isClosed {
  59. actionType = activities_model.ActionCloseIssue
  60. } else {
  61. actionType = activities_model.ActionReopenIssue
  62. }
  63. }
  64. if err := MailParticipants(ctx, issue, doer, actionType, nil); err != nil {
  65. log.Error("MailParticipants: %v", err)
  66. }
  67. }
  68. func (m *mailNotifier) IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
  69. if err := issue.LoadPullRequest(ctx); err != nil {
  70. log.Error("issue.LoadPullRequest: %v", err)
  71. return
  72. }
  73. if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress(ctx) {
  74. if err := MailParticipants(ctx, issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil {
  75. log.Error("MailParticipants: %v", err)
  76. }
  77. }
  78. }
  79. func (m *mailNotifier) NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
  80. if err := MailParticipants(ctx, pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil {
  81. log.Error("MailParticipants: %v", err)
  82. }
  83. }
  84. func (m *mailNotifier) PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
  85. var act activities_model.ActionType
  86. switch comment.Type {
  87. case issues_model.CommentTypeClose:
  88. act = activities_model.ActionCloseIssue
  89. case issues_model.CommentTypeReopen:
  90. act = activities_model.ActionReopenIssue
  91. case issues_model.CommentTypeComment:
  92. act = activities_model.ActionCommentPull
  93. }
  94. if err := MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil {
  95. log.Error("MailParticipantsComment: %v", err)
  96. }
  97. }
  98. func (m *mailNotifier) PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
  99. if err := MailMentionsComment(ctx, pr, comment, mentions); err != nil {
  100. log.Error("MailMentionsComment: %v", err)
  101. }
  102. }
  103. func (m *mailNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
  104. // mail only sent to added assignees and not self-assignee
  105. if !removed && doer.ID != assignee.ID && assignee.EmailNotificationsPreference != user_model.EmailNotificationsDisabled {
  106. ct := fmt.Sprintf("Assigned #%d.", issue.Index)
  107. if err := SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{assignee}); err != nil {
  108. log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err)
  109. }
  110. }
  111. }
  112. func (m *mailNotifier) PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
  113. if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotificationsPreference != user_model.EmailNotificationsDisabled {
  114. ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL(ctx))
  115. if err := SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil {
  116. log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err)
  117. }
  118. }
  119. }
  120. func (m *mailNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
  121. if err := pr.LoadIssue(ctx); err != nil {
  122. log.Error("LoadIssue: %v", err)
  123. return
  124. }
  125. if err := MailParticipants(ctx, pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil {
  126. log.Error("MailParticipants: %v", err)
  127. }
  128. }
  129. func (m *mailNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
  130. if err := pr.LoadIssue(ctx); err != nil {
  131. log.Error("pr.LoadIssue: %v", err)
  132. return
  133. }
  134. if err := MailParticipants(ctx, pr.Issue, doer, activities_model.ActionAutoMergePullRequest, nil); err != nil {
  135. log.Error("MailParticipants: %v", err)
  136. }
  137. }
  138. func (m *mailNotifier) PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
  139. var err error
  140. if err = comment.LoadIssue(ctx); err != nil {
  141. log.Error("comment.LoadIssue: %v", err)
  142. return
  143. }
  144. if err = comment.Issue.LoadRepo(ctx); err != nil {
  145. log.Error("comment.Issue.LoadRepo: %v", err)
  146. return
  147. }
  148. if err = comment.Issue.LoadPullRequest(ctx); err != nil {
  149. log.Error("comment.Issue.LoadPullRequest: %v", err)
  150. return
  151. }
  152. if err = comment.Issue.PullRequest.LoadBaseRepo(ctx); err != nil {
  153. log.Error("comment.Issue.PullRequest.LoadBaseRepo: %v", err)
  154. return
  155. }
  156. if err := issue_service.LoadCommentPushCommits(ctx, comment); err != nil {
  157. log.Error("comment.LoadPushCommits: %v", err)
  158. }
  159. m.CreateIssueComment(ctx, doer, comment.Issue.Repo, comment.Issue, comment, nil)
  160. }
  161. func (m *mailNotifier) PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
  162. if err := comment.Review.LoadReviewer(ctx); err != nil {
  163. log.Error("Error in PullReviewDismiss while loading reviewer for issue[%d], review[%d] and reviewer[%d]: %v", review.Issue.ID, comment.Review.ID, comment.Review.ReviewerID, err)
  164. }
  165. if err := MailParticipantsComment(ctx, comment, activities_model.ActionPullReviewDismissed, review.Issue, nil); err != nil {
  166. log.Error("MailParticipantsComment: %v", err)
  167. }
  168. }
  169. func (m *mailNotifier) NewRelease(ctx context.Context, rel *repo_model.Release) {
  170. if err := rel.LoadAttributes(ctx); err != nil {
  171. log.Error("LoadAttributes: %v", err)
  172. return
  173. }
  174. if rel.IsDraft || rel.IsPrerelease {
  175. return
  176. }
  177. MailNewRelease(ctx, rel)
  178. }
  179. func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
  180. if err := SendRepoTransferNotifyMail(ctx, doer, newOwner, repo); err != nil {
  181. log.Error("SendRepoTransferNotifyMail: %v", err)
  182. }
  183. }
  184. func (m *mailNotifier) WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) {
  185. if err := MailActionsTrigger(ctx, sender, repo, run); err != nil {
  186. log.Error("MailActionsTrigger: %v", err)
  187. }
  188. }