diff options
author | blueworrybear <blueworrybear@gmail.com> | 2019-10-15 20:19:32 +0800 |
---|---|---|
committer | zeripath <art27@cantab.net> | 2019-10-15 13:19:32 +0100 |
commit | 8c909820a9fd1697bb690ec0451c4ead97b51505 (patch) | |
tree | bda76eca8361237fbd5bc59bda58b278a516ffd6 /routers | |
parent | d7d348ea86bd8066aeb079ad121120095d5cba4d (diff) | |
download | gitea-8c909820a9fd1697bb690ec0451c4ead97b51505.tar.gz gitea-8c909820a9fd1697bb690ec0451c4ead97b51505.zip |
Enable Uploading/Removing Attachments When Editing an Issue/Comment (#8426)
Diffstat (limited to 'routers')
-rw-r--r-- | routers/repo/attachment.go | 22 | ||||
-rw-r--r-- | routers/repo/issue.go | 110 | ||||
-rw-r--r-- | routers/routes/routes.go | 7 |
3 files changed, 135 insertions, 4 deletions
diff --git a/routers/repo/attachment.go b/routers/repo/attachment.go index a07a2a8ace..0d496230e1 100644 --- a/routers/repo/attachment.go +++ b/routers/repo/attachment.go @@ -63,3 +63,25 @@ func UploadAttachment(ctx *context.Context) { "uuid": attach.UUID, }) } + +// DeleteAttachment response for deleting issue's attachment +func DeleteAttachment(ctx *context.Context) { + file := ctx.Query("file") + attach, err := models.GetAttachmentByUUID(file) + if !ctx.IsSigned || (ctx.User.ID != attach.UploaderID) { + ctx.Error(403) + return + } + if err != nil { + ctx.Error(400, err.Error()) + return + } + err = models.DeleteAttachment(attach, true) + if err != nil { + ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) + return + } + ctx.JSON(200, map[string]string{ + "uuid": attach.UUID, + }) +} diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 16a049c7aa..dee2c6e698 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -34,6 +34,8 @@ import ( ) const ( + tplAttachment base.TplName = "repo/issue/view_content/attachments" + tplIssues base.TplName = "repo/issue/list" tplIssueNew base.TplName = "repo/issue/new" tplIssueView base.TplName = "repo/issue/view" @@ -1074,8 +1076,14 @@ func UpdateIssueContent(ctx *context.Context) { return } + files := ctx.QueryStrings("files[]") + if err := updateAttachments(issue, files); err != nil { + ctx.ServerError("UpdateAttachments", err) + } + ctx.JSON(200, map[string]interface{}{ - "content": string(markdown.Render([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())), + "content": string(markdown.Render([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())), + "attachments": attachmentsHTML(ctx, issue.Attachments), }) } @@ -1325,6 +1333,13 @@ func UpdateCommentContent(ctx *context.Context) { return } + if comment.Type == models.CommentTypeComment { + if err := comment.LoadAttachments(); err != nil { + ctx.ServerError("LoadAttachments", err) + return + } + } + if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Error(403) return @@ -1346,10 +1361,16 @@ func UpdateCommentContent(ctx *context.Context) { return } + files := ctx.QueryStrings("files[]") + if err := updateAttachments(comment, files); err != nil { + ctx.ServerError("UpdateAttachments", err) + } + notification.NotifyUpdateComment(ctx.User, comment, oldContent) ctx.JSON(200, map[string]interface{}{ - "content": string(markdown.Render([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())), + "content": string(markdown.Render([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())), + "attachments": attachmentsHTML(ctx, comment.Attachments), }) } @@ -1603,3 +1624,88 @@ func filterXRefComments(ctx *context.Context, issue *models.Issue) error { } return nil } + +// GetIssueAttachments returns attachments for the issue +func GetIssueAttachments(ctx *context.Context) { + issue := GetActionIssue(ctx) + var attachments = make([]*api.Attachment, len(issue.Attachments)) + for i := 0; i < len(issue.Attachments); i++ { + attachments[i] = issue.Attachments[i].APIFormat() + } + ctx.JSON(200, attachments) +} + +// GetCommentAttachments returns attachments for the comment +func GetCommentAttachments(ctx *context.Context) { + comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) + if err != nil { + ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + return + } + var attachments = make([]*api.Attachment, 0) + if comment.Type == models.CommentTypeComment { + if err := comment.LoadAttachments(); err != nil { + ctx.ServerError("LoadAttachments", err) + return + } + for i := 0; i < len(comment.Attachments); i++ { + attachments = append(attachments, comment.Attachments[i].APIFormat()) + } + } + ctx.JSON(200, attachments) +} + +func updateAttachments(item interface{}, files []string) error { + var attachments []*models.Attachment + switch content := item.(type) { + case *models.Issue: + attachments = content.Attachments + case *models.Comment: + attachments = content.Attachments + default: + return fmt.Errorf("Unknow Type") + } + for i := 0; i < len(attachments); i++ { + if util.IsStringInSlice(attachments[i].UUID, files) { + continue + } + if err := models.DeleteAttachment(attachments[i], true); err != nil { + return err + } + } + var err error + if len(files) > 0 { + switch content := item.(type) { + case *models.Issue: + err = content.UpdateAttachments(files) + case *models.Comment: + err = content.UpdateAttachments(files) + default: + return fmt.Errorf("Unknow Type") + } + if err != nil { + return err + } + } + switch content := item.(type) { + case *models.Issue: + content.Attachments, err = models.GetAttachmentsByIssueID(content.ID) + case *models.Comment: + content.Attachments, err = models.GetAttachmentsByCommentID(content.ID) + default: + return fmt.Errorf("Unknow Type") + } + return err +} + +func attachmentsHTML(ctx *context.Context, attachments []*models.Attachment) string { + attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{ + "ctx": ctx.Data, + "Attachments": attachments, + }) + if err != nil { + ctx.ServerError("attachmentsHTML.HTMLString", err) + return "" + } + return attachHTML +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 0db0af43f0..9572ea8039 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -513,8 +513,9 @@ func RegisterRoutes(m *macaron.Macaron) { }) }, ignSignIn) - m.Group("", func() { - m.Post("/attachments", repo.UploadAttachment) + m.Group("/attachments", func() { + m.Post("", repo.UploadAttachment) + m.Post("/delete", repo.DeleteAttachment) }, reqSignIn) m.Group("/:username", func() { @@ -710,6 +711,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction) m.Post("/lock", reqRepoIssueWriter, bindIgnErr(auth.IssueLockForm{}), repo.LockIssue) m.Post("/unlock", reqRepoIssueWriter, repo.UnlockIssue) + m.Get("/attachments", repo.GetIssueAttachments) }, context.RepoMustNotBeArchived()) m.Post("/labels", reqRepoIssuesOrPullsWriter, repo.UpdateIssueLabel) @@ -721,6 +723,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("", repo.UpdateCommentContent) m.Post("/delete", repo.DeleteComment) m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeCommentReaction) + m.Get("/attachments", repo.GetCommentAttachments) }, context.RepoMustNotBeArchived()) m.Group("/labels", func() { m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel) |