support serving and receiving requests for status via sockets
This commit is contained in:
parent
cae290eacd
commit
a897198dae
52
README.md
52
README.md
|
@ -59,6 +59,21 @@ Example:
|
||||||
|
|
||||||
## Integrations
|
## 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
|
### Status Bars
|
||||||
|
|
||||||
The Pomo CLI can output the current state of a running task session via the `pomo status`
|
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
|
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
|
## Roadmap
|
||||||
|
|
||||||
|
|
|
@ -212,13 +212,13 @@ func _status(config *pomo.Config) func(*cli.Cmd) {
|
||||||
cmd.Action = func() {
|
cmd.Action = func() {
|
||||||
client, err := pomo.NewClient(config.SocketPath)
|
client, err := pomo.NewClient(config.SocketPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pomo.OutputStatus(pomo.Status{})
|
fmt.Println(pomo.FormatStatus(pomo.Status{}))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
status, err := client.Status()
|
status, err := client.Status()
|
||||||
maybe(err)
|
maybe(err)
|
||||||
pomo.OutputStatus(*status)
|
fmt.Println(pomo.FormatStatus(*status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,12 @@ 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"`
|
||||||
|
// 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 {
|
type ColorMap struct {
|
||||||
|
|
|
@ -6,14 +6,18 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server listens on a Unix domain socket
|
// Server listens on a Unix domain socket
|
||||||
// for Pomo status requests
|
// for Pomo status requests
|
||||||
type Server struct {
|
type Server struct {
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
runner *TaskRunner
|
runner *TaskRunner
|
||||||
running bool
|
running bool
|
||||||
|
publish bool
|
||||||
|
publishJson bool
|
||||||
|
socketPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) listen() {
|
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() {
|
func (s *Server) Start() {
|
||||||
s.running = true
|
s.running = true
|
||||||
go s.listen()
|
if s.publish {
|
||||||
|
go s.push()
|
||||||
|
} else {
|
||||||
|
go s.listen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Stop() {
|
func (s *Server) Stop() {
|
||||||
s.running = false
|
s.running = false
|
||||||
s.listener.Close()
|
if s.listener != nil {
|
||||||
|
s.listener.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(runner *TaskRunner, config *Config) (*Server, error) {
|
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
|
//check if socket file exists
|
||||||
if _, err := os.Stat(config.SocketPath); err == nil {
|
if _, err := os.Stat(config.SocketPath); err == nil {
|
||||||
_, err := net.Dial("unix", config.SocketPath)
|
_, err := net.Dial("unix", config.SocketPath)
|
||||||
|
|
|
@ -68,14 +68,14 @@ func SummerizeTasks(config *Config, tasks []*Task) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func OutputStatus(status Status) {
|
func FormatStatus(status Status) string {
|
||||||
state := "?"
|
state := "?"
|
||||||
if status.State >= RUNNING {
|
if status.State >= RUNNING {
|
||||||
state = string(status.State.String()[0])
|
state = string(status.State.String()[0])
|
||||||
}
|
}
|
||||||
if status.State == RUNNING {
|
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 {
|
} else {
|
||||||
fmt.Printf("%s [%d/%d] -", state, status.Count, status.NPomodoros)
|
return fmt.Sprintf("%s [%d/%d] -", state, status.Count, status.NPomodoros)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue