diff --git a/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala b/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala new file mode 100644 index 0000000..55d1fe9 --- /dev/null +++ b/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala @@ -0,0 +1,61 @@ +package gitbucket.core.api + +import gitbucket.core.util.RepositoryName +import gitbucket.core.model.CommitComment + +import java.util.Date + +/** + * https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent + */ +case class ApiPullRequestReviewComment( + id: Int, // 29724692 + // "diff_hunk": "@@ -1 +1 @@\n-# public-repo", + path: String, // "README.md", + // "position": 1, + // "original_position": 1, + commit_id: String, // "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + // "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + user: ApiUser, + body: String, // "Maybe you should use more emojji on this line.", + created_at: Date, // "2015-05-05T23:40:27Z", + updated_at: Date // "2015-05-05T23:40:27Z", +)(repositoryName:RepositoryName, issueId: Int) extends FieldSerializable { + // "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692", + val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/pulls/comments/${id}") + // "html_url": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692", + val html_url = ApiPath(s"/${repositoryName.fullName}/pull/${issueId}#discussion_r${id}") + // "pull_request_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + val pull_request_url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/pulls/${issueId}") + + /* + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692" + }, + "pull_request": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + } + } + */ + val _links = Map( + "self" -> Map("href" -> url), + "html" -> Map("href" -> html_url), + "pull_request" -> Map("href" -> pull_request_url)) +} + +object ApiPullRequestReviewComment{ + def apply(comment: CommitComment, commentedUser: ApiUser, repositoryName: RepositoryName, issueId: Int): ApiPullRequestReviewComment = + new ApiPullRequestReviewComment( + id = comment.commentId, + path = comment.fileName.getOrElse(""), + commit_id = comment.commitId, + user = commentedUser, + body = comment.content, + created_at = comment.registeredDate, + updated_at = comment.updatedDate + )(repositoryName, issueId) +} diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index 02a7850..9b9b752 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -32,7 +32,7 @@ class RepositoryViewerController extends RepositoryViewerControllerBase with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService - with WebHookPullRequestService + with WebHookPullRequestService with WebHookPullRequestReviewCommentService /** * The repository viewer. @@ -40,7 +40,7 @@ trait RepositoryViewerControllerBase extends ControllerBase { self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService - with WebHookPullRequestService => + with WebHookPullRequestService with WebHookPullRequestReviewCommentService => ArchiveCommand.registerFormat("zip", new ZipFormat) ArchiveCommand.registerFormat("tar.gz", new TgzFormat) @@ -396,12 +396,14 @@ val id = params("id") val commentId = createCommitComment(repository.owner, repository.name, id, context.loginAccount.get.userName, form.content, form.fileName, form.oldLineNumber, form.newLineNumber, form.issueId) + val comment = getCommitComment(repository.owner, repository.name, commentId.toString).get form.issueId match { - case Some(issueId) => recordCommentPullRequestActivity(repository.owner, repository.name, context.loginAccount.get.userName, issueId, form.content) + case Some(issueId) => + recordCommentPullRequestActivity(repository.owner, repository.name, context.loginAccount.get.userName, issueId, form.content) + callPullRequestReviewCommentWebHook("create", comment, repository, issueId, context.baseUrl, context.loginAccount.get) case None => recordCommentCommitActivity(repository.owner, repository.name, context.loginAccount.get.userName, id, form.content) } - helper.html.commitcomment(getCommitComment(repository.owner, repository.name, commentId.toString).get, - hasWritePermission(repository.owner, repository.name, context.loginAccount), repository) + helper.html.commitcomment(comment, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository) }) ajaxGet("/:owner/:repository/commit_comments/_data/:id")(readableUsersOnly { repository => diff --git a/src/main/scala/gitbucket/core/service/WebHookService.scala b/src/main/scala/gitbucket/core/service/WebHookService.scala index c168395..53d0abe 100644 --- a/src/main/scala/gitbucket/core/service/WebHookService.scala +++ b/src/main/scala/gitbucket/core/service/WebHookService.scala @@ -1,7 +1,7 @@ package gitbucket.core.service import gitbucket.core.api._ -import gitbucket.core.model.{WebHook, Account, Issue, PullRequest, IssueComment, WebHookEvent} +import gitbucket.core.model.{WebHook, Account, Issue, PullRequest, IssueComment, WebHookEvent, CommitComment} import gitbucket.core.model.Profile._ import profile.simple._ import gitbucket.core.util.JGitUtil.CommitInfo @@ -212,6 +212,35 @@ } } +trait WebHookPullRequestReviewCommentService extends WebHookService { + self: AccountService with RepositoryService with PullRequestService with IssuesService with CommitsService => + def callPullRequestReviewCommentWebHook(action: String, comment: CommitComment, repository: RepositoryService.RepositoryInfo, issueId: Int, baseUrl: String, sender: Account)(implicit s: Session, context:JsonFormat.Context): Unit = { + import WebHookService._ + callWebHookOf(repository.owner, repository.name, WebHook.PullRequestReviewComment){ + for{ + (issue, pullRequest) <- getPullRequest(repository.owner, repository.name, issueId) + users = getAccountsByUserNames(Set(repository.owner, pullRequest.requestUserName, issue.openedUserName), Set(sender)) + baseOwner <- users.get(repository.owner) + headOwner <- users.get(pullRequest.requestUserName) + issueUser <- users.get(issue.openedUserName) + headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName, baseUrl) + } yield { + WebHookPullRequestReviewCommentPayload( + action = action, + comment = comment, + issue = issue, + issueUser = issueUser, + pullRequest = pullRequest, + headRepository = headRepo, + headOwner = headOwner, + baseRepository = repository, + baseOwner = baseOwner, + sender = sender) + } + } + } +} + trait WebHookIssueCommentService extends WebHookPullRequestService { self: AccountService with RepositoryService with PullRequestService with IssuesService => @@ -341,4 +370,38 @@ comment = ApiComment(comment, RepositoryName(repository), issue.issueId, ApiUser(commentUser), issue.isPullRequest), sender = ApiUser(sender)) } + + // https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent + case class WebHookPullRequestReviewCommentPayload( + action: String, + comment: ApiPullRequestReviewComment, + pull_request: ApiPullRequest, + repository: ApiRepository, + sender: ApiUser + ) extends WebHookPayload + + object WebHookPullRequestReviewCommentPayload{ + def apply( + action: String, + comment: CommitComment, + issue: Issue, + issueUser: Account, + pullRequest: PullRequest, + headRepository: RepositoryInfo, + headOwner: Account, + baseRepository: RepositoryInfo, + baseOwner: Account, + sender: Account + ) : WebHookPullRequestReviewCommentPayload = { + val headRepoPayload = ApiRepository(headRepository, headOwner) + val baseRepoPayload = ApiRepository(baseRepository, baseOwner) + val senderPayload = ApiUser(sender) + WebHookPullRequestReviewCommentPayload( + action = action, + comment = ApiPullRequestReviewComment(comment, senderPayload, RepositoryName(baseRepository), issue.issueId), + pull_request = ApiPullRequest(issue, pullRequest, headRepoPayload, baseRepoPayload, ApiUser(issueUser)), + repository = baseRepoPayload, + sender = senderPayload) + } + } } diff --git a/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html b/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html index f7d27ff..984a62f 100644 --- a/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html +++ b/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html @@ -6,6 +6,7 @@ @import gitbucket.core._ @import gitbucket.core.view.helpers._
@if(!create){ diff --git a/src/test/scala/gitbucket/core/api/JsonFormatSpec.scala b/src/test/scala/gitbucket/core/api/JsonFormatSpec.scala index fe317ce..8b3c351 100644 --- a/src/test/scala/gitbucket/core/api/JsonFormatSpec.scala +++ b/src/test/scala/gitbucket/core/api/JsonFormatSpec.scala @@ -7,7 +7,7 @@ import org.json4s._ import org.specs2.matcher._ -import java.util.{Calendar, TimeZone} +import java.util.{Calendar, TimeZone, Date} @@ -17,6 +17,11 @@ d.set(2011,3,14,16,0,49) d.getTime } + def date(date:String): Date = { + val f = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + f.setTimeZone(TimeZone.getTimeZone("UTC")) + f.parse(date) + } val sha1 = "6dcb09b5b57875f334f61aebed695e2e4193db5e" val repo1Name = RepositoryName("octocat/Hello-World") implicit val context = JsonFormat.Context("http://gitbucket.exmple.com") @@ -305,6 +310,51 @@ // "deletions": 3, // "changed_files": 5 }""" + + // https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent + val apiPullRequestReviewComment = ApiPullRequestReviewComment( + id = 29724692, + // "diff_hunk": "@@ -1 +1 @@\n-# public-repo", + path = "README.md", + // "position": 1, + // "original_position": 1, + commit_id = "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + // "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + user = apiUser, + body = "Maybe you should use more emojji on this line.", + created_at = date("2015-05-05T23:40:27Z"), + updated_at = date("2015-05-05T23:40:27Z") + )(RepositoryName("baxterthehacker/public-repo"), 1) + val apiPullRequestReviewCommentJson = s"""{ + "url": "http://gitbucket.exmple.com/api/v3/repos/baxterthehacker/public-repo/pulls/comments/29724692", + "id": 29724692, + // "diff_hunk": "@@ -1 +1 @@\\n-# public-repo", + "path": "README.md", + // "position": 1, + // "original_position": 1, + "commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + // "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": $apiUserJson, + "body": "Maybe you should use more emojji on this line.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "html_url": "http://gitbucket.exmple.com/baxterthehacker/public-repo/pull/1#discussion_r29724692", + "pull_request_url": "http://gitbucket.exmple.com/api/v3/repos/baxterthehacker/public-repo/pulls/1", + "_links": { + "self": { + "href": "http://gitbucket.exmple.com/api/v3/repos/baxterthehacker/public-repo/pulls/comments/29724692" + }, + "html": { + "href": "http://gitbucket.exmple.com/baxterthehacker/public-repo/pull/1#discussion_r29724692" + }, + "pull_request": { + "href": "http://gitbucket.exmple.com/api/v3/repos/baxterthehacker/public-repo/pulls/1" + } + } + }""" + + + def beFormatted(json2Arg:String) = new Matcher[String] { def apply[S <: String](e: Expectable[S]) = { import java.util.regex.Pattern @@ -358,5 +408,8 @@ "apiPullRequest" in { JsonFormat(apiPullRequest) must beFormatted(apiPullRequestJson) } + "apiPullRequestReviewComment" in { + JsonFormat(apiPullRequestReviewComment) must beFormatted(apiPullRequestReviewCommentJson) + } } }