all repos — felt @ 8f4eb7e9582b5057050d7177bd4a0e5aaacf5118

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

more map stuff - list images and start real setup for setting map image adminside
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmQuS6IACgkQO3+8IhRO
Y5jCPQ/8DBIRHmPxhmBPC2mGNT8mdd8+8GpabojvEheYthJWDDxX4kze9fjkcCcE
wYRL2ySElxg0wCZI46BDvNYiTvF6suKPf+DbVVf2eXf/YJP68Fw9pln1SDvPlYXt
k4LJVPx5Ica4Ydr8CwqtukseR3Pt5yxjcFVM8xILs5YoDuEoPDwsPS4lsUh6LABF
yg1ti6Hq3WHu1w2cyqpNovhsyKfy4nbcPBYUoNORHbVCZpRdgnyMrJOR7x+y0rlq
pSLV129pt3OTG3XrlpRPlhmiOXM4f2Oxt7EsU9t0ulQC4Ha3wf/mj5HspKc17TXI
fgT0h9sDoesAxfruHtUS2LuT/PEAuBGGtK5xoCjtfKAAMMmFNgJFsRoISVhbzI8F
/m2gXlSUdN2P9NIaItTZgoAstizBcBqG5dGWKgfbhx0ANpKhbzlDpS8BCxWOUQdh
8/3GihgNk5QYm9t1gkPDFFuFvEF4YCma8e3chCyXWvW6tAImAMJP3eS+LwYrgd4C
DifQju2n8gSHsmaHYwnNd0tQV+D8c7I0K6sY/aozAVZeByAdqphW6A/WkVgtQDJq
fYBylm3OXUmwPdBHxIED1DhRNRkcWJujC30FycnOakGWa4nMs/bxDDPveNpRpxgd
LneRhSY0okRWVHaCHK16dRZUnQ9bL9rVU+wOcpDRTvBKIvAmbyk=
=Aft9
-----END PGP SIGNATURE-----
commit

8f4eb7e9582b5057050d7177bd4a0e5aaacf5118

parent

16d58eb281aa52186dfae34e07034a22ae32cce5

3 files changed, 58 insertions(+), 6 deletions(-)

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

@@ -119,6 +119,7 @@ table := models.TableKey{}

err = json.NewDecoder(req.Body).Decode(&table) if err != nil { w.WriteHeader(400) + return } for j, t := range tables {

@@ -149,7 +150,7 @@

return http.HandlerFunc(handlerFunc) } -func apiUploadMapImg(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploads, uploadType string, uploadMax int) http.Handler { +func apiUploadImg(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 r, err := req.MultipartReader()

@@ -212,16 +213,18 @@ if err != nil {

fmt.Println(err.Error()) w.WriteHeader(500) next.ServeHTTP(w, req) + return } dest.Write(fileData) dest.Close() err = dbAdapter.SetMapImageUrl(tableKey, "/uploads/"+tableKey.Name+"/"+uploadType+"/"+header.Filename) if err != nil { - fmt.Println(err.Error()) + w.WriteHeader(500) + next.ServeHTTP(w, req) + return } // respond with URL so UI can update - w.Header().Set("Content-Type", "application/json") AddContextValue(req, "location", "/uploads/"+tableKey.Name+"/"+uploadType+"/"+header.Filename) next.ServeHTTP(w, req) }

@@ -229,6 +232,33 @@

return http.HandlerFunc(handlerFunc) } +func apiListImages(next http.Handler, uploads string, uploadType string) http.Handler { + handlerFunc := func(w http.ResponseWriter, req *http.Request) { + urlParams := req.Context().Value("params").(map[string]string) + tableName := urlParams["Slug"] + destPath := filepath.Join(uploads, tableName, uploadType) + files, err := ioutil.ReadDir(destPath) + + if err != nil { + w.WriteHeader(500) + next.ServeHTTP(w, req) + return + } + + fileNames := []string{} + for _, file := range files { + if !file.IsDir() { + fileNames = append(fileNames, "/uploads/"+tableName+"/"+uploadType+"/"+file.Name()) + } + } + + AddContextValue(req, "files", fileNames) + next.ServeHTTP(w, req) + } + + return http.HandlerFunc(handlerFunc) +} + func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploads string, uploadMaxMB int) http.Handler { // create quartzgun router rtr := &router.Router{Fallback: *template.Must(template.ParseFiles("static/error.html"))}

@@ -244,9 +274,11 @@ rtr.Post("/api/table/", Validate(apiCreateTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes))

rtr.Delete(`/api/table/(?P<Slug>\S+)`, Validate(apiDestroyTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes)) // asset management - rtr.Post(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiUploadMapImg(renderer.JSON("location"), udb, dbAdapter, uploads, "map", uploadMaxMB), udb, scopes)) + rtr.Post(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiUploadImg(renderer.JSON("location"), udb, dbAdapter, uploads, "map", uploadMaxMB), udb, scopes)) + // GET /api/upload/<table>/map/ + rtr.Get(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiListImages(renderer.JSON("files"), uploads, "map"), udb, scopes)) // DELETE /api/upload/<table>/map/<map> - rtr.Post(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiUploadMapImg(renderer.JSON("location"), udb, dbAdapter, uploads, "token", uploadMaxMB), udb, scopes)) + rtr.Post(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiUploadImg(renderer.JSON("location"), udb, dbAdapter, uploads, "token", uploadMaxMB), udb, scopes)) // DELETE /api/upload/<table>/token/<token> return http.HandlerFunc(rtr.ServeHTTP)
M models/models.gomodels/models.go

@@ -36,6 +36,7 @@ AuxMessage string `json:"auxMessage"`

} type TableMessage struct { + Auth *string `json:"auth"` Key *TableKey `json:"key"` DiceRoll *DiceRoll `json:"diceRoll"` Token *Token `json:"token"`
M static/admin.jsstatic/admin.js

@@ -13,6 +13,11 @@ const res = await fetch(`/admin/api/table/${name}?passcode=${pass}`, {

method: 'GET', headers: headers, }); + + const mapImgs = await fetch (`/admin/api/upload/${name}/map/`, { + method: 'GET', + headers: headers, + }); if (res.ok) { document.getElementById("input_table_name").value = name;

@@ -21,8 +26,18 @@ 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>" + if (mapImgs.ok) { + const imgs = await mapImgs.json(); + console.dir(imgs); + infoHtml += "<ul>"; + for (const i of imgs) { + const parts = i.split("/"); + infoHtml += `<li>${parts[parts.length - 1]} <a href="${i}">view</a> <button onclick="sendMapImg(${i});">set</button> <button onclick="deleteMapImg(${i})">delete</button></li>\n` + } + infoHtml += "</ul>" + } adminZone.innerHTML = infoHtml; } else {

@@ -31,6 +46,10 @@ }

} catch (err) { setErr(`${err.name}: ${err.message}`); } +} + +function sendMapImg(url) { + publish({mapImg: url, auth: adminToken.access_token}); } async function uploadMapImg() {