support serving and receiving requests for status via sockets

This commit is contained in:
Kevin Schoon 2021-07-29 13:01:25 -04:00
parent cae290eacd
commit a897198dae
5 changed files with 105 additions and 10 deletions

View File

@ -59,6 +59,21 @@ Example:
## Integrations
By default pomo will setup a Unix socket and serve it's status there.
```bash
echo | socat stdio UNIX-CONNECT:/home/kevin/.pomo/pomo.sock | jq .
{
"state": 1,
"remaining": 1492000000000,
"count": 0,
"n_pomodoros": 4
}
```
Alternately by setting the `publish` flag to `true` it will publish it's status
to an existing socket.
### Status Bars
The Pomo CLI can output the current state of a running task session via the `pomo status`
@ -76,6 +91,43 @@ interval = 1
exec = pomo status
```
#### [luastatus](https://github.com/shdown/luastatus)
Configured this bar by setting `publish` to `true`.
```lua
widget = {
plugin = "unixsock",
opts = {
path = "pomo.sock",
timeout = 2,
},
cb = function(t)
local full_text
local foreground = ""
local background = ""
if t.what == "line" then
if string.match(t.line, "R") then
-- green
foreground = "#ffffff"
background = "#307335"
end
if string.match(t.line, "B") or string.match(t.line, "P") or string.match(t.line, "C") then
-- red
foreground = "#ffffff"
background = "ff8080"
end
return { full_text = t.line, background = background, foreground = foreground }
elseif t.what == "timeout" then
return { full_text = "-" }
elseif t.what == "hello" then
return { full_text = "-" }
end
end,
}
```
## Roadmap

View File

@ -212,13 +212,13 @@ func _status(config *pomo.Config) func(*cli.Cmd) {
cmd.Action = func() {
client, err := pomo.NewClient(config.SocketPath)
if err != nil {
pomo.OutputStatus(pomo.Status{})
fmt.Println(pomo.FormatStatus(pomo.Status{}))
return
}
defer client.Close()
status, err := client.Status()
maybe(err)
pomo.OutputStatus(*status)
fmt.Println(pomo.FormatStatus(*status))
}
}
}

View File

@ -21,6 +21,12 @@ type Config struct {
DBPath string `json:"dbPath"`
SocketPath string `json:"socketPath"`
IconPath string `json:"iconPath"`
// Publish pushes updates to the configured
// SocketPath rather than listening for requests
Publish bool `json:"publish"`
// PublishJson pushes socket updates as a JSON
// encoded status message instead of string formatted
PublishJson bool `json:"publishJson"`
}
type ColorMap struct {

View File

@ -6,14 +6,18 @@ import (
"fmt"
"net"
"os"
"time"
)
// Server listens on a Unix domain socket
// for Pomo status requests
type Server struct {
listener net.Listener
runner *TaskRunner
running bool
listener net.Listener
runner *TaskRunner
running bool
publish bool
publishJson bool
socketPath string
}
func (s *Server) listen() {
@ -31,17 +35,50 @@ func (s *Server) listen() {
}
}
func (s *Server) push() {
ticker := time.NewTicker(1 * time.Second)
for s.running {
conn, err := net.Dial("unix", s.socketPath)
if err != nil {
<-ticker.C
continue
}
status := s.runner.Status()
if s.publishJson {
raw, _ := json.Marshal(status)
json.NewEncoder(conn).Encode(raw)
} else {
conn.Write([]byte(FormatStatus(*status) + "\n"))
}
conn.Close()
<-ticker.C
}
}
func (s *Server) Start() {
s.running = true
go s.listen()
if s.publish {
go s.push()
} else {
go s.listen()
}
}
func (s *Server) Stop() {
s.running = false
s.listener.Close()
if s.listener != nil {
s.listener.Close()
}
}
func NewServer(runner *TaskRunner, config *Config) (*Server, error) {
if config.Publish {
return &Server{
runner: runner,
publish: true,
publishJson: config.PublishJson,
socketPath: config.SocketPath}, nil
}
//check if socket file exists
if _, err := os.Stat(config.SocketPath); err == nil {
_, err := net.Dial("unix", config.SocketPath)

View File

@ -68,14 +68,14 @@ func SummerizeTasks(config *Config, tasks []*Task) {
}
}
func OutputStatus(status Status) {
func FormatStatus(status Status) string {
state := "?"
if status.State >= RUNNING {
state = string(status.State.String()[0])
}
if status.State == RUNNING {
fmt.Printf("%s [%d/%d] %s", state, status.Count, status.NPomodoros, status.Remaining)
return fmt.Sprintf("%s [%d/%d] %s", state, status.Count, status.NPomodoros, status.Remaining)
} else {
fmt.Printf("%s [%d/%d] -", state, status.Count, status.NPomodoros)
return fmt.Sprintf("%s [%d/%d] -", state, status.Count, status.NPomodoros)
}
}