Merge pull request #163 from richese/master

Fixed localization of 'clock' formats and multiple issues with 'now_playing'.
This commit is contained in:
enkore 2015-01-19 23:02:22 +01:00
commit e47e4f3a9b
2 changed files with 80 additions and 48 deletions

View File

@ -32,11 +32,12 @@ class Clock(IntervalModule):
on_downscroll = ["scroll_format", -1] on_downscroll = ["scroll_format", -1]
def init(self): def init(self):
lang, enc = os.environ.get('LANG', None).split('.', 1)
if lang != locale.getlocale(locale.LC_TIME)[0]:
# affects datetime.time.strftime() in whole program
locale.setlocale(locale.LC_TIME, (lang, enc))
if self.format is None: if self.format is None:
lang = os.environ.get('LANG', None)
if lang:
locale.setlocale(locale.LC_ALL, lang)
lang = locale.getlocale()[0]
if lang == 'en_US': if lang == 'en_US':
# MDY format - United States of America # MDY format - United States of America
self.format = ["%a %b %-d %X"] self.format = ["%a %b %-d %X"]

View File

@ -8,39 +8,49 @@ from i3pystatus import IntervalModule, formatp
from i3pystatus.core.util import TimeWrapper from i3pystatus.core.util import TimeWrapper
class NoPlayerException(Exception):
pass
class NowPlaying(IntervalModule): class NowPlaying(IntervalModule):
""" """
Shows currently playing track information, supports most media players Shows currently playing track information, supports most media players
* Requires python-dbus available from every distros' package manager.
Left click on the module play/pauses, right click goes to the next track.
Available formatters (uses :ref:`formatp`) Available formatters (uses :ref:`formatp`)
* `{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)
* `{filename}` (file name with out extension and path; empty unless title is empty) * `{filename}` (file name with out extension and path; empty unless title is empty)
* `{song_elapsed}` (Position in the currently playing song, uses :ref:`TimeWrapper`, default is `%m:%S`) * `{song_elapsed}` (position in the currently playing song, uses :ref:`TimeWrapper`, default is `%m:%S`)
* `{song_length}` (Length of the current song, same as song_elapsed) * `{song_length}` (length of the current song, same as song_elapsed)
* `{status}` (play, pause, stop mapped through the `status` dictionary) * `{status}` (play, pause, stop mapped through the `status` dictionary)
* `{volume}` (Volume) * `{volume}` (volume)
Left click on the module play/pauses, right click goes to the next track.
Requires python-dbus available from every distros' package manager.
""" """
interval = 1 interval = 1
settings = ( settings = (
("player", "Player name"), ("player", "Player name. If not set, compatible players will be \
detected automatically."),
("status", "Dictionary mapping pause, play and stop to output text"), ("status", "Dictionary mapping pause, play and stop to output text"),
("color", "Text color"),
("format", "formatp string"), ("format", "formatp string"),
("color", "Text color"),
("format_no_player", "Text to show if no player is detected"),
("color_no_player", "Text color when no player is detected"),
("hide_no_player", "Hide output if no player is detected"), ("hide_no_player", "Hide output if no player is detected"),
) )
hide_no_player = True hide_no_player = True
player = None format_no_player = "No Player"
color_no_player = "#ffffff"
format = "{title} {status}" format = "{title} {status}"
color = "#ffffff"
status = { status = {
"pause": "", "pause": "",
"play": "", "play": "",
@ -51,18 +61,19 @@ class NowPlaying(IntervalModule):
"Paused": "pause", "Paused": "pause",
"Stopped": "stop", "Stopped": "stop",
} }
color = "#FFFFFF"
old_player = None
on_leftclick = "playpause" on_leftclick = "playpause"
on_rightclick = "next_song" on_rightclick = "next_song"
player = None
old_player = None
def find_player(self): def find_player(self):
players = [a for a in dbus.SessionBus().get_object("org.freedesktop.DBus", "/org/freedesktop/DBus").ListNames() if a.startswith("org.mpris.MediaPlayer2.")] players = [a for a in dbus.SessionBus().get_object("org.freedesktop.DBus", "/org/freedesktop/DBus").ListNames() if a.startswith("org.mpris.MediaPlayer2.")]
if self.old_player in players: if self.old_player in players:
return self.old_player return self.old_player
if not players: if not players:
raise dbus.exceptions.DBusException() raise NoPlayerException()
self.old_player = players[0] self.old_player = players[0]
return players[0] return players[0]
@ -76,45 +87,65 @@ class NowPlaying(IntervalModule):
def run(self): def run(self):
try: try:
player = self.get_player() player = self.get_player()
except dbus.exceptions.DBusException: properties = dbus.Interface(player, "org.freedesktop.DBus.Properties")
get_prop = functools.partial(properties.Get, "org.mpris.MediaPlayer2.Player")
currentsong = get_prop("Metadata")
fdict = {
"status": self.status[self.statusmap[get_prop("PlaybackStatus")]],
"len": 0, # TODO: Use optional(!) TrackList interface for this to gain 100 % mpd<->now_playing compat
"pos": 0,
"volume": int(get_prop("Volume") * 100),
"title": currentsong.get("xesam:title", ""),
"album": currentsong.get("xesam:album", ""),
"artist": ", ".join(currentsong.get("xesam:artist", "")),
"song_length": TimeWrapper((currentsong.get("mpris:length") or 0) / 1000 ** 2),
"song_elapsed": TimeWrapper((get_prop("Position") or 0) / 1000 ** 2),
"filename": "",
}
if not fdict["title"]:
fdict["filename"] = '.'.join(
basename((currentsong.get("xesam:url") or "")).split('.')[:-1])
self.output = {
"full_text": formatp(self.format, **fdict).strip(),
"color": self.color,
}
except NoPlayerException:
if self.hide_no_player: if self.hide_no_player:
self.output = None self.output = None
else: else:
self.output = { self.output = {
"full_text": "now_playing: d-bus error", "full_text": self.format_no_player,
"color": self.color_no_player,
}
return
except dbus.exceptions.DBusException as e:
if self.hide_no_player:
self.output = None
else:
self.output = {
"full_text": "DBus error: " + e.get_dbus_message(),
"color": "#ff0000", "color": "#ff0000",
} }
return return
properties = dbus.Interface(player, "org.freedesktop.DBus.Properties")
get_prop = functools.partial(properties.Get, "org.mpris.MediaPlayer2.Player")
currentsong = get_prop("Metadata")
fdict = {
"status": self.status[self.statusmap[get_prop("PlaybackStatus")]],
"len": 0, # TODO: Use optional(!) TrackList interface for this to gain 100 % mpd<->now_playing compat
"pos": 0,
"volume": int(get_prop("Volume") * 100),
"title": currentsong.get("xesam:title", ""),
"album": currentsong.get("xesam:album", ""),
"artist": ", ".join(currentsong.get("xesam:artist", "")),
"song_length": TimeWrapper((currentsong.get("mpris:length") or 0) / 1000 ** 2),
"song_elapsed": TimeWrapper((get_prop("Position") or 0) / 1000 ** 2),
"filename": "",
}
if not fdict["title"]:
fdict["filename"] = '.'.join(
basename((currentsong.get("xesam:url") or "")).split('.')[:-1])
self.output = {
"full_text": formatp(self.format, **fdict).strip(),
"color": self.color,
}
def playpause(self): def playpause(self):
self.get_player().PlayPause() try:
dbus.Interface(self.get_player(), "org.mpris.MediaPlayer2.Player").PlayPause()
except NoPlayerException:
return
except dbus.exceptions.DBusException:
return
def next_song(self): def next_song(self):
self.get_player().Next() try:
dbus.Interface(self.get_player(), "org.mpris.MediaPlayer2.Player").Next()
except NoPlayerException:
return
except dbus.exceptions.DBusException:
return