configui/configui.go

154 lines
3.2 KiB
Go

package configui
import (
"embed"
"encoding/json"
"errors"
"fmt"
"html/template"
"time"
"kumoly.io/tools/configui/public"
)
var UNIX_SHELL = "sh"
var WIN_SHELL = "cmd"
const version = "v0.1.3"
//go:embed templates
var tmplFS embed.FS
var Ext2Mode map[string]string = map[string]string{
"go": "golang",
"log": "sh",
"txt": "text",
"yml": "yaml",
"conf": "ini",
"md": "markdown",
}
type ConfigUI struct {
AppName string `json:"app_name"`
BaseUrl string `json:"base_url"`
ConfigPath string `json:"config_path"`
NoReconfig bool `json:"no_reconfig"`
AllowIP string `json:"allow_ip"`
CmdTimeout string `json:"timeout"`
cmdTimeout time.Duration
Files []*File `json:"files"`
fileIndex map[string]int
ResultBellow bool `json:"result_bellow"`
HideConfig bool `json:"hide_config"`
// Should be in main app
LogPath string `json:"log_path"`
SilentSysOut bool `json:"silent_sys_out"`
TmplFS embed.FS `json:"-"`
tmpl *template.Template
PublicFS embed.FS `json:"-"`
}
func New() *ConfigUI {
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
"step": func(from, to, step uint) []uint {
items := []uint{}
for i := from; i <= to; i += step {
items = append(items, i)
}
return items
},
}).ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
return &ConfigUI{
fileIndex: map[string]int{},
AppName: "ConfigUI",
BaseUrl: "/",
PublicFS: public.FS,
TmplFS: tmplFS,
tmpl: tmpl,
CmdTimeout: "10s",
cmdTimeout: time.Second * 10,
}
}
func (cui *ConfigUI) File(file_name string) (*File, error) {
if file_name == cui.AppName {
return &File{
Path: cui.ConfigPath,
Name: cui.AppName,
Lang: "json",
}, nil
}
index, ok := cui.fileIndex[file_name]
if !ok {
return nil, errors.New("no file found")
}
return cui.Files[index], nil
}
func (cui *ConfigUI) LoadConfig(confstr string) error {
tmpConf := &ConfigUI{}
err := json.Unmarshal([]byte(confstr), tmpConf)
if err != nil {
return nil
}
// construct fileIndex
tmpIndex := map[string]int{}
for i, f := range tmpConf.Files {
if f.Name == "" {
f.Name = f.Path
}
tmpIndex[f.Name] = i
}
// copy
cui.fileIndex = tmpIndex
cui.Files = tmpConf.Files
cui.AllowIP = tmpConf.AllowIP
cui.ConfigPath = tmpConf.ConfigPath
cui.HideConfig = tmpConf.HideConfig
cui.LogPath = tmpConf.LogPath
cui.NoReconfig = tmpConf.NoReconfig
cui.AppName = tmpConf.AppName
cui.BaseUrl = tmpConf.BaseUrl
if cui.BaseUrl == "" {
cui.BaseUrl = "/"
}
ct, err := time.ParseDuration(tmpConf.CmdTimeout)
if err != nil || cui.CmdTimeout == "" {
cui.CmdTimeout = "10s"
cui.cmdTimeout = time.Second * 10
} else {
cui.CmdTimeout = tmpConf.CmdTimeout
cui.cmdTimeout = ct
}
// NOT implemented
cui.ResultBellow = tmpConf.ResultBellow
cui.SilentSysOut = tmpConf.SilentSysOut
// fmt.Printf("%+v", cui)
return nil
}
func (cui *ConfigUI) Config() ([]byte, error) {
return json.MarshalIndent(cui, "", " ")
}
func (cui *ConfigUI) AppendFile(file *File) error {
if file.Name == "" {
file.Name = file.Path
}
i, ok := cui.fileIndex[file.Name]
if ok {
return fmt.Errorf("%v already exists at %d", file.Name, i)
}
cui.fileIndex[file.Name] = len(cui.Files)
cui.Files = append(cui.Files, file)
return nil
}