configui/file.go

109 lines
2.0 KiB
Go
Raw Normal View History

2021-10-18 08:49:16 +00:00
package configui
import (
"encoding/json"
2021-10-18 10:59:09 +00:00
"errors"
2021-10-18 08:49:16 +00:00
"log"
"os"
"os/exec"
"runtime"
"sync"
2021-10-21 08:04:57 +00:00
"time"
2021-10-18 08:49:16 +00:00
)
type File struct {
Path string `json:"path"`
2021-10-21 13:49:15 +00:00
Name string `json:"name"`
2021-10-18 08:49:16 +00:00
Action string `json:"action"`
2021-10-22 05:20:59 +00:00
// RO is readonly
RO bool `json:"ro"`
Lang string `json:"lang"`
// Order order of the display on ui
Order int `json:"order"`
2021-10-18 08:49:16 +00:00
// 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 {
2021-10-18 10:59:09 +00:00
if f.RO {
return errors.New("this file has readonly set")
}
2021-10-18 08:49:16 +00:00
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
}
2021-10-22 16:24:46 +00:00
f.lock.RLock()
defer f.lock.RUnlock()
2021-10-21 08:04:57 +00:00
cmd := &exec.Cmd{}
2021-10-18 08:49:16 +00:00
if runtime.GOOS == "windows" {
cmd = exec.Command(WIN_SHELL, "/c", f.Action)
2021-10-21 08:04:57 +00:00
} else {
2021-10-22 04:37:41 +00:00
cmd = exec.Command(UNIX_SHELL, "-c", f.Action)
2021-10-21 08:04:57 +00:00
}
2021-10-22 04:37:41 +00:00
log.Println("DO: ", f.Action)
2021-10-21 13:49:15 +00:00
done := make(chan string, 1)
2021-10-21 08:04:57 +00:00
go func() {
2021-10-21 13:49:15 +00:00
out, _ := cmd.CombinedOutput()
2021-10-22 04:37:41 +00:00
// real cmd err is unhandled, but passed to client
2021-10-21 08:04:57 +00:00
// if err != nil {
// return string(out), err
// }
2021-10-21 13:49:15 +00:00
done <- string(out)
2021-10-21 08:04:57 +00:00
}()
select {
2021-10-23 04:55:05 +00:00
case <-time.After(10 * time.Second):
2021-10-21 08:04:57 +00:00
cmd.Process.Kill()
2021-10-21 13:49:15 +00:00
log.Println("timeout")
2021-10-21 08:04:57 +00:00
return "", errors.New("command timeout")
2021-10-21 13:49:15 +00:00
case out := <-done:
2021-10-23 04:55:05 +00:00
log.Printf("\n%v", out)
2021-10-21 13:49:15 +00:00
return out, nil
2021-10-18 08:49:16 +00:00
}
}
func ReadConfig(confstr string) ([]File, error) {
conf := []File{}
err := json.Unmarshal([]byte(confstr), &conf)
if err != nil {
return nil, err
}
2021-10-18 15:53:49 +00:00
for i := range conf {
2021-10-21 13:49:15 +00:00
if conf[i].Name == "" {
conf[i].Name = conf[i].Path
2021-10-18 15:53:49 +00:00
}
}
2021-10-18 08:49:16 +00:00
return conf, nil
}
func GetFileMap(files []File) map[string]*File {
fileMap := map[string]*File{}
for i := range files {
2021-10-21 13:49:15 +00:00
fileMap[files[i].Name] = &files[i]
2021-10-18 08:49:16 +00:00
}
return fileMap
}