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.

issue_comment.go 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. // Copyright 2015 The Gogs 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 repo
  5. import (
  6. "time"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/notification"
  10. api "code.gitea.io/sdk/gitea"
  11. )
  12. // ListIssueComments list all the comments of an issue
  13. func ListIssueComments(ctx *context.APIContext) {
  14. // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/comments issue issueGetComments
  15. // ---
  16. // summary: List all comments on an issue
  17. // produces:
  18. // - application/json
  19. // parameters:
  20. // - name: owner
  21. // in: path
  22. // description: owner of the repo
  23. // type: string
  24. // required: true
  25. // - name: repo
  26. // in: path
  27. // description: name of the repo
  28. // type: string
  29. // required: true
  30. // - name: index
  31. // in: path
  32. // description: index of the issue
  33. // type: integer
  34. // format: int64
  35. // required: true
  36. // - name: since
  37. // in: query
  38. // description: if provided, only comments updated since the specified time are returned.
  39. // type: string
  40. // responses:
  41. // "200":
  42. // "$ref": "#/responses/CommentList"
  43. var since time.Time
  44. if len(ctx.Query("since")) > 0 {
  45. since, _ = time.Parse(time.RFC3339, ctx.Query("since"))
  46. }
  47. // comments,err:=models.GetCommentsByIssueIDSince(, since)
  48. issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
  49. if err != nil {
  50. ctx.Error(500, "GetRawIssueByIndex", err)
  51. return
  52. }
  53. comments, err := models.FindComments(models.FindCommentsOptions{
  54. IssueID: issue.ID,
  55. Since: since.Unix(),
  56. Type: models.CommentTypeComment,
  57. })
  58. if err != nil {
  59. ctx.Error(500, "GetCommentsByIssueIDSince", err)
  60. return
  61. }
  62. apiComments := make([]*api.Comment, len(comments))
  63. if err = models.CommentList(comments).LoadPosters(); err != nil {
  64. ctx.Error(500, "LoadPosters", err)
  65. return
  66. }
  67. for i := range comments {
  68. apiComments[i] = comments[i].APIFormat()
  69. }
  70. ctx.JSON(200, &apiComments)
  71. }
  72. // ListRepoIssueComments returns all issue-comments for a repo
  73. func ListRepoIssueComments(ctx *context.APIContext) {
  74. // swagger:operation GET /repos/{owner}/{repo}/issues/comments issue issueGetRepoComments
  75. // ---
  76. // summary: List all comments in a repository
  77. // produces:
  78. // - application/json
  79. // parameters:
  80. // - name: owner
  81. // in: path
  82. // description: owner of the repo
  83. // type: string
  84. // required: true
  85. // - name: repo
  86. // in: path
  87. // description: name of the repo
  88. // type: string
  89. // required: true
  90. // - name: since
  91. // in: query
  92. // description: if provided, only comments updated since the provided time are returned.
  93. // type: string
  94. // responses:
  95. // "200":
  96. // "$ref": "#/responses/CommentList"
  97. var since time.Time
  98. if len(ctx.Query("since")) > 0 {
  99. since, _ = time.Parse(time.RFC3339, ctx.Query("since"))
  100. }
  101. comments, err := models.FindComments(models.FindCommentsOptions{
  102. RepoID: ctx.Repo.Repository.ID,
  103. Since: since.Unix(),
  104. Type: models.CommentTypeComment,
  105. })
  106. if err != nil {
  107. ctx.Error(500, "GetCommentsByRepoIDSince", err)
  108. return
  109. }
  110. if err = models.CommentList(comments).LoadPosters(); err != nil {
  111. ctx.Error(500, "LoadPosters", err)
  112. return
  113. }
  114. apiComments := make([]*api.Comment, len(comments))
  115. for i := range comments {
  116. apiComments[i] = comments[i].APIFormat()
  117. }
  118. ctx.JSON(200, &apiComments)
  119. }
  120. // CreateIssueComment create a comment for an issue
  121. func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOption) {
  122. // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/comments issue issueCreateComment
  123. // ---
  124. // summary: Add a comment to an issue
  125. // consumes:
  126. // - application/json
  127. // produces:
  128. // - application/json
  129. // parameters:
  130. // - name: owner
  131. // in: path
  132. // description: owner of the repo
  133. // type: string
  134. // required: true
  135. // - name: repo
  136. // in: path
  137. // description: name of the repo
  138. // type: string
  139. // required: true
  140. // - name: index
  141. // in: path
  142. // description: index of the issue
  143. // type: integer
  144. // format: int64
  145. // required: true
  146. // - name: body
  147. // in: body
  148. // schema:
  149. // "$ref": "#/definitions/CreateIssueCommentOption"
  150. // responses:
  151. // "201":
  152. // "$ref": "#/responses/Comment"
  153. issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
  154. if err != nil {
  155. ctx.Error(500, "GetIssueByIndex", err)
  156. return
  157. }
  158. comment, err := models.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Body, nil)
  159. if err != nil {
  160. ctx.Error(500, "CreateIssueComment", err)
  161. return
  162. }
  163. notification.NotifyCreateIssueComment(ctx.User, ctx.Repo.Repository, issue, comment)
  164. ctx.JSON(201, comment.APIFormat())
  165. }
  166. // EditIssueComment modify a comment of an issue
  167. func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) {
  168. // swagger:operation PATCH /repos/{owner}/{repo}/issues/comments/{id} issue issueEditComment
  169. // ---
  170. // summary: Edit a comment
  171. // consumes:
  172. // - application/json
  173. // produces:
  174. // - application/json
  175. // parameters:
  176. // - name: owner
  177. // in: path
  178. // description: owner of the repo
  179. // type: string
  180. // required: true
  181. // - name: repo
  182. // in: path
  183. // description: name of the repo
  184. // type: string
  185. // required: true
  186. // - name: id
  187. // in: path
  188. // description: id of the comment to edit
  189. // type: integer
  190. // format: int64
  191. // required: true
  192. // - name: body
  193. // in: body
  194. // schema:
  195. // "$ref": "#/definitions/EditIssueCommentOption"
  196. // responses:
  197. // "200":
  198. // "$ref": "#/responses/Comment"
  199. editIssueComment(ctx, form)
  200. }
  201. // EditIssueCommentDeprecated modify a comment of an issue
  202. func EditIssueCommentDeprecated(ctx *context.APIContext, form api.EditIssueCommentOption) {
  203. // swagger:operation PATCH /repos/{owner}/{repo}/issues/{index}/comments/{id} issue issueEditCommentDeprecated
  204. // ---
  205. // summary: Edit a comment
  206. // deprecated: true
  207. // consumes:
  208. // - application/json
  209. // produces:
  210. // - application/json
  211. // parameters:
  212. // - name: owner
  213. // in: path
  214. // description: owner of the repo
  215. // type: string
  216. // required: true
  217. // - name: repo
  218. // in: path
  219. // description: name of the repo
  220. // type: string
  221. // required: true
  222. // - name: index
  223. // in: path
  224. // description: this parameter is ignored
  225. // type: integer
  226. // required: true
  227. // - name: id
  228. // in: path
  229. // description: id of the comment to edit
  230. // type: integer
  231. // format: int64
  232. // required: true
  233. // - name: body
  234. // in: body
  235. // schema:
  236. // "$ref": "#/definitions/EditIssueCommentOption"
  237. // responses:
  238. // "200":
  239. // "$ref": "#/responses/Comment"
  240. editIssueComment(ctx, form)
  241. }
  242. func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) {
  243. comment, err := models.GetCommentByID(ctx.ParamsInt64(":id"))
  244. if err != nil {
  245. if models.IsErrCommentNotExist(err) {
  246. ctx.Error(404, "GetCommentByID", err)
  247. } else {
  248. ctx.Error(500, "GetCommentByID", err)
  249. }
  250. return
  251. }
  252. if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
  253. ctx.Status(403)
  254. return
  255. } else if comment.Type != models.CommentTypeComment {
  256. ctx.Status(204)
  257. return
  258. }
  259. oldContent := comment.Content
  260. comment.Content = form.Body
  261. if err := models.UpdateComment(ctx.User, comment, oldContent); err != nil {
  262. ctx.Error(500, "UpdateComment", err)
  263. return
  264. }
  265. ctx.JSON(200, comment.APIFormat())
  266. }
  267. // DeleteIssueComment delete a comment from an issue
  268. func DeleteIssueComment(ctx *context.APIContext) {
  269. // swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id} issue issueDeleteComment
  270. // ---
  271. // summary: Delete a comment
  272. // parameters:
  273. // - name: owner
  274. // in: path
  275. // description: owner of the repo
  276. // type: string
  277. // required: true
  278. // - name: repo
  279. // in: path
  280. // description: name of the repo
  281. // type: string
  282. // required: true
  283. // - name: id
  284. // in: path
  285. // description: id of comment to delete
  286. // type: integer
  287. // format: int64
  288. // required: true
  289. // responses:
  290. // "204":
  291. // "$ref": "#/responses/empty"
  292. deleteIssueComment(ctx)
  293. }
  294. // DeleteIssueCommentDeprecated delete a comment from an issue
  295. func DeleteIssueCommentDeprecated(ctx *context.APIContext) {
  296. // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/comments/{id} issue issueDeleteCommentDeprecated
  297. // ---
  298. // summary: Delete a comment
  299. // deprecated: true
  300. // parameters:
  301. // - name: owner
  302. // in: path
  303. // description: owner of the repo
  304. // type: string
  305. // required: true
  306. // - name: repo
  307. // in: path
  308. // description: name of the repo
  309. // type: string
  310. // required: true
  311. // - name: index
  312. // in: path
  313. // description: this parameter is ignored
  314. // type: integer
  315. // required: true
  316. // - name: id
  317. // in: path
  318. // description: id of comment to delete
  319. // type: integer
  320. // format: int64
  321. // required: true
  322. // responses:
  323. // "204":
  324. // "$ref": "#/responses/empty"
  325. deleteIssueComment(ctx)
  326. }
  327. func deleteIssueComment(ctx *context.APIContext) {
  328. comment, err := models.GetCommentByID(ctx.ParamsInt64(":id"))
  329. if err != nil {
  330. if models.IsErrCommentNotExist(err) {
  331. ctx.Error(404, "GetCommentByID", err)
  332. } else {
  333. ctx.Error(500, "GetCommentByID", err)
  334. }
  335. return
  336. }
  337. if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
  338. ctx.Status(403)
  339. return
  340. } else if comment.Type != models.CommentTypeComment {
  341. ctx.Status(204)
  342. return
  343. }
  344. if err = models.DeleteComment(ctx.User, comment); err != nil {
  345. ctx.Error(500, "DeleteCommentByID", err)
  346. return
  347. }
  348. ctx.Status(204)
  349. }