#
# Copyright (c) 2009 by Benjamin Neff <info@benjaminneff.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# moc control and now playing script for Weechat.
# (this script requires WeeChat 0.3.0 (or newer) and moc)
#
# History:
#
# 2009-10-26, Benjamin Neff <info@benjaminneff.ch>:
# version 1.7.3: - Bugfix ( "/me" --> "output_nothing" ) 2
# 2009-10-25, Benjamin Neff <info@benjaminneff.ch>:
# version 1.7.2: - Fix if moc isn't running
# 2009-10-24, Benjamin Neff <info@benjaminneff.ch>:
# version 1.7.1: - Bugfix ( "/me" --> "output_nothing" )
# 2009-10-16, Benjamin Neff <info@benjaminneff.ch>:
# version 1.7: - AvgBitrate bug
# - format Time
# 2009-09-15, Benjamin Neff <info@benjaminneff.ch>:
# version 1.6: - bugfixing ;-)
# - hook_config
# - remove i|o|ot (color-bug)
# 2009-09-08, Benjamin Neff <info@benjaminneff.ch>:
# version 1.5: initial release / port to weechat 0.3.0
#
SCRIPT_NAME = "moc_control"
SCRIPT_AUTHOR = "SuperTux88 (Benjamin Neff) <info@benjaminneff.ch>"
SCRIPT_VERSION = "1.7.3"
SCRIPT_LICENSE = "GPL2"
SCRIPT_DESC = "moc control and now playing script for Weechat"
SCRIPT_COMMAND = "moc"
import_ok = True
try:
import weechat
except ImportError:
print "This script must be run under WeeChat."
print "Get WeeChat now at: http://www.weechat.org/"
import_ok = False
try:
import os
import subprocess
import traceback
except ImportError, message:
print "Missing package(s) for %s: %s" % (SCRIPT_NAME, message)
import_ok = False
# =================================[ config ]=================================
infobar = {}
output = {}
STATUS_NOT_RUNNING = 'NOT_RUNNING'
STATUS_PLAYING = 'PLAY'
STATUS_PAUSED = 'PAUSE'
STATUS_STOPPED = 'STOP'
def load_settings(data, option, value):
"""load all settings"""
infobar['enabled'] = _load_setting('infobar_enabled', 'off', 'bool')
infobar['format'] = _load_setting('infobar_format', 'Now Playing: %mocTitle%')
infobar['update'] = _load_setting('infobar_update', '10', 'int')
output['format'] = _load_setting('output_format', '/me is listening to %C04%title%%C %artist%%album%::: %C07%file%%C ::: %cTime%/%tTime% @ %bitrate%')
output['artist'] = _load_setting('output_format_artist', '- %C03%artist%%C ')
output['album'] = _load_setting('output_format_album', '(%C12%album%%C) ')
output['nothing'] = _load_setting('output_nothing', '/me is listening to nothing')
#update config for 1.6 (i|o|ot -> +/me)
if weechat.config_is_set_plugin('output_type'):
if weechat.config_get_plugin('output_type') == 'ot':
weechat.config_set_plugin('output_format', "/me " + output['format'])
weechat.config_set_plugin('output_nothing', "/me " + output['nothing'])
output['format'] = "/me " + output['format']
output['nothing'] = "/me " + output['nothing']
weechat.config_unset_plugin('output_type')
return weechat.WEECHAT_RC_OK
def _load_setting(setting, default=None, type=None):
"""load setting or create it"""
value = weechat.config_get_plugin(setting)
if value == '' and default != None:
weechat.config_set_plugin(setting, default)
value = default
if type == 'int':
value = int(value)
if type == 'bool':
if value == "on":
value = True
elif value == "off":
value = False
else:
weechat.config_set_plugin(setting, default)
if default == "on":
value = True
elif default == "off":
value = False
return value
# ================================[ command ]=================================
def moc_command(data, buffer, args):
"""run command"""
args = args.split(' ')
if args[0] == '':
return moc_now_playing(buffer)
elif args[0] == 'pause' or args[0] == 'pp':
if _get_status() == STATUS_STOPPED:
weechat.prnt(buffer, 'moc: Not playing')
return weechat.WEECHAT_RC_OK
else:
_execute_command('mocp -G')
weechat.prnt(buffer, 'moc: Song paused / Continue playing')
return weechat.WEECHAT_RC_OK
elif args[0] == 'play':
if _get_status() == STATUS_PLAYING:
weechat.prnt(buffer, 'moc: Already playing')
return weechat.WEECHAT_RC_OK
elif _get_status() == STATUS_PAUSED:
_execute_command('mocp -U')
weechat.prnt(buffer, 'moc: Continue playing.')
return weechat.WEECHAT_RC_OK
else:
_execute_command('mocp -p')
weechat.prnt(buffer, 'moc: Started playing.')
return weechat.WEECHAT_RC_OK
elif args[0] == 'stop':
_execute_command('mocp -s')
weechat.prnt(buffer, 'moc: Stop playing.')
return weechat.WEECHAT_RC_OK
elif args[0] == 'prev':
if _get_status() == STATUS_STOPPED:
weechat.prnt(buffer, 'moc: Not playing, cannot go to previous song.')
return weechat.WEECHAT_RC_OK
else:
_execute_command('mocp -r')
weechat.prnt(buffer, 'moc: Playing previous song.')
return weechat.WEECHAT_RC_OK
elif args[0] == 'next':
if _get_status() == STATUS_STOPPED:
weechat.prnt(buffer, 'moc: Not playing, cannot go to next song.')
return weechat.WEECHAT_RC_OK
else:
_execute_command('mocp -f')
weechat.prnt(buffer, 'moc: Playing next song.')
return weechat.WEECHAT_RC_OK
elif args[0] == 'infobar':
if infobar['enabled']:
infobar['enabled'] = False
weechat.config_set_plugin('infobar_enabled', 'off')
_remove_infobar()
else:
infobar['enabled'] = True
weechat.config_set_plugin('infobar_enabled', 'on')
_add_infobar()
return weechat.WEECHAT_RC_OK
elif args[0] == 'help':
weechat.command(buffer, '/help moc')
return weechat.WEECHAT_RC_OK
else:
weechat.prnt(buffer, 'moc: Unknown command %s' % (args[0]))
return weechat.WEECHAT_RC_OK
# ================================[ infobar ]=================================
def moc_infobar_update(data, buffer, args):
"""Callback for the bar item"""
if _get_status() == STATUS_NOT_RUNNING:
return 'moc is not running'
if _get_status() == STATUS_STOPPED:
return 'moc is not currently playing'
else:
song = _get_song_info()
return _format_np(infobar['format'], song, 'infobar')
def moc_infobar_updater(data,cals):
"""Update the bar item"""
if infobar['enabled']:
weechat.bar_item_update('moc_infobar')
return weechat.WEECHAT_RC_OK
def _add_infobar():
"""add the infobar for moc_control"""
weechat.bar_new(SCRIPT_NAME, "off", "750", "window", "", "bottom", "horizontal", "vertical", "1", "0", "default", "blue", "cyan", "off", "[moc_infobar]")
def _remove_infobar():
"""remove the infobar for moc_control"""
weechat.bar_remove(weechat.bar_search(SCRIPT_NAME))
# ==============================[ now playing ]===============================
def moc_now_playing(buffer):
"""print now playing"""
format = ''
status = _get_status()
if status == STATUS_STOPPED or status == STATUS_NOT_RUNNING:
format = output['nothing']
else:
song = _get_song_info()
format = _format_np(output['format'], song, 'chat')
weechat.command(buffer, format)
return weechat.WEECHAT_RC_OK
def _format_np(np, song, npType):
"""format the 'now Playing'-String"""
np = np.replace('%mocTitle%', song['Title'])
np = np.replace('%title%', song['SongTitle'])
if npType == 'chat':
if song['Artist'] != 'unknown':
np = np.replace('%artist%', output['artist'])
np = np.replace('%artist%', song['Artist'])
else:
np = np.replace('%artist%', '')
if song['Album'] != 'unknown':
np = np.replace('%album%', output['album'])
np = np.replace('%album%', song['Album'])
else:
np = np.replace('%album%', '')
else:
np = np.replace('%artist%', song['Artist'])
np = np.replace('%album%', song['Album'])
np = np.replace('%cTime%', song['CurrentTime'])
np = np.replace('%cSec%', song['CurrentSec'])
np = np.replace('%tTime%', song['TotalTime'])
np = np.replace('%tSec%', song['TotalSec'])
np = np.replace('%bitrate%', song['Bitrate'])
np = np.replace('%avgBitrate%', song['AvgBitrate'])
np = np.replace('%rate%', song['Rate'])
np = np.replace('%file%', song['File'])
np = np.replace('%C', chr(3))
if _get_status() == STATUS_PAUSED:
np = np + " - [PAUSED]"
return np
def _get_song_info():
"""Get the song information from moc"""
song = {}
song['TotalSec'] = '??'
song['AvgBitrate'] = '???Kbps'
info = _execute_command('mocp -i')
for line in info.split('\n'):
if line != '':
index = line.find(': ')
name = line[:index]
value = line[index+2:]
if value == '':
value = 'unknown'
song[name] = value.strip()
if song['File'].find("://") < 0:
song['File'] = os.path.basename(song['File'])
if song['TotalSec'] == '??':
song['TotalTime'] = '?:??'
else:
if song['TotalTime'].find("m") > 0:
song['TotalTime'] = _format_seconds(song['TotalSec'])
if song['CurrentTime'].find("m") > 0:
song['CurrentTime'] = _format_seconds(song['CurrentSec'])
return song
def _format_seconds(s):
"""return the formated time"""
s = int(s)
temp = float()
temp = float(s) / (60 * 60 * 24)
d = int(temp)
temp = (temp - d) * 24
h = int(temp)
temp = (temp - h) * 60
m = int(temp)
temp = (temp - m) * 60
sec = temp
if d > 0:
return "%id %i:%02i:%02i" % (d, h, m, sec)
else:
return "%i:%02i:%02i" % (h, m, sec)
def _get_status():
"""return the Status of moc"""
return _execute_command('mocp -i | grep "State:" | cut -d " " -f 2').strip()
def _execute_command(cmd):
"""execute a command"""
from subprocess import PIPE
proc = subprocess.Popen(cmd, shell = True, stderr = PIPE, stdout = PIPE, close_fds = True)
error = proc.stderr.read()
if error != '':
for line in error.split('\n'):
if line == 'FATAL_ERROR: The server is not running':
return STATUS_NOT_RUNNING
output = proc.stdout.read()
proc.wait()
return output
# ==================================[ main ]==================================
if __name__ == "__main__" and import_ok:
if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "moc_unload", ""):
load_settings('', '', '')
weechat.hook_config('plugins.var.python.moc_control.*', 'load_settings', '')
weechat.bar_item_new('moc_infobar', 'moc_infobar_update', '')
weechat.hook_timer(infobar['update']*1000,0,0,'moc_infobar_updater','')
if infobar['enabled']:
_add_infobar()
weechat.hook_command(
SCRIPT_COMMAND,
'Control moc or display now playing information.',
'play|pause|pp|stop|prev|next|infobar|help',
'Commands Available\n'
' /moc - Display currently playing song.\n'
' /moc play - Start playing music.\n'
' /moc pause - Toggle between pause/playing.\n'
' /moc pp - Toggle between pause/playing.\n'
' /moc stop - Stop playing music.\n'
' /moc prev - Move to the previous song in the playlist.\n'
' /moc next - Move to the next song in the playlist.\n'
' /moc infobar - Toggle the infobar display.\n'
'\n'
'Formatting\n'
' %mocTitle% - Replaced with the title from moc.\n'
' %artist% - Replaced with the song artist.\n'
' %title% - Replaced with the song title.\n'
' %album% - Replaced with the song album.\n'
' %file% - Replaced with the filename/url of the song.\n'
' %cTime% - Replaced with how long the song has been playing.\n'
' %cSec% - Replaced with how long the song has been playing (seconcs).\n'
' %tTime% - Replaced with the length of the song.\n'
' %tSec% - Replaced with the length of the song (seconcs).\n'
' %bitrate% - Replaced with the bitrate of the song.\n'
' %avgBitrate% - Replaced with the AvgBitrate of the song.\n'
' %rate% - Replaced with the rate of the song.\n'
' %C## - Make ## the number code of the color you want to use. Use %C by itself to end the color.\n'
'\n'
'To see all available settings, please check /set *moc_control*\n',
'play|pause|pp|stop|prev|next|infobar|help',
'moc_command',
''
)
# ==================================[ end ]===================================
def moc_unload():
"""Unload the plugin from weechat"""
if infobar['enabled']:
_remove_infobar()
return weechat.WEECHAT_RC_OK