execute command on state change
This commit is contained in:
parent
6236144041
commit
3d3a2bc152
21
README.md
21
README.md
|
@ -65,6 +65,27 @@ Example:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Execute command on state change
|
||||||
|
|
||||||
|
Pomo will execute the command specified in the array argument `onEvent` when the
|
||||||
|
state changes. The new state will be exported as an environment variable
|
||||||
|
`POMO_STATE` for this command. For example, to trigger a terminal bell when a
|
||||||
|
session complete, add the following to `config.json`
|
||||||
|
```
|
||||||
|
...
|
||||||
|
"onEvent": ["/bin/sh", "/path/to/script/my_script.sh"]
|
||||||
|
...
|
||||||
|
```
|
||||||
|
where the contents of `my_script.sh` are
|
||||||
|
```
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$POMO_STATE" == "COMPLETE" ] ; then
|
||||||
|
echo -e '\a'
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
Possible state values are `RUNNING`, `PAUSED`, `BREAKING`, or `COMPLETE`.
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
By default pomo will setup a Unix socket and serve it's status there.
|
By default pomo will setup a Unix socket and serve it's status there.
|
||||||
|
|
|
@ -23,6 +23,7 @@ type Config struct {
|
||||||
DBPath string `json:"dbPath"`
|
DBPath string `json:"dbPath"`
|
||||||
SocketPath string `json:"socketPath"`
|
SocketPath string `json:"socketPath"`
|
||||||
IconPath string `json:"iconPath"`
|
IconPath string `json:"iconPath"`
|
||||||
|
OnEvent []string `json:"onEvent"`
|
||||||
// Publish pushes updates to the configured
|
// Publish pushes updates to the configured
|
||||||
// SocketPath rather than listening for requests
|
// SocketPath rather than listening for requests
|
||||||
Publish bool `json:"publish"`
|
Publish bool `json:"publish"`
|
||||||
|
|
|
@ -2,6 +2,9 @@ package pomo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +24,7 @@ type TaskRunner struct {
|
||||||
notifier Notifier
|
notifier Notifier
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
onEvent []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMockedTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) {
|
func NewMockedTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) {
|
||||||
|
@ -55,6 +59,7 @@ func NewTaskRunner(task *Task, config *Config) (*TaskRunner, error) {
|
||||||
toggle: make(chan bool),
|
toggle: make(chan bool),
|
||||||
notifier: NewXnotifier(config.IconPath),
|
notifier: NewXnotifier(config.IconPath),
|
||||||
duration: task.Duration,
|
duration: task.Duration,
|
||||||
|
onEvent: config.OnEvent,
|
||||||
}
|
}
|
||||||
return tr, nil
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
@ -75,6 +80,20 @@ func (t *TaskRunner) SetState(state State) {
|
||||||
t.state = state
|
t.state = state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execute script command specified by `onEvent` on state change
|
||||||
|
func (t *TaskRunner) OnEvent() error {
|
||||||
|
app, args := t.onEvent[0], t.onEvent[1:len(t.onEvent)]
|
||||||
|
cmd := exec.Command(app, args...)
|
||||||
|
cmd.Env = append(os.Environ(),
|
||||||
|
fmt.Sprintf("POMO_STATE=%s", t.state),
|
||||||
|
)
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TaskRunner) run() error {
|
func (t *TaskRunner) run() error {
|
||||||
for t.count < t.nPomodoros {
|
for t.count < t.nPomodoros {
|
||||||
// Create a new pomodoro where we
|
// Create a new pomodoro where we
|
||||||
|
@ -85,6 +104,8 @@ func (t *TaskRunner) run() error {
|
||||||
pomodoro.Start = time.Now()
|
pomodoro.Start = time.Now()
|
||||||
// Set state to RUNNIN
|
// Set state to RUNNIN
|
||||||
t.SetState(RUNNING)
|
t.SetState(RUNNING)
|
||||||
|
// Execute onEvent command
|
||||||
|
t.OnEvent()
|
||||||
// Create a new timer
|
// Create a new timer
|
||||||
timer := time.NewTimer(t.duration)
|
timer := time.NewTimer(t.duration)
|
||||||
// Record our started time
|
// Record our started time
|
||||||
|
@ -104,6 +125,8 @@ func (t *TaskRunner) run() error {
|
||||||
remaining := t.TimeRemaining()
|
remaining := t.TimeRemaining()
|
||||||
// Change state to PAUSED
|
// Change state to PAUSED
|
||||||
t.SetState(PAUSED)
|
t.SetState(PAUSED)
|
||||||
|
// Execute onEvent command
|
||||||
|
t.OnEvent()
|
||||||
// Wait for the user to press [p]
|
// Wait for the user to press [p]
|
||||||
<-t.pause
|
<-t.pause
|
||||||
// Resume the timer with previous
|
// Resume the timer with previous
|
||||||
|
@ -114,6 +137,8 @@ func (t *TaskRunner) run() error {
|
||||||
t.duration = remaining
|
t.duration = remaining
|
||||||
// Restore state to RUNNING
|
// Restore state to RUNNING
|
||||||
t.SetState(RUNNING)
|
t.SetState(RUNNING)
|
||||||
|
// Execute onEvent command
|
||||||
|
t.OnEvent()
|
||||||
goto loop
|
goto loop
|
||||||
}
|
}
|
||||||
pomodoro.End = time.Now()
|
pomodoro.End = time.Now()
|
||||||
|
@ -128,6 +153,8 @@ func (t *TaskRunner) run() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
t.SetState(BREAKING)
|
t.SetState(BREAKING)
|
||||||
|
// Execute onEvent command
|
||||||
|
t.OnEvent()
|
||||||
t.notifier.Notify("Pomo", "It is time to take a break!")
|
t.notifier.Notify("Pomo", "It is time to take a break!")
|
||||||
// Reset the duration incase it
|
// Reset the duration incase it
|
||||||
// was paused.
|
// was paused.
|
||||||
|
@ -138,6 +165,8 @@ func (t *TaskRunner) run() error {
|
||||||
}
|
}
|
||||||
t.notifier.Notify("Pomo", "Pomo session has completed!")
|
t.notifier.Notify("Pomo", "Pomo session has completed!")
|
||||||
t.SetState(COMPLETE)
|
t.SetState(COMPLETE)
|
||||||
|
// Execute onEvent command
|
||||||
|
t.OnEvent()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue