Compare commits

..

No commits in common. "6ed1eb428f2941b6a5ea603781f6406c221a8087" and "8fb822aa919e119f3e167faa4f7ce026cc917e1b" have entirely different histories.

2 changed files with 108 additions and 144 deletions

252
main.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"net" "net"
@ -45,7 +44,6 @@ const (
// PropertiesChanged // PropertiesChanged
MATCH_PC = "type='signal',path='/org/mpris/MediaPlayer2',interface='org.freedesktop.DBus.Properties'" MATCH_PC = "type='signal',path='/org/mpris/MediaPlayer2',interface='org.freedesktop.DBus.Properties'"
SOCK = "/tmp/waybar-mpris.sock" SOCK = "/tmp/waybar-mpris.sock"
LOGFILE = "/tmp/waybar-mpris.log"
) )
var ( var (
@ -66,19 +64,19 @@ func NewPlayer(conn *dbus.Conn, name string) (p *Player) {
for key, val := range knownPlayers { for key, val := range knownPlayers {
if strings.Contains(name, key) { if strings.Contains(name, key) {
playerName = val playerName = val
break if val == "Browser" {
} file, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
} if err == nil {
if playerName == "Browser" { cmd := string(file)
file, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid)) for k, v := range knownBrowsers {
if err == nil { if strings.Contains(cmd, k) {
cmd := string(file) playerName = v
for key, val := range knownBrowsers { break
if strings.Contains(cmd, key) { }
playerName = val }
break
} }
} }
break
} }
} }
p = &Player{ p = &Player{
@ -354,13 +352,6 @@ func (pl *PlayerList) Toggle() {
} }
func main() { func main() {
logfile, err := os.OpenFile(LOGFILE, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
log.Fatalf("Couldn't open %s for writing: %s", LOGFILE, err)
}
mw := io.MultiWriter(logfile, os.Stdout)
log.SetOutput(mw)
os.Stderr = logfile
flag.StringVar(&PLAY, "play", PLAY, "Play symbol/text to use.") flag.StringVar(&PLAY, "play", PLAY, "Play symbol/text to use.")
flag.StringVar(&PAUSE, "pause", PAUSE, "Pause symbol/text to use.") flag.StringVar(&PAUSE, "pause", PAUSE, "Pause symbol/text to use.")
flag.StringVar(&SEP, "separator", SEP, "Separator string to use between artist, album, and title.") flag.StringVar(&SEP, "separator", SEP, "Separator string to use between artist, album, and title.")
@ -391,153 +382,126 @@ func main() {
fmt.Println("Response:") fmt.Println("Response:")
fmt.Printf(response) fmt.Printf(response)
} }
os.Exit(0) } else {
} conn, err := dbus.SessionBus()
conn, err := dbus.SessionBus()
if err != nil {
log.Fatalln("Error connecting to DBus:", err)
}
players := &PlayerList{
conn: conn,
}
players.Reload()
players.Sort()
players.Refresh()
fmt.Println(players.JSON())
lastLine := ""
// fmt.Println("New array", players)
// Start command listener
if _, err := os.Stat(SOCK); err == nil {
fmt.Printf("Socket %s already exists, this could mean waybar-mpris is already running.\nStarting this instance will overwrite the file, possibly stopping other instances from accepting commands.\n", SOCK)
var input string
ignoreChoice := false
fmt.Printf("Continue? [y/n]: ")
go func() {
fmt.Scanln(&input)
if strings.Contains(input, "y") && !ignoreChoice {
os.Remove(SOCK)
}
}()
time.Sleep(5 * time.Second)
if input == "" {
fmt.Printf("\nRemoving due to lack of input.\n")
ignoreChoice = true
os.Remove(SOCK)
}
}
go func() {
listener, err := net.Listen("unix", SOCK)
if err != nil { if err != nil {
log.Fatalln("Couldn't establish socket connection at", SOCK) panic(err)
} }
defer func() { players := &PlayerList{
listener.Close() conn: conn,
}
players.Reload()
players.Sort()
players.Refresh()
fmt.Println(players.JSON())
lastLine := ""
// fmt.Println("New array", players)
// Start command listener
go func() {
os.Remove(SOCK) os.Remove(SOCK)
}() listener, err := net.Listen("unix", SOCK)
for {
con, err := listener.Accept()
if err != nil { if err != nil {
log.Println("Couldn't accept:", err) log.Fatalln("Couldn't establish socket connection at", SOCK)
continue
} }
buf := make([]byte, 512) defer listener.Close()
nr, err := con.Read(buf) for {
if err != nil { con, err := listener.Accept()
log.Println("Couldn't read:", err) if err != nil {
continue log.Println("Couldn't accept:", err)
} continue
command := string(buf[0:nr]) }
if command == "player-next" { buf := make([]byte, 512)
length := len(players.list) nr, err := con.Read(buf)
if length != 1 { if err != nil {
if players.current < uint(length-1) { log.Println("Couldn't read:", err)
continue
}
command := string(buf[0:nr])
if command == "player-next" {
if players.current < uint(len(players.list)-1) {
players.current += 1 players.current += 1
} else { } else {
players.current = 0 players.current = 0
} }
players.Refresh() players.Refresh()
fmt.Println(players.JSON()) fmt.Println(players.JSON())
} } else if command == "player-prev" {
} else if command == "player-prev" {
length := len(players.list)
if length != 1 {
if players.current != 0 { if players.current != 0 {
players.current -= 1 players.current -= 1
} else { } else {
players.current = uint(length - 1) players.current = uint(len(players.list) - 1)
} }
players.Refresh() players.Refresh()
fmt.Println(players.JSON()) fmt.Println(players.JSON())
} } else if command == "next" {
} else if command == "next" { players.Next()
players.Next() } else if command == "prev" {
} else if command == "prev" { players.Prev()
players.Prev() } else if command == "toggle" {
} else if command == "toggle" { players.Toggle()
players.Toggle() } else if command == "list" {
} else if command == "list" { resp := ""
resp := "" pad := 0
pad := 0 i := len(players.list)
i := len(players.list) for i != 0 {
for i != 0 { i /= 10
i /= 10 pad++
pad++
}
for i, p := range players.list {
symbol := ""
if uint(i) == players.current {
symbol = "*"
} }
resp += fmt.Sprintf("%0"+strconv.Itoa(pad)+"d%s: Name: %s; Playing: %t; PID: %d\n", i, symbol, p.fullName, p.playing, p.pid) for i, p := range players.list {
} symbol := ""
con.Write([]byte(resp)) if uint(i) == players.current {
} else { symbol = "*"
fmt.Println("Invalid command") }
} resp += fmt.Sprintf("%0"+strconv.Itoa(pad)+"d%s: Name: %s; Playing: %t; PID: %d\n", i, symbol, p.fullName, p.playing, p.pid)
} }
}() con.Write([]byte(resp))
} else {
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_NOC) fmt.Println("Invalid command")
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_PC)
if SHOW_POS {
go func() {
for {
time.Sleep(1000 * time.Millisecond)
if players.list[players.current].playing {
go fmt.Println(players.JSON())
} }
} }
}() }()
}
c := make(chan *dbus.Signal, 10) conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_NOC)
conn.Signal(c) conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_PC)
for v := range c { if SHOW_POS {
// fmt.Printf("SIGNAL: Sender %s, Path %s, Name %s, Body %s\n", v.Sender, v.Path, v.Name, v.Body) go func() {
if strings.Contains(v.Name, "NameOwnerChanged") { for {
switch name := v.Body[0].(type) { time.Sleep(1000 * time.Millisecond)
case string: if players.list[players.current].playing {
var pid uint32 go fmt.Println(players.JSON())
conn.BusObject().Call("org.freedesktop.DBus.GetConnectionUnixProcessID", 0, name).Store(&pid)
// Ignore playerctld again
if strings.Contains(name, INTERFACE) && !strings.Contains(name, "playerctld") {
if pid == 0 {
// fmt.Println("Removing", name)
players.Remove(name)
} else {
// fmt.Println("Adding", name)
players.New(name)
} }
} }
} }()
} else if strings.Contains(v.Name, "PropertiesChanged") && strings.Contains(v.Body[0].(string), INTERFACE+".Player") { }
players.Refresh() c := make(chan *dbus.Signal, 10)
if AUTOFOCUS { conn.Signal(c)
players.Sort() for v := range c {
} // fmt.Printf("SIGNAL: Sender %s, Path %s, Name %s, Body %s\n", v.Sender, v.Path, v.Name, v.Body)
if l := players.JSON(); l != lastLine { if strings.Contains(v.Name, "NameOwnerChanged") {
lastLine = l switch name := v.Body[0].(type) {
fmt.Println(l) case string:
var pid uint32
conn.BusObject().Call("org.freedesktop.DBus.GetConnectionUnixProcessID", 0, name).Store(&pid)
// Ignore playerctld again
if strings.Contains(name, INTERFACE) && !strings.Contains(name, "playerctld") {
if pid == 0 {
// fmt.Println("Removing", name)
players.Remove(name)
} else {
// fmt.Println("Adding", name)
players.New(name)
}
}
}
} else if strings.Contains(v.Name, "PropertiesChanged") && strings.Contains(v.Body[0].(string), INTERFACE+".Player") {
players.Refresh()
if AUTOFOCUS {
players.Sort()
}
if l := players.JSON(); l != lastLine {
lastLine = l
fmt.Println(l)
}
} }
} }
} }

Binary file not shown.