new xmms2 bell
Недавно в git дереве полностью заменили консольный интерфейс к демону xmms2. Для меня это обернулось тем, что отвалилась моя любимая отрисовывалка песенки в трее и я решил это пофиксить.
Причем отвалилась она довольно оригинально: xmobar (мой менеджер трея) сожрал всю память. Оказалось, что команда xmms2 status больше не вставляет переводы строк в конец вывода.
На канале #xmms2 мне повосетовали написать своего клиента. Авторы больше всего шарят в python и C, так что первый вариант слепил на python. Вот его исходник:
#!/usr/bin/python
import sys
if sys.argv[1] in ['irc', 'xmobar', 'none', 'tty']:
pass
else:
print "ERROR: please choose available flavour"
1)
exit(#
# Умеем работать в нескольних режимах:
#
= sys.argv[1]
flavour #
# цвета для разных сред задаются по-разному
#
def paint(color, text):
if flavour == 'xmobar':
return "<fc=%s>%s</fc>" % (color, text)
elif flavour == 'irc':
= { 'green' : 3
colors 'brightred' : 4
, 'red' : 5
, 'yellow' : 7
, 'brightyellow' : 8
, 'cyan' : 10
, 'brightcyan' : 11
, 'gray' : 14
, 'white' : 15
,
}return "\x03%02d%s" % (colors.get(color, 15), text)
elif flavour == 'tty':
= { 'green' : 32
colors 'brightred' : 31
, 'red' : 31
, 'yellow' : 33
, 'brightyellow' : 33
, 'cyan' : 36
, 'brightcyan' : 36
, 'gray' : 30
, 'white' : 29
,
}return "\033[01;%02dm%s\033[00m" % (colors.get(color, 15), text)
elif flavour == 'none':
return text
else:
print "ERROR: bad flavour: %s" % flavour
1)
exit(import locale
'')
locale.setlocale(locale.LC_ALL, = locale.nl_langinfo(locale.CODESET)
locale_enc #
# чудо инженерной мысли: python требует явного
# перекодирования строк из его внутреннего представления
# в локаль пользователя.
#
def show(s):
print(s.encode(locale_enc
='backslashreplace'
, errors#, errors='replace'
#, errors='xmlcharrefreplace'
)
)#
# собственно сам клиент
#
import xmmsclient
= xmmsclient.XMMSSync('xmobar-tray')
xc connect()
xc.= xc.playback_current_id()
mid = xc.medialib_get_info(mid)
mdata #
# это приоритет полей, по которым осуществляются выборки:
# У нас тут ('plugin/segment', 'duration') (длина песни в плейлисте)
# будет более приоритетной, чем ('server', 'duration') (длина всего плейлиста)
#
= [ 'client/xmobar-tray'
mdata.sources 'plugin/segment'
, 'server'
, 'plugins/*'
, 'client/*'
, '*'
,
]def pp_duration(milliseconds):
= ""
result = milliseconds / 1000
seconds = seconds / 60
minutes = minutes / 60
hours = hours / 24
days = False
started_output if days > 0 or started_output: result += ("%dd " % days); started_output = True
if hours > 0 or started_output: result += ("%dh " % (hours % 24)); started_output = True
if minutes > 0 or started_output: result += ("%dm " % (minutes % 60)); started_output = True
if seconds > 0 or started_output: result += ("%ds" % (seconds % 60)); started_output = True
return result
#
# собственно, вывод:
#
' '.join(map( lambda(c,t): paint(c,t)
show('cyan', "<%s>" % mdata.get('artist', '?'))
, [ (#, ('green', "%s" % '-')
'yellow', "[%s]" % mdata.get('album', '?'))
, (#, ('green', "%s" % '-')
'red', "%s" % mdata.get('title', '?'))
, ('cyan', "[%dkbps]" % (mdata.get('bitrate', 0) / 1000))
, ('green', "%s" % pp_duration(mdata.get('duration', 0)))
, ( ])))
Результат работы команд в IRC клиенте (pse.py irc), терминале (pse.py tty), и в xmobar(pse.py xmobar): |результат|.
UPDATE: я же забыл самое главное, выпендриться!
Эта свистелка помогла найти мне баг в самом xmms2. На mac плагине я заметил, что bitrate не бывает выше 1 kbit/s (обычно 0), а это losless формат, так что цифры должны быть 600-1000 kbit/s. Оказалось, mac нетрадиционно возвращает битрейт не в битах в секунду, а в битах в миллисекунду: патч.