From 088d5d4cbe45e60b7a7783d6c1d622c3d3b70c1f Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 18 Mar 2018 18:32:29 +0100
Subject: [PATCH] Improved upload API

---
 page_upload.go        | 97 ++++++++++++++++++-------------------------
 templates/upload.html | 21 ++++++----
 2 files changed, 53 insertions(+), 65 deletions(-)

diff --git a/page_upload.go b/page_upload.go
index 26b8810..23154e6 100644
--- a/page_upload.go
+++ b/page_upload.go
@@ -92,65 +92,50 @@ func pageUpload(ctx PageContext) http.Handler {
 				}
 			}
 
-			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 = returnJson(w, []Result{{
-						Success: false,
-						Errors:  []string{err.Error()},
-					}}); err != nil {
-						panic(err)
-					}
-					return
+			file, header, err := r.FormFile("file")
+			if err != nil {
+				if err = returnJson(w, []Result{{
+					Success: false,
+					Errors:  []string{err.Error()},
+				}}); err != nil {
+					panic(err)
 				}
-				image, err := createImage(ctx.Config, file, header)
-				if err != nil {
-					if err = returnJson(w, []Result{{
-						Success: false,
-						Errors:  []string{err.Error()},
-					}}); err != nil {
-						panic(err)
-					}
-					return
+				return
+			}
+			image, err := createImage(ctx.Config, file, header)
+			if err != nil {
+				if err = returnJson(w, []Result{{
+					Success: false,
+					Errors:  []string{err.Error()},
+				}}); err != nil {
+					panic(err)
 				}
-
-				images = append(images, image)
-				ids = append(ids, image.Id)
+				return
 			}
 
 			pubsub := ctx.Redis.Subscribe(ctx.Config.ResultChannel)
-			waiting := make(map[string]bool)
-			for _, image := range images {
-				_, err = ctx.Database.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)
-				}
+			_, err = ctx.Database.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)
+			}
 
-				data, err := json.Marshal(image)
-				if err != nil {
-					if err = returnJson(w, []Result{{
-						Success: false,
-						Errors:  []string{err.Error()},
-					}}); err != nil {
-						panic(err)
-					}
-					return
+			data, err := json.Marshal(image)
+			if err != nil {
+				if err = returnJson(w, []Result{{
+					Success: false,
+					Errors:  []string{err.Error()},
+				}}); err != nil {
+					panic(err)
 				}
-
-				fmt.Printf("Created task %s at %d\n", image.Id, time.Now().Unix())
-				ctx.Redis.RPush(fmt.Sprintf("queue:%s", ctx.Config.ImageQueue), data)
-				fmt.Printf("Submitted task %s at %d\n", image.Id, time.Now().Unix())
-
-				waiting[image.Id] = true
+				return
 			}
 
-			var results []Result
-			for len(waiting) != 0 {
+			fmt.Printf("Created task %s at %d\n", image.Id, time.Now().Unix())
+			ctx.Redis.RPush(fmt.Sprintf("queue:%s", ctx.Config.ImageQueue), data)
+			fmt.Printf("Submitted task %s at %d\n", image.Id, time.Now().Unix())
+
+			waiting := true
+			for waiting {
 				message, err := pubsub.ReceiveMessage()
 				if err != nil {
 					if err = returnJson(w, []Result{{
@@ -176,16 +161,14 @@ func pageUpload(ctx PageContext) http.Handler {
 
 				fmt.Printf("Returned task %s at %d\n", result.Id, time.Now().Unix())
 
-				if _, ok := waiting[result.Id]; ok {
-					delete(waiting, result.Id)
+				if result.Id == image.Id {
+					waiting = false
 
-					results = append(results, result)
+					if err = returnJson(w, result); err != nil {
+						panic(err)
+					}
 				}
 			}
-
-			if err = returnJson(w, results); err != nil {
-				panic(err)
-			}
 			return
 		} else {
 			user := parseUser(r)
diff --git a/templates/upload.html b/templates/upload.html
index 8351784..38ebd82 100644
--- a/templates/upload.html
+++ b/templates/upload.html
@@ -30,6 +30,17 @@
     <div class="uploading images"></div>
 </div>
 <script>
+    function postData(url, data) {
+        return fetch(url, {
+            body: data,
+            cache: 'no-cache',
+            credentials: 'same-origin',
+            method: 'POST',
+            mode: 'cors',
+            redirect: 'follow'
+        }).then(response => response.json())
+    }
+
     const form = document.querySelector("form.upload");
     const element = document.querySelector("form.upload input[type=file]");
     const results = document.querySelector(".uploading.images");
@@ -46,15 +57,9 @@
                 results.appendChild(node);
 
                 const data = new FormData();
-                data.append("file", file);
+                data.append("file", file, file.name);
 
-                fetch("/upload", {
-                    method: "POST",
-                    credentials: "same-origin",
-                    body: data
-                }).then((response) => {
-                    return response.json()
-                }).then((json) => {
+                postData("/upload/", data).then((json) => {
                     const text = document.createElement("pre");
                     text.innerText = JSON.stringify(json);
                     node.appendChild(text);
-- 
GitLab