update
parent
a956221c4e
commit
38cc74dd6f
15
app.go
15
app.go
|
@ -14,6 +14,7 @@ type ActiveFile struct {
|
|||
Name string
|
||||
Action string
|
||||
Content string
|
||||
Order int
|
||||
}
|
||||
|
||||
type Editor struct {
|
||||
|
@ -39,11 +40,17 @@ func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
|||
Files := []ActiveFile{}
|
||||
for _, i := range cui.fileIndex {
|
||||
Files = append(Files, ActiveFile{
|
||||
Name: cui.Files[i].Name,
|
||||
Path: cui.Files[i].Path,
|
||||
Name: cui.Files[i].Name,
|
||||
Path: cui.Files[i].Path,
|
||||
Order: cui.Files[i].Order,
|
||||
})
|
||||
}
|
||||
sort.Slice(Files, func(i, j int) bool { return Files[i].Name < Files[j].Name })
|
||||
sort.Slice(Files, func(i, j int) bool {
|
||||
if Files[i].Order == Files[j].Order {
|
||||
return Files[i].Name < Files[j].Name
|
||||
}
|
||||
return Files[i].Order < Files[j].Order
|
||||
})
|
||||
plat := "unix"
|
||||
if runtime.GOOS == "windows" {
|
||||
plat = "windows"
|
||||
|
@ -65,7 +72,7 @@ func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
|||
file, err := cui.File(name)
|
||||
if name == "" || err != nil {
|
||||
tmp, err = cui.Config()
|
||||
data.File.Name = "ConfigUI"
|
||||
data.File.Name = cui.AppName
|
||||
data.File.Path = ":mem:"
|
||||
data.Editor.Lang = "json"
|
||||
if name != "" {
|
||||
|
|
|
@ -95,6 +95,7 @@ func main() {
|
|||
|
||||
cui.LogPath = flagLogFile
|
||||
cui.ConfigPath = flagConfigPath
|
||||
cui.NoReconfig = flagNoReconfig
|
||||
|
||||
// setup routes
|
||||
server := &http.Server{
|
||||
|
|
|
@ -97,6 +97,9 @@ func (cui *ConfigUI) LoadConfig(confstr string) error {
|
|||
cui.HideConfig = tmpConf.HideConfig
|
||||
cui.LogPath = tmpConf.LogPath
|
||||
cui.NoReconfig = tmpConf.NoReconfig
|
||||
cui.AppName = tmpConf.AppName
|
||||
|
||||
// NOT implemented
|
||||
cui.ResultBellow = tmpConf.ResultBellow
|
||||
cui.SilentSysOut = tmpConf.SilentSysOut
|
||||
// fmt.Printf("%+v", cui)
|
||||
|
|
9
file.go
9
file.go
|
@ -15,8 +15,12 @@ type File struct {
|
|||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Action string `json:"action"`
|
||||
RO bool `json:"ro"`
|
||||
Lang string `json:"lang"`
|
||||
// RO is readonly
|
||||
RO bool `json:"ro"`
|
||||
Lang string `json:"lang"`
|
||||
|
||||
// Order order of the display on ui
|
||||
Order int `json:"order"`
|
||||
|
||||
// used for parsing post data
|
||||
Data string `json:"data"`
|
||||
|
@ -39,7 +43,6 @@ func (f *File) Write(data []byte) error {
|
|||
if f.RO {
|
||||
return errors.New("this file has readonly set")
|
||||
}
|
||||
log.Println("dfsdf")
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
info, err := os.Stat(f.Path)
|
||||
|
|
147
handler.go
147
handler.go
|
@ -1 +1,148 @@
|
|||
package configui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func (cui *ConfigUI) ListFiles(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := json.Marshal(cui.Files)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) GetFile(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.URL.Query().Get("name")
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
data, err := file.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
response, err := json.Marshal(map[string]string{
|
||||
"path": file.Path,
|
||||
"name": file.Name,
|
||||
"action": file.Action,
|
||||
"data": string(data),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) PostFile(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f := File{}
|
||||
if err := json.Unmarshal(data, &f); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
file, err := cui.File(f.Name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
if err := file.Write([]byte(f.Data)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) Apply(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.URL.Query().Get("name")
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
result, err := file.Do()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write([]byte(result))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) Download(w http.ResponseWriter, r *http.Request) {
|
||||
if name := r.URL.Query().Get("name"); name != "" {
|
||||
if name == cui.AppName {
|
||||
data, err := cui.Config()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set(
|
||||
"Content-Disposition", `
|
||||
attachment; filename="`+cui.AppName+`.json"`,
|
||||
)
|
||||
w.Write(data)
|
||||
return
|
||||
}
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
data, err := file.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="`+filepath.Base(file.Path)+`"`)
|
||||
w.Write(data)
|
||||
return
|
||||
}
|
||||
fs := []string{}
|
||||
for _, i := range cui.fileIndex {
|
||||
fs = append(fs, cui.Files[i].Path)
|
||||
}
|
||||
if cui.ConfigPath != "" {
|
||||
fs = append(fs, cui.ConfigPath)
|
||||
}
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="export.tar.gz"`)
|
||||
bundle(w, fs, cui.AppName, false)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) PostConfig(w http.ResponseWriter, r *http.Request) {
|
||||
if cui.NoReconfig {
|
||||
panic("system reconfig is disabled")
|
||||
}
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = cui.LoadConfig(string(data))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if cui.ConfigPath != "" {
|
||||
info, err := os.Stat(cui.ConfigPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = os.WriteFile(cui.ConfigPath, data, info.Mode())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := cui.Config()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(data)
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@ package public
|
|||
|
||||
import "embed"
|
||||
|
||||
//go:embed js css ace assets
|
||||
//go:embed css ace assets
|
||||
var FS embed.FS
|
||||
|
|
143
server.go
143
server.go
|
@ -1,12 +1,8 @@
|
|||
package configui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -80,142 +76,3 @@ func (cui *ConfigUI) mux() *http.ServeMux {
|
|||
cuiR.HandleFunc("/", cui.App)
|
||||
return cuiR
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) ListFiles(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := json.Marshal(cui.Files)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) GetFile(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.URL.Query().Get("name")
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
data, err := file.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
response, err := json.Marshal(map[string]string{
|
||||
"path": file.Path,
|
||||
"name": file.Name,
|
||||
"action": file.Action,
|
||||
"data": string(data),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) PostFile(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f := File{}
|
||||
if err := json.Unmarshal(data, &f); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
file, err := cui.File(f.Name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
if err := file.Write([]byte(f.Data)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) Apply(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.URL.Query().Get("name")
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
result, err := file.Do()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write([]byte(result))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) Download(w http.ResponseWriter, r *http.Request) {
|
||||
if name := r.URL.Query().Get("name"); name != "" {
|
||||
if name == cui.AppName {
|
||||
data, err := cui.Config()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set(
|
||||
"Content-Disposition", `
|
||||
attachment; filename="`+cui.AppName+`.json"`,
|
||||
)
|
||||
w.Write(data)
|
||||
return
|
||||
}
|
||||
file, err := cui.File(name)
|
||||
if err != nil {
|
||||
response(w, 404, []byte("file not found"))
|
||||
return
|
||||
}
|
||||
data, err := file.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="`+filepath.Base(file.Path)+`"`)
|
||||
w.Write(data)
|
||||
return
|
||||
}
|
||||
fs := []string{}
|
||||
for _, i := range cui.fileIndex {
|
||||
fs = append(fs, cui.Files[i].Path)
|
||||
}
|
||||
if cui.ConfigPath != "" {
|
||||
fs = append(fs, cui.ConfigPath)
|
||||
}
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="export.tar.gz"`)
|
||||
bundle(w, fs, cui.AppName, false)
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) PostConfig(w http.ResponseWriter, r *http.Request) {
|
||||
if cui.NoReconfig {
|
||||
panic("system reconfig is disabled")
|
||||
}
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = cui.LoadConfig(string(data))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if cui.ConfigPath != "" {
|
||||
info, err := os.Stat(cui.ConfigPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = os.WriteFile(cui.ConfigPath, data, info.Mode())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := cui.Config()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(data)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{define "base/footer"}}
|
||||
<script src="/public/ace/js/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="/public/ace/js/ext-beautify.js" type="text/javascript" charset="utf-8"></script>
|
||||
{{template "base/script" .}}
|
||||
<!-- <script src="/public/js/main.js"></script> -->
|
||||
<script src="/public/js/back.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
|
||||
{{define "base/script"}}
|
||||
<script>
|
||||
window.ToolIsFollow = false;
|
||||
|
||||
async function FileGet(follower=false){
|
||||
|
@ -29,7 +29,7 @@ async function FileGet(follower=false){
|
|||
}
|
||||
|
||||
async function FileSave(){
|
||||
if (Active == 'ConfigUI') {
|
||||
if (Active == '{{.AppName}}') {
|
||||
const res = await fetch('/api/conf', {
|
||||
method: 'POST',
|
||||
body: editor.getValue(),
|
||||
|
@ -53,13 +53,14 @@ async function FileSave(){
|
|||
}
|
||||
|
||||
async function FileApply(){
|
||||
if (Active == 'ConfigUI') {
|
||||
if (Active == '{{.AppName}}') {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const res = await fetch('/api/apply?name='+ Active, {
|
||||
method: 'POST',
|
||||
}).catch(err=>{console.log(err);return;});
|
||||
console.log("running")
|
||||
if(!res.ok){
|
||||
const result = await Catch(res)
|
||||
result_editor.session.setValue(result)
|
||||
|
@ -80,13 +81,6 @@ async function Catch(res){
|
|||
|
||||
// starting point
|
||||
(function(){
|
||||
// block ctl-s
|
||||
window.addEventListener("keypress", function(event) {
|
||||
if (!(event.code == 115 && event.ctrlKey) && !(event.code == 19)) return true
|
||||
alert("Ctrl-S pressed")
|
||||
event.preventDefault()
|
||||
return false
|
||||
})
|
||||
|
||||
// setup ace editor
|
||||
setEditor()
|
||||
|
@ -101,4 +95,6 @@ async function Catch(res){
|
|||
editor.gotoLine(editor.session.getLength());
|
||||
}
|
||||
}), 1000)
|
||||
}())
|
||||
}())
|
||||
</script>
|
||||
{{end}}
|
|
@ -15,14 +15,14 @@
|
|||
{{ end }}
|
||||
</ul>
|
||||
<p class="menu-label">
|
||||
ConfigUI
|
||||
System
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<a class="has-tooltip-arrow {{if eq .File.Name .AppName }}is-active{{end}}"
|
||||
data-tooltip="{{$.File.Path}}"
|
||||
href="/"
|
||||
>config.json</a></li>
|
||||
>Config</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
|
|
Loading…
Reference in New Issue