|
|
@ -7,11 +7,8 @@ package repo |
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"errors" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"io" |
|
|
|
|
|
|
|
"io/ioutil" |
|
|
|
|
|
|
|
"net/http" |
|
|
|
"net/http" |
|
|
|
"net/url" |
|
|
|
"net/url" |
|
|
|
"os" |
|
|
|
|
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
@ -181,6 +178,7 @@ func NewIssue(ctx *middleware.Context) { |
|
|
|
ctx.Data["RequireDropzone"] = true |
|
|
|
ctx.Data["RequireDropzone"] = true |
|
|
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled |
|
|
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled |
|
|
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes |
|
|
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes |
|
|
|
|
|
|
|
ctx.Data["AttachmentMaxFiles"] = setting.AttachmentMaxFiles |
|
|
|
|
|
|
|
|
|
|
|
if ctx.User.IsAdmin { |
|
|
|
if ctx.User.IsAdmin { |
|
|
|
var ( |
|
|
|
var ( |
|
|
@ -215,18 +213,19 @@ func NewIssue(ctx *middleware.Context) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { |
|
|
|
func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { |
|
|
|
fmt.Println(ctx.QueryStrings("uuids")) |
|
|
|
|
|
|
|
ctx.Data["Title"] = ctx.Tr("repo.issues.new") |
|
|
|
ctx.Data["Title"] = ctx.Tr("repo.issues.new") |
|
|
|
ctx.Data["PageIsIssueList"] = true |
|
|
|
ctx.Data["PageIsIssueList"] = true |
|
|
|
ctx.Data["RequireDropzone"] = true |
|
|
|
ctx.Data["RequireDropzone"] = true |
|
|
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled |
|
|
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled |
|
|
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes |
|
|
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes |
|
|
|
|
|
|
|
ctx.Data["AttachmentMaxFiles"] = setting.AttachmentMaxFiles |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
|
repo = ctx.Repo.Repository |
|
|
|
repo = ctx.Repo.Repository |
|
|
|
labelIDs []int64 |
|
|
|
labelIDs []int64 |
|
|
|
milestoneID int64 |
|
|
|
milestoneID int64 |
|
|
|
assigneeID int64 |
|
|
|
assigneeID int64 |
|
|
|
|
|
|
|
attachments []string |
|
|
|
) |
|
|
|
) |
|
|
|
if ctx.User.IsAdmin { |
|
|
|
if ctx.User.IsAdmin { |
|
|
|
// Check labels.
|
|
|
|
// Check labels.
|
|
|
@ -286,6 +285,10 @@ func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if setting.AttachmentEnabled { |
|
|
|
|
|
|
|
attachments = ctx.QueryStrings("attachments") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ctx.HasError() { |
|
|
|
if ctx.HasError() { |
|
|
|
ctx.HTML(200, ISSUE_NEW) |
|
|
|
ctx.HTML(200, ISSUE_NEW) |
|
|
|
return |
|
|
|
return |
|
|
@ -301,7 +304,7 @@ func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { |
|
|
|
AssigneeID: assigneeID, |
|
|
|
AssigneeID: assigneeID, |
|
|
|
Content: form.Content, |
|
|
|
Content: form.Content, |
|
|
|
} |
|
|
|
} |
|
|
|
if err := models.NewIssue(repo, issue, labelIDs); err != nil { |
|
|
|
if err := models.NewIssue(repo, issue, labelIDs, attachments); err != nil { |
|
|
|
ctx.Handle(500, "NewIssue", err) |
|
|
|
ctx.Handle(500, "NewIssue", err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -347,9 +350,50 @@ func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { |
|
|
|
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index)) |
|
|
|
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func UploadAttachment(ctx *middleware.Context) { |
|
|
|
func UploadIssueAttachment(ctx *middleware.Context) { |
|
|
|
|
|
|
|
if !setting.AttachmentEnabled { |
|
|
|
|
|
|
|
ctx.Error(404, "attachment is not enabled") |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allowedTypes := strings.Split(setting.AttachmentAllowedTypes, ",") |
|
|
|
|
|
|
|
file, header, err := ctx.Req.FormFile("file") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Error(500, fmt.Sprintf("FormFile: %v", err)) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
defer file.Close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf := make([]byte, 1024) |
|
|
|
|
|
|
|
n, _ := file.Read(buf) |
|
|
|
|
|
|
|
if n > 0 { |
|
|
|
|
|
|
|
buf = buf[:n] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
fileType := http.DetectContentType(buf) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allowed := false |
|
|
|
|
|
|
|
for _, t := range allowedTypes { |
|
|
|
|
|
|
|
t := strings.Trim(t, " ") |
|
|
|
|
|
|
|
if t == "*/*" || t == fileType { |
|
|
|
|
|
|
|
allowed = true |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !allowed { |
|
|
|
|
|
|
|
ctx.Error(400, ErrFileTypeForbidden.Error()) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
attach, err := models.NewAttachment(header.Filename, buf, file) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Error(500, fmt.Sprintf("NewAttachment: %v", err)) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.Trace("New attachment uploaded: %s", attach.UUID) |
|
|
|
ctx.JSON(200, map[string]string{ |
|
|
|
ctx.JSON(200, map[string]string{ |
|
|
|
"uuid": "fuck", |
|
|
|
"uuid": attach.UUID, |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -687,78 +731,6 @@ func UpdateAssignee(ctx *middleware.Context) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func uploadFiles(ctx *middleware.Context, issueId, commentId int64) { |
|
|
|
|
|
|
|
if !setting.AttachmentEnabled { |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allowedTypes := strings.Split(setting.AttachmentAllowedTypes, "|") |
|
|
|
|
|
|
|
attachments := ctx.Req.MultipartForm.File["attachments"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(attachments) > setting.AttachmentMaxFiles { |
|
|
|
|
|
|
|
ctx.Handle(400, "issue.Comment", ErrTooManyFiles) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, header := range attachments { |
|
|
|
|
|
|
|
file, err := header.Open() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Handle(500, "issue.Comment(header.Open)", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defer file.Close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf := make([]byte, 1024) |
|
|
|
|
|
|
|
n, _ := file.Read(buf) |
|
|
|
|
|
|
|
if n > 0 { |
|
|
|
|
|
|
|
buf = buf[:n] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
fileType := http.DetectContentType(buf) |
|
|
|
|
|
|
|
fmt.Println(fileType) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allowed := false |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, t := range allowedTypes { |
|
|
|
|
|
|
|
t := strings.Trim(t, " ") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if t == "*/*" || t == fileType { |
|
|
|
|
|
|
|
allowed = true |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !allowed { |
|
|
|
|
|
|
|
ctx.Handle(400, "issue.Comment", ErrFileTypeForbidden) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
os.MkdirAll(setting.AttachmentPath, os.ModePerm) |
|
|
|
|
|
|
|
out, err := ioutil.TempFile(setting.AttachmentPath, "attachment_") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Handle(500, "ioutil.TempFile", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defer out.Close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out.Write(buf) |
|
|
|
|
|
|
|
_, err = io.Copy(out, file) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Handle(500, "io.Copy", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_, err = models.CreateAttachment(issueId, commentId, header.Filename, out.Name()) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Handle(500, "CreateAttachment", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func Comment(ctx *middleware.Context) { |
|
|
|
func Comment(ctx *middleware.Context) { |
|
|
|
send := func(status int, data interface{}, err error) { |
|
|
|
send := func(status int, data interface{}, err error) { |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
@ -884,7 +856,7 @@ func Comment(ctx *middleware.Context) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if comment != nil { |
|
|
|
if comment != nil { |
|
|
|
uploadFiles(ctx, issue.ID, comment.Id) |
|
|
|
// uploadFiles(ctx, issue.ID, comment.Id)
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Notify watchers.
|
|
|
|
// Notify watchers.
|
|
|
@ -1194,25 +1166,6 @@ func DeleteMilestone(ctx *middleware.Context) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func IssueGetAttachment(ctx *middleware.Context) { |
|
|
|
|
|
|
|
id := com.StrTo(ctx.Params(":id")).MustInt64() |
|
|
|
|
|
|
|
if id == 0 { |
|
|
|
|
|
|
|
ctx.Error(404) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
attachment, err := models.GetAttachmentById(id) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
ctx.Handle(404, "models.GetAttachmentById", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
|
|
|
|
|
|
|
|
// We must put the name in " manually.
|
|
|
|
|
|
|
|
ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func PullRequest2(ctx *middleware.Context) { |
|
|
|
func PullRequest2(ctx *middleware.Context) { |
|
|
|
ctx.HTML(200, "repo/pr2/list") |
|
|
|
ctx.HTML(200, "repo/pr2/list") |
|
|
|
} |
|
|
|
} |
|
|
|