kconfig/kconfig.go

130 lines
2.6 KiB
Go

package kconfig
import (
_ "embed"
"html/template"
"io/ioutil"
"net/http"
"strings"
"github.com/rs/zerolog/log"
"kumoly.io/lib/guard/engine"
"kumoly.io/tools/kconfig/public"
)
//go:embed assets/default.jcs
var defaultSchema []byte
//go:embed public/index.html
var index string
var servePublic = http.FileServer(http.FS(public.FS))
var tmpl *engine.Engine
var l = log.With().Str("mod", "kconfig").Logger()
func init() {
tmpl = engine.Must(engine.New("").Parse(index))
}
type Kconfig struct {
// AppName displays appname in title and the download file will be {{.AppName}}.json
AppName string
// Schema json for schema, more information see [json-editor](https://github.com/json-editor/json-editor)
Schema []byte
// Mux the underlying Mux
Mux *http.ServeMux
// Apply function callback for intergrating submit
Apply func([]byte) error
// Load function callback for intergrating load
Load func() []byte
}
func New() *Kconfig {
k := &Kconfig{
AppName: "kconfig",
Schema: defaultSchema,
Apply: func(b []byte) error {
l.Debug().Msgf("%s", b)
return nil
},
Load: func() []byte {
return []byte(`{
"name": "test",
"age": 21,
"gender": "male",
"location": {
"city": "",
"state": "",
"citystate": ", "
},
"pets": [],
"cars": []
}`)
},
}
mux := http.NewServeMux()
mux.HandleFunc("/", k.App)
mux.HandleFunc("/api/schema", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.NotFound(w, r)
return
}
w.Write([]byte(k.Schema))
})
mux.HandleFunc("/api/load", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.NotFound(w, r)
return
}
w.Write([]byte(k.Load()))
})
mux.HandleFunc("/api/apply", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.NotFound(w, r)
return
}
data, err := ioutil.ReadAll(r.Body)
r.Body.Close()
if err != nil {
panic(err)
}
err = k.Apply(data)
if err != nil {
panic(err)
}
w.Write([]byte("ok"))
})
k.Mux = mux
return k
}
func (k *Kconfig) ServeHTTP(w http.ResponseWriter, r *http.Request) {
k.Mux.ServeHTTP(w, r)
}
func (k *Kconfig) App(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
tmpl.Execute(w, struct {
AppName string
ACE_JS template.HTML
}{
k.AppName,
template.HTML(`<script src="ace/ace.js"></script>`),
})
return
}
file, err := public.FS.Open(strings.TrimPrefix(r.URL.String(), "/"))
if err != nil {
http.NotFound(w, r)
return
}
stat, err := file.Stat()
if err != nil || stat.IsDir() {
http.NotFound(w, r)
return
}
servePublic.ServeHTTP(w, r)
}