2023-12-01 09:56:06 +01:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
2023-12-01 13:44:58 +01:00
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"github.com/gin-gonic/gin"
|
2023-12-01 09:56:06 +01:00
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/ginext"
|
2023-12-01 13:44:58 +01:00
|
|
|
templhtml "html/template"
|
|
|
|
bunny "locbunny"
|
2023-12-01 09:56:06 +01:00
|
|
|
"locbunny/logic"
|
|
|
|
"locbunny/models"
|
2023-12-01 13:44:58 +01:00
|
|
|
"locbunny/webassets"
|
2023-12-01 09:56:06 +01:00
|
|
|
"net/http"
|
2023-12-01 13:44:58 +01:00
|
|
|
"path/filepath"
|
|
|
|
templtext "text/template"
|
|
|
|
"time"
|
2023-12-01 09:56:06 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type WebHandler struct {
|
|
|
|
app *logic.Application
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewWebHandler(app *logic.Application) WebHandler {
|
|
|
|
return WebHandler{
|
|
|
|
app: app,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-01 13:44:58 +01:00
|
|
|
// ServeIndexHTML swaggerdoc
|
2023-12-01 09:56:06 +01:00
|
|
|
//
|
2023-12-01 13:44:58 +01:00
|
|
|
// @Summary (Website)
|
2023-12-01 09:56:06 +01:00
|
|
|
//
|
2023-12-01 13:44:58 +01:00
|
|
|
// @Router / [GET]
|
|
|
|
// @Router /index.html [GET]
|
|
|
|
func (h WebHandler) ServeIndexHTML(pctx ginext.PreContext) ginext.HTTPResponse {
|
|
|
|
ctx, _, errResp := pctx.Start()
|
|
|
|
if errResp != nil {
|
|
|
|
return *errResp
|
|
|
|
}
|
|
|
|
defer ctx.Cancel()
|
|
|
|
|
|
|
|
templ, err := h.app.Assets.Template("index.html", h.buildIndexHTMLTemplate)
|
|
|
|
if err != nil {
|
|
|
|
return ginext.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
data := map[string]any{}
|
|
|
|
|
|
|
|
bin := bytes.Buffer{}
|
|
|
|
err = templ.Execute(&bin, data)
|
|
|
|
if err != nil {
|
|
|
|
return ginext.Error(err)
|
2023-12-01 09:56:06 +01:00
|
|
|
}
|
|
|
|
|
2023-12-01 13:44:58 +01:00
|
|
|
return ginext.Data(http.StatusOK, "text/html", bin.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
// ServeScriptJS swaggerdoc
|
|
|
|
//
|
|
|
|
// @Summary (Website)
|
|
|
|
//
|
|
|
|
// @Router /scripts.script.js [GET]
|
|
|
|
func (h WebHandler) ServeScriptJS(pctx ginext.PreContext) ginext.HTTPResponse {
|
2023-12-01 09:56:06 +01:00
|
|
|
ctx, _, errResp := pctx.Start()
|
|
|
|
if errResp != nil {
|
|
|
|
return *errResp
|
|
|
|
}
|
|
|
|
defer ctx.Cancel()
|
|
|
|
|
2023-12-01 13:44:58 +01:00
|
|
|
templ, err := h.app.Assets.Template("scripts/script.js", h.buildScriptJSTemplate)
|
2023-12-01 09:56:06 +01:00
|
|
|
if err != nil {
|
|
|
|
return ginext.Error(err)
|
|
|
|
}
|
|
|
|
|
2023-12-01 13:44:58 +01:00
|
|
|
data := map[string]any{}
|
|
|
|
|
|
|
|
bin := bytes.Buffer{}
|
|
|
|
err = templ.Execute(&bin, data)
|
|
|
|
if err != nil {
|
|
|
|
return ginext.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ginext.Data(http.StatusOK, "text/javascript", bin.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h WebHandler) buildIndexHTMLTemplate(content []byte) (webassets.ITemplate, error) {
|
|
|
|
t := templhtml.New("index.html")
|
|
|
|
|
|
|
|
t.Funcs(h.templateFuncMap())
|
|
|
|
|
|
|
|
_, err := t.Parse(string(content))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h WebHandler) ServeAssets(pctx ginext.PreContext) ginext.HTTPResponse {
|
|
|
|
type uri struct {
|
|
|
|
FP1 *string `uri:"fp1"`
|
|
|
|
FP2 *string `uri:"fp2"`
|
|
|
|
FP3 *string `uri:"fp3"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var u uri
|
|
|
|
ctx, _, errResp := pctx.URI(&u).Start()
|
|
|
|
if errResp != nil {
|
|
|
|
return *errResp
|
|
|
|
}
|
|
|
|
defer ctx.Cancel()
|
2023-12-01 09:56:06 +01:00
|
|
|
|
2023-12-01 13:44:58 +01:00
|
|
|
assetpath := ""
|
|
|
|
if u.FP1 == nil && u.FP2 == nil && u.FP3 == nil {
|
|
|
|
assetpath = filepath.Join()
|
|
|
|
} else if u.FP2 == nil && u.FP3 == nil {
|
|
|
|
assetpath = filepath.Join(*u.FP1)
|
|
|
|
} else if u.FP3 == nil {
|
|
|
|
assetpath = filepath.Join(*u.FP1, *u.FP2)
|
|
|
|
} else {
|
|
|
|
assetpath = filepath.Join(*u.FP1, *u.FP2, *u.FP3)
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := h.app.Assets.Read(assetpath)
|
|
|
|
if err != nil {
|
|
|
|
return ginext.JSON(http.StatusNotFound, gin.H{"error": "AssetNotFound", "assetpath": assetpath})
|
|
|
|
}
|
|
|
|
|
|
|
|
mime := bunny.FilenameToMime(assetpath, "text/plain")
|
|
|
|
|
|
|
|
return ginext.Data(http.StatusOK, mime, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h WebHandler) buildScriptJSTemplate(content []byte) (webassets.ITemplate, error) {
|
|
|
|
t := templtext.New("scripts/script.js")
|
|
|
|
|
|
|
|
t.Funcs(h.templateFuncMap())
|
|
|
|
|
|
|
|
_, err := t.Parse(string(content))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h WebHandler) templateFuncMap() map[string]any {
|
|
|
|
return map[string]any{
|
|
|
|
"listServers": func() []models.Server {
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), bunny.Conf.VerifyConnTimeoutHTML+2*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
v, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutHTML)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
},
|
|
|
|
"safe_html": func(s string) templhtml.HTML { return templhtml.HTML(s) }, //nolint:gosec
|
|
|
|
"safe_js": func(s string) templhtml.JS { return templhtml.JS(s) }, //nolint:gosec
|
|
|
|
"json": func(obj any) string {
|
|
|
|
v, err := json.Marshal(obj)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return string(v)
|
|
|
|
},
|
|
|
|
"json_indent": func(obj any) string {
|
|
|
|
v, err := json.MarshalIndent(obj, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return string(v)
|
|
|
|
},
|
|
|
|
"mkarr": func(ln int) []int { return make([]int, ln) },
|
|
|
|
}
|
2023-12-01 09:56:06 +01:00
|
|
|
}
|