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) }