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:
parent
dee02fdd93
commit
5304629cf1
@ -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):
|
||||||
|
2
setup.py
2
setup.py
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user