You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

action.go 7.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package action
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "path"
  9. "strings"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/git"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/notification/base"
  14. )
  15. type actionNotifier struct {
  16. base.NullNotifier
  17. }
  18. var (
  19. _ base.Notifier = &actionNotifier{}
  20. )
  21. // NewNotifier create a new actionNotifier notifier
  22. func NewNotifier() base.Notifier {
  23. return &actionNotifier{}
  24. }
  25. func (a *actionNotifier) NotifyNewIssue(issue *models.Issue) {
  26. if err := issue.LoadPoster(); err != nil {
  27. log.Error("issue.LoadPoster: %v", err)
  28. return
  29. }
  30. if err := issue.LoadRepo(); err != nil {
  31. log.Error("issue.LoadRepo: %v", err)
  32. return
  33. }
  34. repo := issue.Repo
  35. if err := models.NotifyWatchers(&models.Action{
  36. ActUserID: issue.Poster.ID,
  37. ActUser: issue.Poster,
  38. OpType: models.ActionCreateIssue,
  39. Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
  40. RepoID: repo.ID,
  41. Repo: repo,
  42. IsPrivate: repo.IsPrivate,
  43. }); err != nil {
  44. log.Error("NotifyWatchers: %v", err)
  45. }
  46. }
  47. func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest) {
  48. if err := pull.LoadIssue(); err != nil {
  49. log.Error("pull.LoadIssue: %v", err)
  50. return
  51. }
  52. if err := pull.Issue.LoadRepo(); err != nil {
  53. log.Error("pull.Issue.LoadRepo: %v", err)
  54. return
  55. }
  56. if err := pull.Issue.LoadPoster(); err != nil {
  57. log.Error("pull.Issue.LoadPoster: %v", err)
  58. return
  59. }
  60. if err := models.NotifyWatchers(&models.Action{
  61. ActUserID: pull.Issue.Poster.ID,
  62. ActUser: pull.Issue.Poster,
  63. OpType: models.ActionCreatePullRequest,
  64. Content: fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title),
  65. RepoID: pull.Issue.Repo.ID,
  66. Repo: pull.Issue.Repo,
  67. IsPrivate: pull.Issue.Repo.IsPrivate,
  68. }); err != nil {
  69. log.Error("NotifyWatchers: %v", err)
  70. }
  71. }
  72. func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) {
  73. log.Trace("action.ChangeRepositoryName: %s/%s", doer.Name, repo.Name)
  74. if err := models.NotifyWatchers(&models.Action{
  75. ActUserID: doer.ID,
  76. ActUser: doer,
  77. OpType: models.ActionRenameRepo,
  78. RepoID: repo.ID,
  79. Repo: repo,
  80. IsPrivate: repo.IsPrivate,
  81. Content: oldRepoName,
  82. }); err != nil {
  83. log.Error("NotifyWatchers: %v", err)
  84. }
  85. }
  86. func (a *actionNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) {
  87. if err := models.NotifyWatchers(&models.Action{
  88. ActUserID: doer.ID,
  89. ActUser: doer,
  90. OpType: models.ActionTransferRepo,
  91. RepoID: repo.ID,
  92. Repo: repo,
  93. IsPrivate: repo.IsPrivate,
  94. Content: path.Join(oldOwnerName, repo.Name),
  95. }); err != nil {
  96. log.Error("NotifyWatchers: %v", err)
  97. }
  98. }
  99. func (a *actionNotifier) NotifyCreateRepository(doer *models.User, u *models.User, repo *models.Repository) {
  100. if err := models.NotifyWatchers(&models.Action{
  101. ActUserID: doer.ID,
  102. ActUser: doer,
  103. OpType: models.ActionCreateRepo,
  104. RepoID: repo.ID,
  105. Repo: repo,
  106. IsPrivate: repo.IsPrivate,
  107. }); err != nil {
  108. log.Error("notify watchers '%d/%d': %v", doer.ID, repo.ID, err)
  109. }
  110. }
  111. func (a *actionNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
  112. if err := models.NotifyWatchers(&models.Action{
  113. ActUserID: doer.ID,
  114. ActUser: doer,
  115. OpType: models.ActionCreateRepo,
  116. RepoID: repo.ID,
  117. Repo: repo,
  118. IsPrivate: repo.IsPrivate,
  119. }); err != nil {
  120. log.Error("notify watchers '%d/%d': %v", doer.ID, repo.ID, err)
  121. }
  122. }
  123. func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment) {
  124. if err := review.LoadReviewer(); err != nil {
  125. log.Error("LoadReviewer '%d/%d': %v", review.ID, review.ReviewerID, err)
  126. return
  127. }
  128. if err := review.LoadCodeComments(); err != nil {
  129. log.Error("LoadCodeComments '%d/%d': %v", review.Reviewer.ID, review.ID, err)
  130. return
  131. }
  132. var actions = make([]*models.Action, 0, 10)
  133. for _, lines := range review.CodeComments {
  134. for _, comments := range lines {
  135. for _, comm := range comments {
  136. actions = append(actions, &models.Action{
  137. ActUserID: review.Reviewer.ID,
  138. ActUser: review.Reviewer,
  139. Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]),
  140. OpType: models.ActionCommentIssue,
  141. RepoID: review.Issue.RepoID,
  142. Repo: review.Issue.Repo,
  143. IsPrivate: review.Issue.Repo.IsPrivate,
  144. Comment: comm,
  145. CommentID: comm.ID,
  146. })
  147. }
  148. }
  149. }
  150. if review.Type != models.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" {
  151. action := &models.Action{
  152. ActUserID: review.Reviewer.ID,
  153. ActUser: review.Reviewer,
  154. Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]),
  155. RepoID: review.Issue.RepoID,
  156. Repo: review.Issue.Repo,
  157. IsPrivate: review.Issue.Repo.IsPrivate,
  158. Comment: comment,
  159. CommentID: comment.ID,
  160. }
  161. switch review.Type {
  162. case models.ReviewTypeApprove:
  163. action.OpType = models.ActionApprovePullRequest
  164. case models.ReviewTypeReject:
  165. action.OpType = models.ActionRejectPullRequest
  166. default:
  167. action.OpType = models.ActionCommentIssue
  168. }
  169. actions = append(actions, action)
  170. }
  171. if err := models.NotifyWatchersActions(actions); err != nil {
  172. log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err)
  173. }
  174. }
  175. func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *models.User, baseRepo *git.Repository) {
  176. if err := models.NotifyWatchers(&models.Action{
  177. ActUserID: doer.ID,
  178. ActUser: doer,
  179. OpType: models.ActionMergePullRequest,
  180. Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title),
  181. RepoID: pr.Issue.Repo.ID,
  182. Repo: pr.Issue.Repo,
  183. IsPrivate: pr.Issue.Repo.IsPrivate,
  184. }); err != nil {
  185. log.Error("NotifyWatchers [%d]: %v", pr.ID, err)
  186. }
  187. }
  188. func (a *actionNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
  189. data, err := json.Marshal(commits)
  190. if err != nil {
  191. log.Error("json.Marshal: %v", err)
  192. return
  193. }
  194. if err := models.NotifyWatchers(&models.Action{
  195. ActUserID: repo.OwnerID,
  196. ActUser: repo.MustOwner(),
  197. OpType: models.ActionMirrorSyncPush,
  198. RepoID: repo.ID,
  199. Repo: repo,
  200. IsPrivate: repo.IsPrivate,
  201. RefName: refName,
  202. Content: string(data),
  203. }); err != nil {
  204. log.Error("notifyWatchers: %v", err)
  205. }
  206. }
  207. func (a *actionNotifier) NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
  208. if err := models.NotifyWatchers(&models.Action{
  209. ActUserID: repo.OwnerID,
  210. ActUser: repo.MustOwner(),
  211. OpType: models.ActionMirrorSyncCreate,
  212. RepoID: repo.ID,
  213. Repo: repo,
  214. IsPrivate: repo.IsPrivate,
  215. RefName: refFullName,
  216. }); err != nil {
  217. log.Error("notifyWatchers: %v", err)
  218. }
  219. }
  220. func (a *actionNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
  221. if err := models.NotifyWatchers(&models.Action{
  222. ActUserID: repo.OwnerID,
  223. ActUser: repo.MustOwner(),
  224. OpType: models.ActionMirrorSyncCreate,
  225. RepoID: repo.ID,
  226. Repo: repo,
  227. IsPrivate: repo.IsPrivate,
  228. RefName: refFullName,
  229. }); err != nil {
  230. log.Error("notifyWatchers: %v", err)
  231. }
  232. }