From bc443cc320d3a87722d0ee10344e2c726d8e1ab1 Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Thu, 21 Oct 2021 21:49:15 +0800 Subject: [PATCH] tmp --- api.go => bak/api.go | 0 main.go => bak/main.go | 0 netutil.go => bak/netutil.go | 0 route.go => bak/route.go | 0 bak/util.go | 118 +++++++++++++++++++++++++++ cmd/configui/main.go | 1 + configui.go | 42 ++++++++++ insomnia.json => docs/insomnia.json | 0 file.go | 101 +++++++++++++++++++++++ handler.go | 1 + server.go | 1 + templates/components/toolbar.tmpl | 20 ++--- util.go | 119 +--------------------------- 13 files changed, 275 insertions(+), 128 deletions(-) rename api.go => bak/api.go (100%) rename main.go => bak/main.go (100%) rename netutil.go => bak/netutil.go (100%) rename route.go => bak/route.go (100%) create mode 100644 bak/util.go create mode 100644 cmd/configui/main.go create mode 100644 configui.go rename insomnia.json => docs/insomnia.json (100%) create mode 100644 file.go create mode 100644 handler.go create mode 100644 server.go diff --git a/api.go b/bak/api.go similarity index 100% rename from api.go rename to bak/api.go diff --git a/main.go b/bak/main.go similarity index 100% rename from main.go rename to bak/main.go diff --git a/netutil.go b/bak/netutil.go similarity index 100% rename from netutil.go rename to bak/netutil.go diff --git a/route.go b/bak/route.go similarity index 100% rename from route.go rename to bak/route.go diff --git a/bak/util.go b/bak/util.go new file mode 100644 index 0000000..c3f057c --- /dev/null +++ b/bak/util.go @@ -0,0 +1,118 @@ +package main + +import ( + "archive/tar" + "compress/gzip" + "io" + "os" + "strings" +) + +func matchIPGlob(ip, pattern string) bool { + parts := strings.Split(pattern, ".") + seg := strings.Split(ip, ".") + for i, part := range parts { + + // normalize pattern to 3 digits + switch len(part) { + case 1: + if part == "*" { + part = "***" + } else { + part = "00" + part + } + case 2: + if strings.HasPrefix(part, "*") { + part = "*" + part + } else if strings.HasSuffix(part, "*") { + part = part + "*" + } else { + part = "0" + part + } + } + + // normalize ip to 3 digits + switch len(seg[i]) { + case 1: + seg[i] = "00" + seg[i] + case 2: + seg[i] = "0" + seg[i] + } + + for j := range part { + if string(part[j]) == "*" { + continue + } + if part[j] != seg[i][j] { + return false + } + } + } + return true +} + +func bundle(buf io.Writer, paths []string, flat bool) error { + gw := gzip.NewWriter(buf) + defer gw.Close() + tw := tar.NewWriter(gw) + defer tw.Close() + + for _, file := range paths { + if err := func(file string) error { + f, err := os.Open(file) + if err != nil { + return err + } + defer f.Close() + + info, err := f.Stat() + if err != nil { + return err + } + + header, err := tar.FileInfoHeader(info, info.Name()) + if err != nil { + return err + } + + // Use full path as name (FileInfoHeader only takes the basename) + // If we don't do this the directory strucuture would + // not be preserved + // https://golang.org/src/archive/tar/common.go?#L626 + if !flat { + if !strings.HasPrefix(file, "/") { + file = "configui/" + file + } else { + file = "configui" + file + } + header.Name = file + } + + // Write file header to the tar archive + err = tw.WriteHeader(header) + if err != nil { + return err + } + + // Copy file content to tar archive + _, err = io.Copy(tw, f) + if err != nil { + return err + } + return nil + + }(file); err != nil { + return err + } + } + + return nil +} + +var ext2mode map[string]string = map[string]string{ + "go": "golang", + "log": "sh", + "txt": "text", + "yml": "yaml", + "conf": "ini", +} diff --git a/cmd/configui/main.go b/cmd/configui/main.go new file mode 100644 index 0000000..06ab7d0 --- /dev/null +++ b/cmd/configui/main.go @@ -0,0 +1 @@ +package main diff --git a/configui.go b/configui.go new file mode 100644 index 0000000..ba50a1b --- /dev/null +++ b/configui.go @@ -0,0 +1,42 @@ +package configui + +var APP_NAME = "ConfigUI" +var UNIX_SHELL = "sh" +var WIN_SHELL = "cmd" + +type ConfigUI struct { + ConfigPath string `json:"config_path"` + + NoReconfig bool `json:"no_reconfig"` + LogPath string `json:"log_path"` + SilentSysOut bool `json:"silent_sys_out"` + AllowIP string `json:"allow_ip"` + + Files []*File `json:"files"` + fileIndex map[string]int + + // TODO + ResultBellow bool `json:"result_bellow"` + HideConfig bool `json:"hide_config"` +} + +func New() *ConfigUI { + return &ConfigUI{ + fileIndex: map[string]int{}, + } +} + +func (cui *ConfigUI) Get(file_name string) (*File, error) { + if file_name == APP_NAME { + + } + return nil, nil +} + +func (cui *ConfigUI) LoadConfig(confstr string) { + + // construct fileIndex +} +func (cui *ConfigUI) GetConfig() []byte { + return nil +} diff --git a/insomnia.json b/docs/insomnia.json similarity index 100% rename from insomnia.json rename to docs/insomnia.json diff --git a/file.go b/file.go new file mode 100644 index 0000000..cf1a40f --- /dev/null +++ b/file.go @@ -0,0 +1,101 @@ +package configui + +import ( + "encoding/json" + "errors" + "log" + "os" + "os/exec" + "runtime" + "sync" + "time" +) + +type File struct { + Path string `json:"path"` + Name string `json:"name"` + Action string `json:"action"` + RO bool `json:"ro"` + Lang string `json:"lang"` + + // used for parsing post data + Data string `json:"data"` + + lock sync.RWMutex `json:"-"` +} + +func (f *File) Read() ([]byte, error) { + f.lock.RLock() + defer f.lock.RUnlock() + data, err := os.ReadFile(f.Path) + if err != nil { + log.Println(err) + return nil, err + } + return data, nil +} + +func (f *File) Write(data []byte) error { + if f.RO { + return errors.New("this file has readonly set") + } + f.lock.Lock() + defer f.lock.Unlock() + info, err := os.Stat(f.Path) + if err != nil { + return err + } + return os.WriteFile(f.Path, data, info.Mode()) +} + +func (f *File) Do() (string, error) { + if f.Action == "" { + return "", nil + } + timeout := time.After(2 * time.Second) + cmd := &exec.Cmd{} + if runtime.GOOS == "windows" { + cmd = exec.Command(WIN_SHELL, "/c", f.Action) + } else { + exec.Command(UNIX_SHELL, "-c", f.Action) + } + var out []byte + done := make(chan struct{}, 1) + go func() { + out, _ = cmd.CombinedOutput() + // real cmd err is only pass down + // if err != nil { + // return string(out), err + // } + done <- struct{}{} + }() + select { + case <-timeout: + cmd.Process.Kill() + return "", errors.New("command timeout") + case <-done: + return string(out), nil + } +} + +func ReadConfig(confstr string) ([]File, error) { + conf := []File{} + err := json.Unmarshal([]byte(confstr), &conf) + if err != nil { + return nil, err + } + for i := range conf { + if conf[i].Name == "" { + conf[i].Name = conf[i].Path + } + } + return conf, nil +} + +func GetFileMap(files []File) map[string]*File { + fileMap := map[string]*File{} + for i := range files { + fileMap[files[i].Name] = &files[i] + } + return fileMap +} diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..73d4077 --- /dev/null +++ b/handler.go @@ -0,0 +1 @@ +package configui diff --git a/server.go b/server.go new file mode 100644 index 0000000..73d4077 --- /dev/null +++ b/server.go @@ -0,0 +1 @@ +package configui diff --git a/templates/components/toolbar.tmpl b/templates/components/toolbar.tmpl index dea102d..f2dcf62 100644 --- a/templates/components/toolbar.tmpl +++ b/templates/components/toolbar.tmpl @@ -11,16 +11,6 @@

-

-

- -
-

+

+

+ +
+

diff --git a/util.go b/util.go index c3f057c..73d4077 100644 --- a/util.go +++ b/util.go @@ -1,118 +1 @@ -package main - -import ( - "archive/tar" - "compress/gzip" - "io" - "os" - "strings" -) - -func matchIPGlob(ip, pattern string) bool { - parts := strings.Split(pattern, ".") - seg := strings.Split(ip, ".") - for i, part := range parts { - - // normalize pattern to 3 digits - switch len(part) { - case 1: - if part == "*" { - part = "***" - } else { - part = "00" + part - } - case 2: - if strings.HasPrefix(part, "*") { - part = "*" + part - } else if strings.HasSuffix(part, "*") { - part = part + "*" - } else { - part = "0" + part - } - } - - // normalize ip to 3 digits - switch len(seg[i]) { - case 1: - seg[i] = "00" + seg[i] - case 2: - seg[i] = "0" + seg[i] - } - - for j := range part { - if string(part[j]) == "*" { - continue - } - if part[j] != seg[i][j] { - return false - } - } - } - return true -} - -func bundle(buf io.Writer, paths []string, flat bool) error { - gw := gzip.NewWriter(buf) - defer gw.Close() - tw := tar.NewWriter(gw) - defer tw.Close() - - for _, file := range paths { - if err := func(file string) error { - f, err := os.Open(file) - if err != nil { - return err - } - defer f.Close() - - info, err := f.Stat() - if err != nil { - return err - } - - header, err := tar.FileInfoHeader(info, info.Name()) - if err != nil { - return err - } - - // Use full path as name (FileInfoHeader only takes the basename) - // If we don't do this the directory strucuture would - // not be preserved - // https://golang.org/src/archive/tar/common.go?#L626 - if !flat { - if !strings.HasPrefix(file, "/") { - file = "configui/" + file - } else { - file = "configui" + file - } - header.Name = file - } - - // Write file header to the tar archive - err = tw.WriteHeader(header) - if err != nil { - return err - } - - // Copy file content to tar archive - _, err = io.Copy(tw, f) - if err != nil { - return err - } - return nil - - }(file); err != nil { - return err - } - } - - return nil -} - -var ext2mode map[string]string = map[string]string{ - "go": "golang", - "log": "sh", - "txt": "text", - "yml": "yaml", - "conf": "ini", -} +package configui