mpd-status

Utility to show mpd status in tmux
git clone https://www.brianlane.com/git/mpd-status
Log | Files | Refs | README | LICENSE

mpd-status.go (3209B)


      1 /*mpd-status - Print the artist, song title, status, elapsed time
      2 
      3   Copyright (C) 2019 Brian C. Lane <bcl@brianlane.com>
      4 
      5   This program is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as published by
      7   the Free Software Foundation; either version 2 of the License, or
      8   (at your option) any later version.
      9 
     10   This program is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public License along
     16   with this program; if not, write to the Free Software Foundation, Inc.,
     17   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     18 */
     19 package main
     20 
     21 import (
     22 	"flag"
     23 	"fmt"
     24 	"github.com/fhs/gompd/mpd"
     25 	"log"
     26 	"strings"
     27 	"time"
     28 	"unicode/utf8"
     29 )
     30 
     31 /* commandline flags */
     32 type cmdlineArgs struct {
     33 	Volume  bool // Show volume percentage 0-100
     34 	Elapsed bool // Show the duration:elapsed time
     35 	Width   int  // Maximum width
     36 }
     37 
     38 /* commandline defaults */
     39 var cfg = cmdlineArgs{
     40 	Volume:  false,
     41 	Elapsed: false,
     42 	Width:   60,
     43 }
     44 
     45 /* parseArgs handles parsing the cmdline args and setting values in the global cfg struct */
     46 func parseArgs() {
     47 	flag.BoolVar(&cfg.Volume, "volume", cfg.Volume, "Include the volume percentage 0-100")
     48 	flag.BoolVar(&cfg.Elapsed, "elapsed", cfg.Elapsed, "Include the duration:elapsed time")
     49 	flag.IntVar(&cfg.Width, "width", cfg.Width, "Maximum width of output")
     50 
     51 	flag.Parse()
     52 }
     53 
     54 func main() {
     55 	parseArgs()
     56 
     57 	// Connect to MPD server
     58 	conn, err := mpd.Dial("tcp", "localhost:6600")
     59 	if err != nil {
     60 		log.Fatalln(err)
     61 	}
     62 	defer conn.Close()
     63 
     64 	// Get the status and current song
     65 	status, err := conn.Status()
     66 	if err != nil {
     67 		log.Fatalln(err)
     68 	}
     69 	song, err := conn.CurrentSong()
     70 	if err != nil {
     71 		log.Fatalln(err)
     72 	}
     73 	// fmt.Printf("STATUS- %s\n", status)
     74 	// fmt.Printf("SONG- %s\n", song)
     75 
     76 	// Build the optional parts of the output
     77 	var optional strings.Builder
     78 	if cfg.Volume {
     79 		fmt.Fprintf(&optional, " %s%%", status["volume"])
     80 	}
     81 	if cfg.Elapsed {
     82 		duration, _ := time.ParseDuration(status["duration"] + "s")
     83 		elapsed, _ := time.ParseDuration(status["elapsed"] + "s")
     84 		fmt.Fprintf(&optional, " %s/%s", elapsed.Truncate(time.Second), duration.Truncate(time.Second))
     85 	}
     86 
     87 	// Build the final output string
     88 	var s strings.Builder
     89 	switch status["state"] {
     90 	case "play":
     91 		s.WriteString("▶ ")
     92 	case "stop":
     93 		s.WriteString("◼ ")
     94 	case "pause":
     95 		s.WriteString("‖ ")
     96 	default:
     97 		s.WriteString("  ")
     98 	}
     99 
    100 	// Build the Artist + title part (do I want to make artist optional? album?)
    101 	songStr := fmt.Sprintf("%s - %s", song["Artist"], song["Title"])
    102 
    103 	// Calculate how much title to trim
    104 	trim := cfg.Width - utf8.RuneCountInString(optional.String()) - utf8.RuneCountInString(s.String())
    105 	trim = utf8.RuneCountInString(songStr) - trim
    106 	if trim < 0 {
    107 		trim = 0
    108 	} else if trim > utf8.RuneCountInString(songStr) {
    109 		trim = utf8.RuneCountInString(songStr)
    110 	}
    111 
    112 	// Trim the title so that it will fit into the width
    113 	fmt.Printf("%s%s%s", s.String(), songStr[trim:], optional.String())
    114 }