reveil/model/routine.go

120 lines
2.2 KiB
Go

package reveil
import (
"crypto/sha512"
"io/fs"
"io/ioutil"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"git.nemunai.re/nemunaire/reveil/config"
)
type RoutineStep struct {
Delay uint64 `json:"delay"`
Action string `json:"action"`
Args []string `json:"args,omitempty"`
}
type Routine struct {
Id Identifier `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
Steps []RoutineStep `json:"steps"`
}
func LoadRoutine(path string, cfg *config.Config) ([]RoutineStep, error) {
ds, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
actionsDir, err := filepath.Abs(cfg.ActionsDir)
if err != nil {
return nil, err
}
var steps []RoutineStep
for _, f := range ds {
fullpath := filepath.Join(path, f.Name())
if f.Mode()&os.ModeSymlink == 0 {
continue
}
dst, err := os.Readlink(fullpath)
if err != nil {
return nil, err
}
if adst, err := filepath.Abs(filepath.Join(path, dst)); err == nil {
dst = adst
}
args := strings.Split(f.Name(), "_")
delay, err := strconv.ParseUint(args[0], 10, 64)
step := RoutineStep{
Delay: delay,
Action: strings.TrimPrefix(dst, actionsDir+"/"),
}
if len(args) > 1 {
step.Args = args[1:]
}
steps = append(steps, step)
}
return steps, nil
}
func LoadRoutines(cfg *config.Config) (routines []*Routine, err error) {
err = filepath.Walk(cfg.RoutinesDir, func(path string, d fs.FileInfo, err error) error {
if d.IsDir() && path != cfg.RoutinesDir {
hash := sha512.Sum512([]byte(path))
// Explore directory
steps, err := LoadRoutine(path, cfg)
if err != nil {
log.Printf("Invalid routine directory (trying to walk through %s): %s", path, err.Error())
// Ignore invalid routines
return nil
}
routines = append(routines, &Routine{
Id: hash[:],
Name: d.Name(),
Path: path,
Steps: steps,
})
}
return nil
})
return
}
func (r *Routine) Rename(newName string) error {
newPath := filepath.Join(filepath.Dir(r.Path), newName)
err := os.Rename(
r.Path,
newPath,
)
if err != nil {
return err
}
r.Path = newPath
return nil
}
func (a *Routine) Remove() error {
return os.Remove(a.Path)
}