aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod5
-rw-r--r--go.sum18
-rw-r--r--main.go300
-rwxr-xr-xwaybar-mprisbin4804992 -> 4362867 bytes
4 files changed, 184 insertions, 139 deletions
diff --git a/go.mod b/go.mod
index 88a35ef..11fa2ba 100644
--- a/go.mod
+++ b/go.mod
@@ -3,12 +3,9 @@ module git.hrfee.pw/hrfee/waybar-mpris
go 1.15
require (
- github.com/fsnotify/fsnotify v1.4.9 // indirect
+ github.com/fsnotify/fsnotify v1.4.9
github.com/godbus/dbus/v5 v5.0.3
- github.com/hpcloud/tail v1.0.0
github.com/hrfee/mpris2client v0.0.5
github.com/spf13/pflag v1.0.5
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 // indirect
- gopkg.in/fsnotify.v1 v1.4.7 // indirect
- gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
diff --git a/go.sum b/go.sum
index 3634c75..147a035 100644
--- a/go.sum
+++ b/go.sum
@@ -2,28 +2,10 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hrfee/mpris2client v0.0.0-20210108004725-d2a36745cc4a h1:3H1awMdF3eJBCg0QPpDtNW+ujQPvUCuLsqlMRoODMA4=
-github.com/hrfee/mpris2client v0.0.0-20210108004725-d2a36745cc4a/go.mod h1:tVpzzAlsljmQevNA4mJwUy1onUUiaQcRAa4gdl37okY=
-github.com/hrfee/mpris2client v0.0.0-20210115213010-244c4cd6a569 h1:aCHzdXajnRUeaaW9FHzunrjGcRqmyFedwO0ODJRAdBk=
-github.com/hrfee/mpris2client v0.0.0-20210115213010-244c4cd6a569/go.mod h1:tVpzzAlsljmQevNA4mJwUy1onUUiaQcRAa4gdl37okY=
-github.com/hrfee/mpris2client v0.0.2 h1:AqsDoJCKyKjSGwVk3sJ5fjx+7M0tsSueZbVUIDxS1xI=
-github.com/hrfee/mpris2client v0.0.2/go.mod h1:tVpzzAlsljmQevNA4mJwUy1onUUiaQcRAa4gdl37okY=
-github.com/hrfee/mpris2client v0.0.4 h1:2WnCkTWGBr1eg3qHFjxDo7hIeCeQWh3jJ0hFJSts9Ks=
-github.com/hrfee/mpris2client v0.0.4/go.mod h1:tVpzzAlsljmQevNA4mJwUy1onUUiaQcRAa4gdl37okY=
github.com/hrfee/mpris2client v0.0.5 h1:h3gcb8Q68i6SfcEgOxL9cXcGee9ekvxXltrUxGwRLDU=
github.com/hrfee/mpris2client v0.0.5/go.mod h1:tVpzzAlsljmQevNA4mJwUy1onUUiaQcRAa4gdl37okY=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200928205150-006507a75852 h1:sXxgOAXy8JwHhZnPuItAlUtwIlxrlEqi28mKhUR+zZY=
-golang.org/x/sys v0.0.0-20200928205150-006507a75852/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201116194326-cc9327a14d48 h1:AYCWBZhgIw6XobZ5CibNJr0Rc4ZofGGKvWa1vcx2IGk=
-golang.org/x/sys v0.0.0-20201116194326-cc9327a14d48/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
diff --git a/main.go b/main.go
index 4135e78..f4bf549 100644
--- a/main.go
+++ b/main.go
@@ -11,8 +11,8 @@ import (
"strings"
"time"
+ "github.com/fsnotify/fsnotify"
"github.com/godbus/dbus/v5"
- "github.com/hpcloud/tail"
mpris2 "github.com/hrfee/mpris2client"
flag "github.com/spf13/pflag"
)
@@ -37,6 +37,7 @@ var (
SHOW_POS = false
INTERPOLATE = false
REPLACE = false
+ isSharing = false
WRITER io.Writer = os.Stdout
)
@@ -129,6 +130,182 @@ func (pl *players) Prev() { pl.mpris2.List[pl.mpris2.Current].Previous() }
func (pl *players) Toggle() { pl.mpris2.List[pl.mpris2.Current].Toggle() }
+func execCommand(cmd string) {
+ conn, err := net.Dial("unix", SOCK)
+ if err != nil {
+ log.Fatalln("Couldn't dial:", err)
+ }
+ _, err = conn.Write([]byte(cmd))
+ if err != nil {
+ log.Fatalln("Couldn't send command")
+ }
+ fmt.Println("Sent.")
+ if cmd == "list" {
+ buf := make([]byte, 512)
+ nr, err := conn.Read(buf)
+ if err != nil {
+ log.Fatalln("Couldn't read response.")
+ }
+ response := string(buf[0:nr])
+ fmt.Println("Response:")
+ fmt.Printf(response)
+ }
+ os.Exit(0)
+}
+
+func duplicateOutput(conn net.Conn) {
+ // Print to stderr to avoid errors from waybar
+ os.Stderr.WriteString("waybar-mpris is already running. This instance will clone its output.")
+ // Tell other instance to share output in OUTFILE
+ _, err := conn.Write([]byte("share"))
+ if err != nil {
+ log.Fatalf("Couldn't send command: %v", err)
+ }
+ buf := make([]byte, 512)
+ nr, err := conn.Read(buf)
+ if err != nil {
+ log.Fatalf("Couldn't read response: %v", err)
+ }
+ if resp := string(buf[0:nr]); resp == "success" {
+ // t, err := tail.TailFile(OUTFILE, tail.Config{
+ // Follow: true,
+ // MustExist: true,
+ // Logger: tail.DiscardingLogger,
+ // })
+ // if err == nil {
+ // for line := range t.Lines {
+ // fmt.Println(line.Text)
+ // }
+ // }
+ f, err := os.Open(OUTFILE)
+ if err != nil {
+ log.Fatalf("Failed to open \"%s\": %v", OUTFILE, err)
+ }
+ watcher, err := fsnotify.NewWatcher()
+ if err != nil {
+ log.Fatalf("Failed to start watcher: %v", err)
+ }
+ defer watcher.Close()
+ err = watcher.Add(OUTFILE)
+ if err != nil {
+ log.Fatalf("Failed to watch file: %v", err)
+ }
+ for {
+ select {
+ case event, ok := <-watcher.Events:
+ if !ok {
+ log.Printf("Watcher failed: %v", err)
+ return
+ }
+ if event.Op&fsnotify.Write == fsnotify.Write {
+ l, err := io.ReadAll(f)
+ if err != nil {
+ log.Printf("Failed to read file: %v", err)
+ return
+ }
+ str := string(l)
+ if str[len(str)-2:] == "\n\n" {
+ fmt.Print(str[:len(str)-1])
+ } else {
+ fmt.Print(string(l))
+ }
+ f.Seek(0, 0)
+ }
+ }
+ }
+ }
+
+}
+
+func listenForCommands(players *players) {
+ listener, err := net.Listen("unix", SOCK)
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt)
+ go func() {
+ <-c
+ os.Remove(OUTFILE)
+ os.Remove(SOCK)
+ os.Exit(1)
+ }()
+ if err != nil {
+ log.Fatalf("Couldn't establish socket connection at %s (error %s)\n", SOCK, err)
+ }
+ 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])
+ switch command {
+ case "player-next":
+ length := len(players.mpris2.List)
+ if length != 1 {
+ if players.mpris2.Current < uint(length-1) {
+ players.mpris2.Current++
+ } else {
+ players.mpris2.Current = 0
+ }
+ players.mpris2.Refresh()
+ }
+ case "player-prev":
+ length := len(players.mpris2.List)
+ if length != 1 {
+ if players.mpris2.Current != 0 {
+ players.mpris2.Current--
+ } else {
+ players.mpris2.Current = uint(length - 1)
+ }
+ players.mpris2.Refresh()
+ }
+ case "next":
+ players.Next()
+ case "prev":
+ players.Prev()
+ case "toggle":
+ players.Toggle()
+ case "list":
+ con.Write([]byte(players.mpris2.String()))
+ case "share":
+ if !isSharing {
+ f, err := os.OpenFile(OUTFILE, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
+ defer f.Close()
+ if err != nil {
+ fmt.Fprintf(con, "Failed: %v", err)
+ }
+ var out io.Writer = emptyEveryWrite{file: f}
+ WRITER = io.MultiWriter(os.Stdout, out)
+ isSharing = true
+ }
+ fmt.Fprint(con, "success")
+ default:
+ fmt.Println("Invalid command")
+ }
+ }
+}
+
+type emptyEveryWrite struct {
+ file *os.File
+}
+
+func (w emptyEveryWrite) Write(p []byte) (n int, err error) {
+ offset, err := w.file.Seek(0, 0)
+ if err != nil {
+ return 0, err
+ }
+ return w.file.WriteAt(p, offset)
+}
+
func main() {
logfile, err := os.OpenFile(LOGFILE, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
@@ -151,26 +328,7 @@ func main() {
os.Stderr = logfile
if command != "" {
- conn, err := net.Dial("unix", SOCK)
- if err != nil {
- log.Fatalln("Couldn't dial:", err)
- }
- _, err = conn.Write([]byte(command))
- if err != nil {
- log.Fatalln("Couldn't send command")
- }
- fmt.Println("Sent.")
- if command == "list" {
- buf := make([]byte, 512)
- nr, err := conn.Read(buf)
- if err != nil {
- log.Fatalln("Couldn't read response.")
- }
- response := string(buf[0:nr])
- fmt.Println("Response:")
- fmt.Printf(response)
- }
- os.Exit(0)
+ execCommand(command)
}
// fmt.Println("New array", players)
// Start command listener
@@ -194,33 +352,11 @@ func main() {
}
} else if conn, err := net.Dial("unix", SOCK); err == nil {
// When waybar-mpris is already running, we attach to its output instead of launching a whole new instance.
- // Print to stderr to avoid errors from waybar
- os.Stderr.WriteString("waybar-mpris is already running. This instance will clone its output.")
- if err != nil {
- log.Fatalln("Couldn't dial:", err)
- }
- _, err = conn.Write([]byte("share"))
- if err != nil {
- log.Fatalln("Couldn't send command")
- }
- buf := make([]byte, 512)
- nr, err := conn.Read(buf)
+ duplicateOutput(conn)
+ } else {
if err != nil {
- log.Fatalln("Couldn't read response.")
- }
- if string(buf[0:nr]) == "success" {
- t, err := tail.TailFile(OUTFILE, tail.Config{
- Follow: true,
- MustExist: true,
- Logger: tail.DiscardingLogger,
- })
- if err == nil {
- for line := range t.Lines {
- fmt.Println(line.Text)
- }
- }
+ os.Stdout.WriteString("Couldn't dial socket, deleting instead: " + err.Error())
}
- } else {
os.Remove(SOCK)
os.Remove(OUTFILE)
}
@@ -235,77 +371,7 @@ func main() {
players.mpris2.Reload()
players.mpris2.Sort()
lastLine := ""
- go func() {
- listener, err := net.Listen("unix", SOCK)
- c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt)
- go func() {
- <-c
- os.Remove(OUTFILE)
- os.Remove(SOCK)
- os.Exit(1)
- }()
- if err != nil {
- log.Fatalf("Couldn't establish socket connection at %s (error %s)\n", SOCK, err)
- }
- 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])
- switch command {
- case "player-next":
- length := len(players.mpris2.List)
- if length != 1 {
- if players.mpris2.Current < uint(length-1) {
- players.mpris2.Current++
- } else {
- players.mpris2.Current = 0
- }
- players.mpris2.Refresh()
- }
- case "player-prev":
- length := len(players.mpris2.List)
- if length != 1 {
- if players.mpris2.Current != 0 {
- players.mpris2.Current--
- } else {
- players.mpris2.Current = uint(length - 1)
- }
- players.mpris2.Refresh()
- }
- case "next":
- players.Next()
- case "prev":
- players.Prev()
- case "toggle":
- players.Toggle()
- case "list":
- con.Write([]byte(players.mpris2.String()))
- case "share":
- out, err := os.Create(OUTFILE)
- if err != nil {
- con.Write([]byte(fmt.Sprintf("Failed: %s", err)))
- }
- WRITER = io.MultiWriter(os.Stdout, out)
- con.Write([]byte("success"))
- default:
- fmt.Println("Invalid command")
- }
- }
- }()
+ go listenForCommands(players)
go players.mpris2.Listen()
if SHOW_POS {
go func() {
diff --git a/waybar-mpris b/waybar-mpris
index 8f71aec..a940dcf 100755
--- a/waybar-mpris
+++ b/waybar-mpris
Binary files differ