diff --git a/i3pystatus/mpd.py b/i3pystatus/mpd.py index 33f7526..19c9903 100644 --- a/i3pystatus/mpd.py +++ b/i3pystatus/mpd.py @@ -3,6 +3,9 @@ import socket from i3pystatus import IntervalModule +def format_time(seconds): + return "{}:{:02}".format(*divmod(int(seconds), 60)) + class MPD(IntervalModule): """ Displays various information from MPD (the music player daemon) @@ -11,27 +14,36 @@ class MPD(IntervalModule): * title (the title of the current song) * album (the album of the current song, can be an empty string (e.g. for online streams)) * artist (can be empty, too) - * playtime_h (Playtime, hours) - * playtime_m (Playtime, minutes) - * playtime_s (Playtime, seconds) + * song_elapsed (Position in the currently playing song, looks like 3:54) + * song_length (Length of the current song, same format as song_elapsed) * pos (Position of current song in playlist, one-based) - * len (Length of current playlist) - * status + * len (Songs in playlist) + * status (play, pause, stop mapped through the `status` dictionary) + * bitrate (Current bitrate in kilobit/s) + * volume (Volume set in MPD) Left click on the module play/pauses, right click (un)mutes. + + `format` is the default format string and `format_sparse` is the format string for + situations where only partial metadata is available (only title, no album or artist data) + , as often the case with internet radio. + + If `format_sparse` is None (the default), the standard format string is used. """ + interval = 1 settings = ( ("host"), ("port", "MPD port"), - "format", + "format", "format_sparse", ("status", "Dictionary mapping pause, play and stop to output") ) host = "localhost" port = 6600 format = "{title} {status}" + format_sparse = None status = { "pause": "▷", "play": "▶", @@ -49,28 +61,41 @@ class MPD(IntervalModule): (line.split(": ", 1)[0], line.split(": ", 1)[1]) for line in replylines ) + def init(self): + if not self.format_sparse: + self.format_sparse = self.format + def run(self): with socket.create_connection((self.host, self.port)) as s: + # Skip "OK MPD ..." s.recv(8192) + fdict = {} status = self._mpd_command(s, "status") - fdict["pos"] = int(status.get("song", 0))+1 - fdict["len"] = int(status["playlistlength"]) - fdict["status"] = self.status[status["state"]] - currentsong = self._mpd_command(s, "currentsong") - fdict["title"] = currentsong.get("Title", "") - fdict["album"] = currentsong.get("Album", "") - fdict["artist"] = currentsong.get("Artist", "") - playtime = int(self._mpd_command(s, "stats")["playtime"]) - fdict["playtime_h"] = playtime // 3600 - fdict["playtime_m"] = (playtime % 3600) // 60 - fdict["playtime_s"] = (playtime % 3600) % 60 + fdict = { + "pos": int(status.get("song", 0))+1, + "len": int(status["playlistlength"]), + "status": self.status[status["state"]], + "volume": int(status["volume"]), + + "title": currentsong.get("Title", ""), + "album": currentsong.get("Album", ""), + "artist": currentsong.get("Artist", ""), + "song_length": format_time(currentsong.get("Time", 0)), + "song_elapsed": format_time(float(status.get("elapsed", 0))), + "bitrate": int(status.get("bitrate", 0)), + + } + + fstring = self.format + if not fdict["album"] and not fdict["artist"]: + fstring = self.format_sparse self.output = { - "full_text": self.format.format(**fdict).strip(), + "full_text": fstring.format(**fdict).strip(), } def on_leftclick(self): diff --git a/setup.py b/setup.py index f8f8d3b..834a88c 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup setup(name="i3pystatus", - version="3.19", + version="3.20", description="Like i3status, this generates status line for i3bar / i3wm", url="http://github.com/enkore/i3pystatus", license="MIT",