3.20: Extend MPD module

-Removed playtime_* formatters (pretty much useless)
-Add bitrate formatter
-Add volume formatter
-Add song_elapsed formatter
-Add song_length formatter
-Add format_sparse option (intended for streams/internet radio or untagged media)
This commit is contained in:
enkore 2013-07-31 21:07:45 +02:00
parent dee02fdd93
commit 5304629cf1
2 changed files with 44 additions and 19 deletions

View File

@ -3,6 +3,9 @@ import socket
from i3pystatus import IntervalModule from i3pystatus import IntervalModule
def format_time(seconds):
return "{}:{:02}".format(*divmod(int(seconds), 60))
class MPD(IntervalModule): class MPD(IntervalModule):
""" """
Displays various information from MPD (the music player daemon) Displays various information from MPD (the music player daemon)
@ -11,27 +14,36 @@ class MPD(IntervalModule):
* title (the title of the current song) * title (the title of the current song)
* album (the album of the current song, can be an empty string (e.g. for online streams)) * album (the album of the current song, can be an empty string (e.g. for online streams))
* artist (can be empty, too) * artist (can be empty, too)
* playtime_h (Playtime, hours) * song_elapsed (Position in the currently playing song, looks like 3:54)
* playtime_m (Playtime, minutes) * song_length (Length of the current song, same format as song_elapsed)
* playtime_s (Playtime, seconds)
* pos (Position of current song in playlist, one-based) * pos (Position of current song in playlist, one-based)
* len (Length of current playlist) * len (Songs in playlist)
* status * 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. 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 interval = 1
settings = ( settings = (
("host"), ("host"),
("port", "MPD port"), ("port", "MPD port"),
"format", "format", "format_sparse",
("status", "Dictionary mapping pause, play and stop to output") ("status", "Dictionary mapping pause, play and stop to output")
) )
host = "localhost" host = "localhost"
port = 6600 port = 6600
format = "{title} {status}" format = "{title} {status}"
format_sparse = None
status = { status = {
"pause": "", "pause": "",
"play": "", "play": "",
@ -49,28 +61,41 @@ class MPD(IntervalModule):
(line.split(": ", 1)[0], line.split(": ", 1)[1]) for line in replylines (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): def run(self):
with socket.create_connection((self.host, self.port)) as s: with socket.create_connection((self.host, self.port)) as s:
# Skip "OK MPD ..."
s.recv(8192) s.recv(8192)
fdict = {} fdict = {}
status = self._mpd_command(s, "status") 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") 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 = {
fdict["playtime_h"] = playtime // 3600 "pos": int(status.get("song", 0))+1,
fdict["playtime_m"] = (playtime % 3600) // 60 "len": int(status["playlistlength"]),
fdict["playtime_s"] = (playtime % 3600) % 60 "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 = { self.output = {
"full_text": self.format.format(**fdict).strip(), "full_text": fstring.format(**fdict).strip(),
} }
def on_leftclick(self): def on_leftclick(self):

View File

@ -3,7 +3,7 @@
from setuptools import setup from setuptools import setup
setup(name="i3pystatus", setup(name="i3pystatus",
version="3.19", version="3.20",
description="Like i3status, this generates status line for i3bar / i3wm", description="Like i3status, this generates status line for i3bar / i3wm",
url="http://github.com/enkore/i3pystatus", url="http://github.com/enkore/i3pystatus",
license="MIT", license="MIT",