Browse Source

More Issue-Comments API-endpoints (#3624)

* ListAllInRepo & Delete Issue-Comments

* Moar data in issue-comments
Kim "BKC" Carlbäcker 8 years ago
parent
commit
b2de3d71c5
3 changed files with 109 additions and 7 deletions
  1. 58 6
      models/issue_comment.go
  2. 6 1
      routers/api/v1/api.go
  3. 45 0
      routers/api/v1/repo/issue_comment.go

+ 58 - 6
models/issue_comment.go

@@ -115,13 +115,51 @@ func (c *Comment) AfterDelete() {
 	}
 }
 
+func (c *Comment) HTMLURL() string {
+	issue, err := GetIssueByID(c.IssueID)
+	if err != nil { // Silently dropping errors :unamused:
+		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
+		return ""
+	}
+	return fmt.Sprintf("%s#issuecomment-%d", issue.HTMLURL(), c.ID)
+}
+
+func (c *Comment) IssueURL() string {
+	issue, err := GetIssueByID(c.IssueID)
+	if err != nil { // Silently dropping errors :unamused:
+		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
+		return ""
+	}
+
+	if issue.IsPull {
+		return ""
+	}
+	return issue.HTMLURL()
+}
+
+func (c *Comment) PRURL() string {
+	issue, err := GetIssueByID(c.IssueID)
+	if err != nil { // Silently dropping errors :unamused:
+		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
+		return ""
+	}
+
+	if !issue.IsPull {
+		return ""
+	}
+	return issue.HTMLURL()
+}
+
 func (c *Comment) APIFormat() *api.Comment {
 	return &api.Comment{
-		ID:      c.ID,
-		Poster:  c.Poster.APIFormat(),
-		Body:    c.Content,
-		Created: c.Created,
-		Updated: c.Updated,
+		ID:       c.ID,
+		Poster:   c.Poster.APIFormat(),
+		HTMLURL:  c.HTMLURL(),
+		IssueURL: c.IssueURL(),
+		PRURL:    c.PRURL(),
+		Body:     c.Content,
+		Created:  c.Created,
+		Updated:  c.Updated,
 	}
 }
 
@@ -363,6 +401,15 @@ func getCommentsByIssueIDSince(e Engine, issueID, since int64) ([]*Comment, erro
 	return comments, sess.Find(&comments)
 }
 
+func getCommentsByRepoIDSince(e Engine, repoID, since int64) ([]*Comment, error) {
+	comments := make([]*Comment, 0, 10)
+	sess := e.Where("issue.repo_id = ?", repoID).Join("INNER", "issue", "issue.id = comment.issue_id", repoID).Asc("created_unix")
+	if since > 0 {
+		sess.And("updated_unix >= ?", since)
+	}
+	return comments, sess.Find(&comments)
+}
+
 func getCommentsByIssueID(e Engine, issueID int64) ([]*Comment, error) {
 	return getCommentsByIssueIDSince(e, issueID, -1)
 }
@@ -372,11 +419,16 @@ func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
 	return getCommentsByIssueID(x, issueID)
 }
 
-// GetCommentsByIssueID returns a list of comments of an issue since a given time point.
+// GetCommentsByIssueIDSince returns a list of comments of an issue since a given time point.
 func GetCommentsByIssueIDSince(issueID, since int64) ([]*Comment, error) {
 	return getCommentsByIssueIDSince(x, issueID, since)
 }
 
+// GetCommentsByRepoIDSince returns a list of comments for all issues in a repo since a given time point.
+func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
+	return getCommentsByRepoIDSince(x, repoID, since)
+}
+
 // UpdateComment updates information of comment.
 func UpdateComment(c *Comment) error {
 	_, err := x.Id(c.ID).AllCols().Update(c)

+ 6 - 1
routers/api/v1/api.go

@@ -259,12 +259,17 @@ func RegisterRoutes(m *macaron.Macaron) {
 				})
 				m.Group("/issues", func() {
 					m.Combo("").Get(repo.ListIssues).Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
+					m.Group("/comments", func() {
+						m.Get("", repo.ListRepoIssueComments)
+						m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
+					})
 					m.Group("/:index", func() {
 						m.Combo("").Get(repo.GetIssue).Patch(bind(api.EditIssueOption{}), repo.EditIssue)
 
 						m.Group("/comments", func() {
 							m.Combo("").Get(repo.ListIssueComments).Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
-							m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
+							m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
+								Delete(repo.DeleteIssueComment)
 						})
 
 						m.Group("/labels", func() {

+ 45 - 0
routers/api/v1/repo/issue_comment.go

@@ -38,6 +38,25 @@ func ListIssueComments(ctx *context.APIContext) {
 	ctx.JSON(200, &apiComments)
 }
 
+func ListRepoIssueComments(ctx *context.APIContext) {
+	var since time.Time
+	if len(ctx.Query("since")) > 0 {
+		since, _ = time.Parse(time.RFC3339, ctx.Query("since"))
+	}
+
+	comments, err := models.GetCommentsByRepoIDSince(ctx.Repo.Repository.ID, since.Unix())
+	if err != nil {
+		ctx.Error(500, "GetCommentsByRepoIDSince", err)
+		return
+	}
+
+	apiComments := make([]*api.Comment, len(comments))
+	for i := range comments {
+		apiComments[i] = comments[i].APIFormat()
+	}
+	ctx.JSON(200, &apiComments)
+}
+
 func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOption) {
 	issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
 	if err != nil {
@@ -80,3 +99,29 @@ func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
 	}
 	ctx.JSON(200, comment.APIFormat())
 }
+
+func DeleteIssueComment(ctx *context.APIContext) {
+	comment, err := models.GetCommentByID(ctx.ParamsInt64(":id"))
+	if err != nil {
+		if models.IsErrCommentNotExist(err) {
+			ctx.Error(404, "GetCommentByID", err)
+		} else {
+			ctx.Error(500, "GetCommentByID", err)
+		}
+		return
+	}
+
+	if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
+		ctx.Status(403)
+		return
+	} else if comment.Type != models.COMMENT_TYPE_COMMENT {
+		ctx.Status(204)
+		return
+	}
+
+	if err = models.DeleteCommentByID(comment.ID); err != nil {
+		ctx.Error(500, "DeleteCommentByID", err)
+		return
+	}
+	ctx.Status(204)
+}