all repos — felt @ 16d58eb281aa52186dfae34e07034a22ae32cce5

virtual tabletop for dungeons and dragons (and similar) using Go, MongoDB, and websockets

upload map image and displaying on connect works (still need to send broadcast on the socket when upload happens)
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmQrsmUACgkQO3+8IhRO
Y5hN1w//fpUsMyFTF4ynYoAoC8Vp0qYsdKMbxior0cJ+DDkWMKxB6eaXg+AbAdGn
LLMk04bHkVvShQJ8FpL/3+LSC1cqqyHcL/O/oJO6V2f1K1skHJsup+A4yjICxBNp
Lz73Y9ebdomx6BJ/WPgl1qYTfHM811yVwENVv99PIn8pVF2+0zNmCa/PecRf7nUC
vgfh2++9ib2QpsB55qEGMnBXOtLfMs/666JegcOKFTIoaZ83L3dT3EqhbQlJT3Uq
duYFb3cVZ/EFSYnUhZAcOxsMWDuMywi1lem90RFkvPEA+beT1L6o+FrMRsGPCVqS
omSWC+hSg/iUXjyD0x8c6PyTAioUlQouB/BstkqC9BKwqzPUW7AGN62lx8SiMKQ7
C4YWs4D+jnX8QpLBHBHHPGtnFWjqcV12FwpETWlDCBIBaPJORX2k9Uea/kxPZppM
2oI9UmFj6yrJmmQWrA1uVVl1PRtbWuoT18dPJqSriGhfp7B264nO/cuZA4P1cgR1
nFBkYN6Q3wkCc5Y3bzHNMiFw15fcYVG6VeO+E3bftyZjlL8paFy1d620mvyCrB08
6hi4r/gklqEBJ3mssGMc7kr2vPrDPa8tlseGEJW/nLCQoIpASZT8wqImuBVb3gVe
w3gDhx77/VDTOoLjAmu/nGtious9z8fh5TMKVs5TTbqDhVpYaqI=
=bQRk
-----END PGP SIGNATURE-----
commit

16d58eb281aa52186dfae34e07034a22ae32cce5

parent

51f50d679de76b17ee0445bf8718d5d894162b75

5 files changed, 71 insertions(+), 15 deletions(-)

jump to
M admin/admin.goadmin/admin.go

@@ -2,7 +2,7 @@ package admin

import ( "encoding/json" - _ "fmt" + "fmt" "hacklab.nilfm.cc/felt/admin/util" "hacklab.nilfm.cc/felt/models" "hacklab.nilfm.cc/felt/mongodb"

@@ -152,12 +152,19 @@

func apiUploadMapImg(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploads, uploadType string, uploadMax int) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { // get table from request body - tableKey := models.TableKey{} - err := json.NewDecoder(req.Body).Decode(&tableKey) + r, err := req.MultipartReader() if err != nil { - w.WriteHeader(400) - next.ServeHTTP(w, req) - return + fmt.Println(err.Error()) + } + + f, err := r.ReadForm(int64(uploadMax << 20)) + if err != nil { + fmt.Println(err.Error()) + } + + tableKey := models.TableKey{ + Name: f.Value["name"][0], + Passcode: f.Value["passcode"][0], } // check if this table exists

@@ -170,20 +177,25 @@

// ensure data storage dir exists info, err := os.Stat(uploads) if !info.IsDir() { + fmt.Println("uploads dir aint no dir") w.WriteHeader(500) next.ServeHTTP(w, req) + return } else if err != nil { - err = os.MkdirAll(filepath.Join(uploads, tableKey.Name, uploadType), 0755) + err = os.MkdirAll(uploads, 0755) if err != nil { + fmt.Println(err.Error()) w.WriteHeader(500) next.ServeHTTP(w, req) } } + err = os.MkdirAll(filepath.Join(uploads, tableKey.Name, uploadType), 0755) // check for filename; call create to overwrite regardless // get file data from multipart form - req.ParseMultipartForm(int64(uploadMax << 20)) - file, header, err := req.FormFile("file") + header := f.File["file"][0] + file, err := header.Open() if err != nil { + fmt.Println(err.Error()) w.WriteHeader(500) next.ServeHTTP(w, req) }

@@ -194,15 +206,21 @@ next.ServeHTTP(w, req)

} // write to file destPath := filepath.Join(uploads, tableKey.Name, uploadType, header.Filename) + fmt.Println(destPath) dest, err := os.Create(destPath) if err != nil { + fmt.Println(err.Error()) w.WriteHeader(500) next.ServeHTTP(w, req) } dest.Write(fileData) dest.Close() + + err = dbAdapter.SetMapImageUrl(tableKey, "/uploads/"+tableKey.Name+"/"+uploadType+"/"+header.Filename) + if err != nil { + fmt.Println(err.Error()) + } // respond with URL so UI can update - w.WriteHeader(201) w.Header().Set("Content-Type", "application/json") AddContextValue(req, "location", "/uploads/"+tableKey.Name+"/"+uploadType+"/"+header.Filename) next.ServeHTTP(w, req)
M gametable/server.gogametable/server.go

@@ -45,6 +45,7 @@ publishLimiter: rate.NewLimiter(rate.Every(time.Millisecond*100), 8),

dbAdapter: adapter, } srvr.serveMux.Handle("/table/", http.StripPrefix("/table/", renderer.Subtree("./static"))) + srvr.serveMux.Handle("/uploads/", http.StripPrefix("/uploads/", renderer.Subtree(uploads))) srvr.serveMux.Handle("/admin/", http.StripPrefix("/admin", admin.CreateAdminInterface(udb, adapter, uploads, uploadMaxMB))) srvr.serveMux.HandleFunc("/subscribe", srvr.subscribeHandler) srvr.serveMux.HandleFunc("/publish", srvr.publishHandler)
M mongodb/adapter.gomongodb/adapter.go

@@ -213,7 +213,7 @@ {"name", table.Name},

{"passcode", table.Passcode}, }, bson.D{ - {"mapImageUrl", url}, + {"$set", bson.D{{"mapImageUrl", url}}}, }, ).Decode(&result)

@@ -254,7 +254,7 @@ {"name", table.Name},

{"passcode", table.Passcode}, }, bson.D{ - {"auxMessage", message}, + {"$set", bson.D{{"auxMessage", message}}}, }, ).Decode(&result)
M static/admin.jsstatic/admin.js

@@ -21,11 +21,36 @@ dial();

infoHtml = "<a href='#' onclick='getTables()'>&larr; table list</a><br><pre>"; infoHtml += await res.text(); infoHtml += "</pre>" - infoHtml += `<button onclick='destroyTable()'>Destroy</button>` + infoHtml += "<input id='map_img_upload' type='file'>Map Image</input><button onclick='uploadMapImg()'>Upload</button>" + infoHtml += "<button onclick='destroyTable()'>Destroy</button>" adminZone.innerHTML = infoHtml; } else { console.log(res.status); + } + } catch (err) { + setErr(`${err.name}: ${err.message}`); + } +} + +async function uploadMapImg() { + try { + var input = document.getElementById("map_img_upload"); + var data = new FormData(); + data.append('file', input.files[0]); + data.append('name', tableKey.name); + data.append('passcode', tableKey.passcode); + const headers = new Headers(); + headers.set('Authorization', 'Bearer ' + adminToken.access_token); + res = await fetch(`/admin/api/upload/${tableKey.name}/map/`, { + headers: headers, + method: "POST", + body: data, + }); + if (res.ok) { + getTable(tableKey.name, tableKey.passcode); + } else { + throw new Error("Something went wrong uploading the map BG..."); } } catch (err) { setErr(`${err.name}: ${err.message}`);
M static/socket.jsstatic/socket.js

@@ -40,9 +40,18 @@ }

} function makeUpToDate(table) { - if (table && table.diceRolls) { - logDice(table.diceRolls, true); + if (table) { + if (table.diceRolls) { + logDice(table.diceRolls, true); + } + if (table.mapImageUrl) { + setMapImg(table.mapImageUrl); + } } +} + +function setMapImg(url) { + document.getElementById("map").innerHTML = `<img src="${url}"/>` } function dial() {

@@ -94,6 +103,9 @@ makeUpToDate(table);

} else { if (data.diceRoll) { logDice(data.diceRoll); + } + if (data.mapImageUrl) { + setMapImg(data.mapImageUrl); } } console.log(data);