From 520a74c736aa423c5d4fa90c3c58f3dd55afd7df Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Sat, 17 Mar 2018 21:48:36 +0100 Subject: [PATCH] Allow multiple uploads --- main.go | 133 +++++++++++++++++++++++++++--------------- templates/upload.html | 26 ++++----- types.go | 2 +- 3 files changed, 99 insertions(+), 62 deletions(-) diff --git a/main.go b/main.go index 101eeb1..71d935d 100644 --- a/main.go +++ b/main.go @@ -91,8 +91,8 @@ func parseUser(r *http.Request) UserInfo { } type UploadData struct { - User UserInfo - Result Result + User UserInfo + Results []Result } func returnResult(w http.ResponseWriter, templateName string, data interface{}) error { @@ -129,59 +129,95 @@ func main() { if r.Method == "POST" { user := parseUser(r) - r.ParseMultipartForm(32 << 20) - file, header, err := r.FormFile("file") - image, err := createImage(&config, file, header) + err := r.ParseMultipartForm(32 << 20) if err != nil { - returnResult(w, "upload.html", UploadData{ + if err = returnResult(w, "upload.html", UploadData{ user, - Result{ - Id: "", + []Result{{ Success: false, Errors: []string{err.Error()}, - }, - }) - return + }}, + }); err != nil { + panic(err) + } } - _, err = db.Exec("INSERT INTO images (id, owner, created_at, original_name, type) VALUES ($1, $2, $3, $4, $5)", image.Id, user.Id, image.CreatedAt, image.OriginalName, image.MimeType) - if err != nil { - panic(err) + var images []Image + var ids []string + + m := r.MultipartForm + files := m.File["file"] + for _, header := range files { + file, err := header.Open() + if err != nil { + if err = returnResult(w, "upload.html", UploadData{ + user, + []Result{{ + Success: false, + Errors: []string{err.Error()}, + }}, + }); err != nil { + panic(err) + } + return + } + image, err := createImage(&config, file, header) + if err != nil { + if err = returnResult(w, "upload.html", UploadData{ + user, + []Result{{ + Success: false, + Errors: []string{err.Error()}, + }}, + }); err != nil { + panic(err) + } + return + } + + images = append(images, image) + ids = append(ids, image.Id) } - fmt.Printf("Created task %s at %d\n", image.Id, time.Now().Unix()) + pubsub := client.Subscribe(config.ResultChannel) - data, err := json.Marshal(image) - if err != nil { - if err = returnResult(w, "upload.html", UploadData{ - user, - Result{ - Id: image.Id, - Success: false, - Errors: []string{err.Error()}, - }, - }); err != nil { + for _, image := range images { + _, err = db.Exec("INSERT INTO images (id, owner, created_at, original_name, type) VALUES ($1, $2, $3, $4, $5)", image.Id, user.Id, image.CreatedAt, image.OriginalName, image.MimeType) + if err != nil { panic(err) } - return - } - pubsub := client.Subscribe(config.ResultChannel) - client.RPush(fmt.Sprintf("queue:%s", config.ImageQueue), data) + data, err := json.Marshal(images) + if err != nil { + if err = returnResult(w, "upload.html", UploadData{ + user, + []Result{{ + Success: false, + Errors: []string{err.Error()}, + }}, + }); err != nil { + panic(err) + } + return + } + + fmt.Printf("Created task %s at %d\n", image.Id, time.Now().Unix()) + client.RPush(fmt.Sprintf("queue:%s", config.ImageQueue), data) + fmt.Printf("Submitted task %s at %d\n", image.Id, time.Now().Unix()) + } - fmt.Printf("Submitted task %s at %d\n", image.Id, time.Now().Unix()) + var results []Result - waiting := true - for waiting { + var waiting map[string]bool + for len(waiting) != 0 { message, err := pubsub.ReceiveMessage() if err != nil { if err = returnResult(w, "upload.html", UploadData{ user, - Result{ - Id: image.Id, + []Result{{ Success: false, Errors: []string{err.Error()}, - }, + }}, }); err != nil { panic(err) } @@ -193,11 +229,10 @@ func main() { if err != nil { if err = returnResult(w, "upload.html", UploadData{ user, - Result{ - Id: image.Id, + []Result{{ Success: false, Errors: []string{err.Error()}, - }, + }}, }); err != nil { panic(err) } @@ -206,23 +241,25 @@ func main() { fmt.Printf("Returned task %s at %d\n", result.Id, time.Now().Unix()) - if result.Id == image.Id { - waiting = false + if _, ok := waiting[result.Id]; ok { + delete(waiting, result.Id) - if err = returnResult(w, "upload.html", UploadData{ - user, - result, - }); err != nil { - panic(err) - } - return + results = append(results, result) } } + + if err = returnResult(w, "upload.html", UploadData{ + user, + results, + }); err != nil { + panic(err) + } + return } else { user := parseUser(r) if err = returnResult(w, "upload.html", UploadData{ user, - Result{}, + []Result{}, }); err != nil { panic(err) } diff --git a/templates/upload.html b/templates/upload.html index 08b68c3..3663ee5 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -11,19 +11,19 @@ <a href="/upload">Upload</a> </p> -{{ if .Result.Id }} - {{ if .Result.Success }} - <div class="info success"> - <h2>Upload of {{ .Result.Id }} finished. <a href="/i/{{ .Result.Id }}">View</a>.</h2> - </div> - {{ else }} - <div class="info error"> - <h2>Upload of {{ .Result.Id }} failed.</h2> - {{ range .Result.Errors }} - <pre>{{ . }}</pre> - {{ end }} - </div> - {{ end }} +{{ range .Results }} +{{ if .Success }} +<div class="info success"> + <h2>Upload of {{ .Id }} finished. <a href="/i/{{ .Id }}">View</a>.</h2> +</div> +{{ else }} +<div class="info error"> + <h2>Upload of {{ .Id }} failed.</h2> +{{ range .Errors }} + <pre>{{ . }}</pre> +{{ end }} +</div> +{{ end }} {{ end }} <form action="/upload/" method="POST" enctype="multipart/form-data"> diff --git a/types.go b/types.go index 2ea713f..ddd6a21 100644 --- a/types.go +++ b/types.go @@ -16,7 +16,7 @@ type Image struct { } type Result struct { - Id string `json:"id"` + Id string `json:"id"` Success bool `json:"success"` Errors []string `json:"errors"` } -- GitLab