130 lines
2.6 KiB
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)
|
|
}
|