package reveil import ( "bufio" "crypto/sha512" "errors" "io/fs" "log" "os" "path/filepath" "strings" "git.nemunai.re/nemunaire/reveil/config" ) type Action struct { Id Identifier `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Path string `json:"path"` Enabled bool `json:"enabled"` } func LoadAction(path string) (string, string, error) { fd, err := os.Open(path) if err != nil { return "", "", err } defer fd.Close() fileScanner := bufio.NewScanner(fd) fileScanner.Split(bufio.ScanLines) var ( shebang = false name = "" description = "" ) for fileScanner.Scan() { line := strings.TrimSpace(fileScanner.Text()) if !shebang { if len(line) < 2 || line[0] != '#' || line[1] != '!' { return name, description, errors.New("Not a valid action file (shebang not found).") } shebang = true continue } if len(line) < 2 || line[0] != '#' { if len(description) > 0 { return name, strings.TrimSpace(description), nil } continue } if len(name) == 0 { name = strings.TrimSpace(line[1:]) } else { description += strings.TrimSpace(line[1:]) + "\n" } } return name, description, nil } func LoadActions(cfg *config.Config) (actions []*Action, err error) { actionsDir, err := filepath.Abs(cfg.ActionsDir) if err != nil { return nil, err } err = filepath.Walk(cfg.ActionsDir, func(path string, d fs.FileInfo, err error) error { if d.Mode().IsRegular() { hash := sha512.Sum512([]byte(path)) // Parse content name, description, err := LoadAction(path) if err != nil { log.Printf("Invalid action file (trying to parse %s): %s", path, err.Error()) // Ignore invalid files return nil } if description == "" { return nil } if apath, err := filepath.Abs(path); err == nil { path = apath } actions = append(actions, &Action{ Id: hash[:], Name: name, Description: description, Path: strings.TrimPrefix(path, actionsDir+"/"), Enabled: d.Mode().Perm()&0111 != 0, }) } return nil }) return } func (a *Action) Rename(name string) error { return errors.New("Not implemeted") } func (a *Action) Enable() error { fi, err := os.Stat(a.Path) if err != nil { return err } return os.Chmod(a.Path, fi.Mode().Perm()|0111) } func (a *Action) Disable() error { fi, err := os.Stat(a.Path) if err != nil { return err } return os.Chmod(a.Path, fi.Mode().Perm()&0666) } func (a *Action) Remove() error { return os.Remove(a.Path) }