ask before removing existing socket

automatically removes the socket after 5 seconds of no input so that its
functions headlessly.
This commit is contained in:
Harvey Tindall 2020-08-31 20:14:14 +01:00
parent 3918d2f30e
commit f4090c1f07
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
2 changed files with 150 additions and 129 deletions

279
main.go
View File

@ -64,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
if val == "Browser" { break
file, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid)) }
if err == nil { }
cmd := string(file) if playerName == "Browser" {
for k, v := range knownBrowsers { file, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
if strings.Contains(cmd, k) { if err == nil {
playerName = v cmd := string(file)
break for key, val := range knownBrowsers {
} if strings.Contains(cmd, key) {
} playerName = val
break
} }
} }
break
} }
} }
p = &Player{ p = &Player{
@ -382,132 +382,153 @@ func main() {
fmt.Println("Response:") fmt.Println("Response:")
fmt.Printf(response) fmt.Printf(response)
} }
} else { os.Exit(0)
conn, err := dbus.SessionBus() }
if err != nil { conn, err := dbus.SessionBus()
panic(err) if err != nil {
} log.Fatalln("Error connecting to DBus:", err)
players := &PlayerList{ }
conn: conn, players := &PlayerList{
} conn: conn,
players.Reload() }
players.Sort() players.Reload()
players.Refresh() players.Sort()
fmt.Println(players.JSON()) players.Refresh()
lastLine := "" fmt.Println(players.JSON())
// fmt.Println("New array", players) lastLine := ""
// Start command listener // 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() { go func() {
os.Remove(SOCK) fmt.Scanln(&input)
listener, err := net.Listen("unix", SOCK) if strings.Contains(input, "y") && !ignoreChoice {
if err != nil { os.Remove(SOCK)
log.Fatalln("Couldn't establish socket connection at", SOCK)
} }
defer listener.Close() }()
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 {
log.Fatalln("Couldn't establish socket connection at", SOCK)
}
defer func() {
listener.Close()
os.Remove(SOCK)
}()
for {
con, err := listener.Accept()
if err != nil {
log.Println("Couldn't accept:", err)
continue
}
buf := make([]byte, 512)
nr, err := con.Read(buf)
if err != nil {
log.Println("Couldn't read:", err)
continue
}
command := string(buf[0:nr])
if command == "player-next" {
length := len(players.list)
if length != 1 {
if players.current < uint(length-1) {
players.current += 1
} else {
players.current = 0
}
players.Refresh()
fmt.Println(players.JSON())
}
} else if command == "player-prev" {
length := len(players.list)
if length != 1 {
if players.current != 0 {
players.current -= 1
} else {
players.current = uint(length - 1)
}
players.Refresh()
fmt.Println(players.JSON())
}
} else if command == "next" {
players.Next()
} else if command == "prev" {
players.Prev()
} else if command == "toggle" {
players.Toggle()
} else if command == "list" {
resp := ""
pad := 0
i := len(players.list)
for i != 0 {
i /= 10
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)
}
con.Write([]byte(resp))
} else {
fmt.Println("Invalid command")
}
}
}()
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_NOC)
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_PC)
if SHOW_POS {
go func() {
for { for {
con, err := listener.Accept() time.Sleep(1000 * time.Millisecond)
if err != nil { if players.list[players.current].playing {
log.Println("Couldn't accept:", err) go fmt.Println(players.JSON())
continue
}
buf := make([]byte, 512)
nr, err := con.Read(buf)
if err != nil {
log.Println("Couldn't read:", err)
continue
}
command := string(buf[0:nr])
if command == "player-next" {
length := len(players.list)
if length != 1 {
if players.current < uint(length-1) {
players.current += 1
} else {
players.current = 0
}
players.Refresh()
fmt.Println(players.JSON())
}
} else if command == "player-prev" {
length := len(players.list)
if length != 1 {
if players.current != 0 {
players.current -= 1
} else {
players.current = uint(length - 1)
}
players.Refresh()
fmt.Println(players.JSON())
}
} else if command == "next" {
players.Next()
} else if command == "prev" {
players.Prev()
} else if command == "toggle" {
players.Toggle()
} else if command == "list" {
resp := ""
pad := 0
i := len(players.list)
for i != 0 {
i /= 10
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)
}
con.Write([]byte(resp))
} else {
fmt.Println("Invalid command")
} }
} }
}() }()
}
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_NOC) c := make(chan *dbus.Signal, 10)
conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, MATCH_PC) conn.Signal(c)
if SHOW_POS { for v := range c {
go func() { // fmt.Printf("SIGNAL: Sender %s, Path %s, Name %s, Body %s\n", v.Sender, v.Path, v.Name, v.Body)
for { if strings.Contains(v.Name, "NameOwnerChanged") {
time.Sleep(1000 * time.Millisecond) switch name := v.Body[0].(type) {
if players.list[players.current].playing { case string:
go fmt.Println(players.JSON()) 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") {
c := make(chan *dbus.Signal, 10) players.Refresh()
conn.Signal(c) if AUTOFOCUS {
for v := range c { players.Sort()
// fmt.Printf("SIGNAL: Sender %s, Path %s, Name %s, Body %s\n", v.Sender, v.Path, v.Name, v.Body) }
if strings.Contains(v.Name, "NameOwnerChanged") { if l := players.JSON(); l != lastLine {
switch name := v.Body[0].(type) { lastLine = l
case string: fmt.Println(l)
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.