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

convert.go 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright 2021 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 feed
  5. import (
  6. "fmt"
  7. "html"
  8. "net/url"
  9. "strconv"
  10. "strings"
  11. "code.gitea.io/gitea/models"
  12. "code.gitea.io/gitea/modules/context"
  13. "code.gitea.io/gitea/modules/setting"
  14. "code.gitea.io/gitea/modules/templates"
  15. "code.gitea.io/gitea/modules/util"
  16. "github.com/gorilla/feeds"
  17. )
  18. func toBranchLink(act *models.Action) string {
  19. return act.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(act.GetBranch())
  20. }
  21. func toTagLink(act *models.Action) string {
  22. return act.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(act.GetTag())
  23. }
  24. func toIssueLink(act *models.Action) string {
  25. return act.GetRepoLink() + "/issues/" + url.PathEscape(act.GetIssueInfos()[0])
  26. }
  27. func toPullLink(act *models.Action) string {
  28. return act.GetRepoLink() + "/pulls/" + url.PathEscape(act.GetIssueInfos()[0])
  29. }
  30. func toSrcLink(act *models.Action) string {
  31. return act.GetRepoLink() + "/src/" + util.PathEscapeSegments(act.GetBranch())
  32. }
  33. func toReleaseLink(act *models.Action) string {
  34. return act.GetRepoLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch())
  35. }
  36. // feedActionsToFeedItems convert gitea's Action feed to feeds Item
  37. func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (items []*feeds.Item, err error) {
  38. for _, act := range actions {
  39. act.LoadActUser()
  40. content, desc, title := "", "", ""
  41. link := &feeds.Link{Href: act.GetCommentLink()}
  42. // title
  43. title = act.ActUser.DisplayName() + " "
  44. switch act.OpType {
  45. case models.ActionCreateRepo:
  46. title += ctx.TrHTMLEscapeArgs("action.create_repo", act.GetRepoLink(), act.ShortRepoPath())
  47. link.Href = act.GetRepoLink()
  48. case models.ActionRenameRepo:
  49. title += ctx.TrHTMLEscapeArgs("action.rename_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
  50. link.Href = act.GetRepoLink()
  51. case models.ActionCommitRepo:
  52. link.Href = toBranchLink(act)
  53. if len(act.Content) != 0 {
  54. title += ctx.TrHTMLEscapeArgs("action.commit_repo", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
  55. } else {
  56. title += ctx.TrHTMLEscapeArgs("action.create_branch", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
  57. }
  58. case models.ActionCreateIssue:
  59. link.Href = toIssueLink(act)
  60. title += ctx.TrHTMLEscapeArgs("action.create_issue", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath())
  61. case models.ActionCreatePullRequest:
  62. link.Href = toPullLink(act)
  63. title += ctx.TrHTMLEscapeArgs("action.create_pull_request", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath())
  64. case models.ActionTransferRepo:
  65. link.Href = act.GetRepoLink()
  66. title += ctx.TrHTMLEscapeArgs("action.transfer_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
  67. case models.ActionPushTag:
  68. link.Href = toTagLink(act)
  69. title += ctx.TrHTMLEscapeArgs("action.push_tag", act.GetRepoLink(), link.Href, act.GetTag(), act.ShortRepoPath())
  70. case models.ActionCommentIssue:
  71. issueLink := toIssueLink(act)
  72. if link.Href == "#" {
  73. link.Href = issueLink
  74. }
  75. title += ctx.TrHTMLEscapeArgs("action.comment_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  76. case models.ActionMergePullRequest:
  77. pullLink := toPullLink(act)
  78. if link.Href == "#" {
  79. link.Href = pullLink
  80. }
  81. title += ctx.TrHTMLEscapeArgs("action.merge_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  82. case models.ActionCloseIssue:
  83. issueLink := toIssueLink(act)
  84. if link.Href == "#" {
  85. link.Href = issueLink
  86. }
  87. title += ctx.TrHTMLEscapeArgs("action.close_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  88. case models.ActionReopenIssue:
  89. issueLink := toIssueLink(act)
  90. if link.Href == "#" {
  91. link.Href = issueLink
  92. }
  93. title += ctx.TrHTMLEscapeArgs("action.reopen_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  94. case models.ActionClosePullRequest:
  95. pullLink := toPullLink(act)
  96. if link.Href == "#" {
  97. link.Href = pullLink
  98. }
  99. title += ctx.TrHTMLEscapeArgs("action.close_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  100. case models.ActionReopenPullRequest:
  101. pullLink := toPullLink(act)
  102. if link.Href == "#" {
  103. link.Href = pullLink
  104. }
  105. title += ctx.TrHTMLEscapeArgs("action.reopen_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  106. case models.ActionDeleteTag:
  107. link.Href = act.GetRepoLink()
  108. title += ctx.TrHTMLEscapeArgs("action.delete_tag", act.GetRepoLink(), act.GetTag(), act.ShortRepoPath())
  109. case models.ActionDeleteBranch:
  110. link.Href = act.GetRepoLink()
  111. title += ctx.TrHTMLEscapeArgs("action.delete_branch", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
  112. case models.ActionMirrorSyncPush:
  113. srcLink := toSrcLink(act)
  114. if link.Href == "#" {
  115. link.Href = srcLink
  116. }
  117. title += ctx.TrHTMLEscapeArgs("action.mirror_sync_push", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
  118. case models.ActionMirrorSyncCreate:
  119. srcLink := toSrcLink(act)
  120. if link.Href == "#" {
  121. link.Href = srcLink
  122. }
  123. title += ctx.TrHTMLEscapeArgs("action.mirror_sync_create", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
  124. case models.ActionMirrorSyncDelete:
  125. link.Href = act.GetRepoLink()
  126. title += ctx.TrHTMLEscapeArgs("action.mirror_sync_delete", act.GetRepoLink(), act.GetBranch(), act.ShortRepoPath())
  127. case models.ActionApprovePullRequest:
  128. pullLink := toPullLink(act)
  129. title += ctx.TrHTMLEscapeArgs("action.approve_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  130. case models.ActionRejectPullRequest:
  131. pullLink := toPullLink(act)
  132. title += ctx.TrHTMLEscapeArgs("action.reject_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  133. case models.ActionCommentPull:
  134. pullLink := toPullLink(act)
  135. title += ctx.TrHTMLEscapeArgs("action.comment_pull", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
  136. case models.ActionPublishRelease:
  137. releaseLink := toReleaseLink(act)
  138. if link.Href == "#" {
  139. link.Href = releaseLink
  140. }
  141. title += ctx.TrHTMLEscapeArgs("action.publish_release", act.GetRepoLink(), releaseLink, act.ShortRepoPath(), act.Content)
  142. case models.ActionPullReviewDismissed:
  143. pullLink := toPullLink(act)
  144. title += ctx.TrHTMLEscapeArgs("action.review_dismissed", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath(), act.GetIssueInfos()[1])
  145. case models.ActionStarRepo:
  146. link.Href = act.GetRepoLink()
  147. title += ctx.TrHTMLEscapeArgs("action.starred_repo", act.GetRepoLink(), act.GetRepoPath())
  148. case models.ActionWatchRepo:
  149. link.Href = act.GetRepoLink()
  150. title += ctx.TrHTMLEscapeArgs("action.watched_repo", act.GetRepoLink(), act.GetRepoPath())
  151. default:
  152. return nil, fmt.Errorf("unknown action type: %v", act.OpType)
  153. }
  154. // description & content
  155. {
  156. switch act.OpType {
  157. case models.ActionCommitRepo, models.ActionMirrorSyncPush:
  158. push := templates.ActionContent2Commits(act)
  159. repoLink := act.GetRepoLink()
  160. for _, commit := range push.Commits {
  161. if len(desc) != 0 {
  162. desc += "\n\n"
  163. }
  164. desc += fmt.Sprintf("<a href=\"%s\">%s</a>\n%s",
  165. html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), commit.Sha1)),
  166. commit.Sha1,
  167. templates.RenderCommitMessage(commit.Message, repoLink, nil),
  168. )
  169. }
  170. if push.Len > 1 {
  171. link = &feeds.Link{Href: fmt.Sprintf("%s/%s", setting.AppSubURL, push.CompareURL)}
  172. } else if push.Len == 1 {
  173. link = &feeds.Link{Href: fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), push.Commits[0].Sha1)}
  174. }
  175. case models.ActionCreateIssue, models.ActionCreatePullRequest:
  176. desc = strings.Join(act.GetIssueInfos(), "#")
  177. content = act.GetIssueContent()
  178. case models.ActionCommentIssue, models.ActionApprovePullRequest, models.ActionRejectPullRequest, models.ActionCommentPull:
  179. desc = act.GetIssueTitle()
  180. comment := act.GetIssueInfos()[1]
  181. if len(comment) != 0 {
  182. desc += "\n\n" + comment
  183. }
  184. case models.ActionMergePullRequest:
  185. desc = act.GetIssueInfos()[1]
  186. case models.ActionCloseIssue, models.ActionReopenIssue, models.ActionClosePullRequest, models.ActionReopenPullRequest:
  187. desc = act.GetIssueTitle()
  188. case models.ActionPullReviewDismissed:
  189. desc = ctx.Tr("action.review_dismissed_reason") + "\n\n" + act.GetIssueInfos()[2]
  190. }
  191. }
  192. if len(content) == 0 {
  193. content = desc
  194. }
  195. items = append(items, &feeds.Item{
  196. Title: title,
  197. Link: link,
  198. Description: desc,
  199. Author: &feeds.Author{
  200. Name: act.ActUser.DisplayName(),
  201. Email: act.ActUser.GetEmail(),
  202. },
  203. Id: strconv.FormatInt(act.ID, 10),
  204. Created: act.CreatedUnix.AsTime(),
  205. Content: content,
  206. })
  207. }
  208. return
  209. }