All pastes #77871 Raw Edit

Something

public text v1 · immutable
·published 2006-07-03 14:44 UTC
rendered paste body
## Implements command /psong, which prints the currently playing song
## in RhythmBox.
## (c) 2003 Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
## 	    G-LiTe / <stephan@wilkogazu.nl>

## REQUIRES: gnome-python >= 2.0
##           Rhythmbox >= 0.5.3 (>= 0.5.99 recommended)

## WARNING: before trying this plugin, and if xchat <= 2.0.5, install
## the xchat python interface replacement:
## 	http://yang.inescn.pt/~gjc/pyxchat-0.1.tar.bz2
## Alternatively, wait for xchat 2.0.6 to be released.

## Changes in version 0.5.1:
##	- Remove .mp3 or .ogg suffix from song title (G-LiTe)

## Changes in version 0.5:
##	- Make it work with recent CVS build of Rhythmbox, including
##	  more info (Gustavo, G-LiTe)

## Changes in version 0.4:
##	- Code cleanup (Gustavo)
##      - Added missing import string (Gustavo)
##      - Make psong a subcommand of /rb (Gustavo)
##      - Added /rb prev|next|play to change and pause song (Gustavo)

## Changes in version 0.3:
##      - Prettier song display, using bold text (G-LiTe)
##      - Print song length next to the title, when using CVS Rhythmbox (G-LiTe)
##      - Detect when RB isn't playing anything, when using CVS Rhythmbox (G-LiTe)
##      - Make G-LiTe's changes not break with RB 0.5.3 (Gustavo)

rb_command_help_text = """Rhythmbox control. Usage:
/rb psong   Prints song currently playing on Rhythmbox
/rb prev    Change to the previous song
/rb next    Change to the next song"""

import pygtk; pygtk.require("2.0")
import CORBA
import xchat
import bonobo.activation
import string

__module_name__        = "xchatrb"
__module_version__     = "0.5.1"
__module_description__ = "Show song playing in rhythmbox"

# missing consts from the typelib
_ACTIVATION_FLAG_NO_LOCAL = 1<<0;      # No shared libraries
_ACTIVATION_FLAG_PRIVATE = 1<<1;       # start a new server and don't register it
_ACTIVATION_FLAG_EXISTING_ONLY = 1<<2; # don't start the server if not started


_rhythmbox = None
def get_rhythmbox():
    global _rhythmbox

    def get_new(): return bonobo.activation.activate(
	"repo_ids.has('IDL:GNOME/Rhythmbox:1.0')",
	[], _ACTIVATION_FLAG_EXISTING_ONLY)

    if _rhythmbox is None:
	_rhythmbox = get_new()
    else:
	# Check if the cached reference points to a server that is
	# still alive, otherwise ask bonobo-activation for a new fresh
	# reference.
	try:
	    # basically this means: _rhythmbox.ping()
	    _rhythmbox.ref()
	    _rhythmbox.unref()
	except CORBA.COMM_FAILURE:
	    _rhythmbox = get_new()
    return _rhythmbox

def psong(word, word_eol, userdata):
    rb = get_rhythmbox()
    if rb is None:
	print "Rhythmbox is not running"
	return xchat.EAT_ALL
    
    outlist = []
    try:
	outlist.append(rb.getPlayingTitle())
	duration = None
    except AttributeError:
	pb = rb.getPlayerProperties()
	info = pb.getValue("song").value()
	pb.unref()
	if info is None:
	    print "Rhythmbox is not playing anything"
	    return xchat.EAT_ALL
	if info.artist:
	    outlist.append(info.artist)
	if info.album:
	    outlist.append(info.album)
	if info.track_number != -1:
	    tracknumber = "\x02%i.\x02" % info.track_number
	else:
	    tracknumber = ""
	if info.title:
	    title = info.title
	    if title.endswith('.mp3') or title.endswith('.ogg'):
		title = title[:-4]
	    outlist.append(' '.join((tracknumber, title)))
	duration = info.duration

    if duration is None:
	try:
	    duration = rb.getPlayingSongDuration()
	except AttributeError:
	    pass

    if duration is None or duration == 0:
	duration_str = ""
    else:
	if duration == -1:
	    print "Rhythmbox is not playing anything"
	    return xchat.EAT_ALL
	else:
	    hours    = duration // 3600
	    duration = duration % 3600
	    minutes  = duration // 60
	    duration = duration % 60
	    duration_str = str(minutes) + ":" + str(duration).zfill(2)
	    if hours == 0:
		duration_str = '%s:%s' % (str(minutes), str(duration).zfill(2))
	    else:
		duration_str = '%s:%s:%s' % (str(hours), str(minutes).zfill(2),
					     str(duration).zfill(2))

    xchat.command("ME is listening to \x02-< %s (\x02%s\x02) >-\x02" % \
		  (' - '.join(outlist), duration_str))
    return xchat.EAT_ALL

def rb_next(word, word_eol, userdata):
    rb = get_rhythmbox()
    if rb is None:
	print "Rhythmbox is not running"
	return xchat.EAT_ALL
    try:
	rb.next()
    except AttributeError():
	print "Your Rhythmbox version doesn't support this operation"
    return xchat.EAT_ALL

def rb_prev(word, word_eol, userdata):
    rb = get_rhythmbox()
    if rb is None:
	print "Rhythmbox is not running"
	return xchat.EAT_ALL
    try:
	rb.previous()
    except AttributeError():
	print "Your Rhythmbox version doesn't support this operation"
    return xchat.EAT_ALL

def rb_play(word, word_eol, userdata):
    rb = get_rhythmbox()
    if rb is None:
	print "Rhythmbox is not running"
	return xchat.EAT_ALL
    try:
	rb.playPause()
    except AttributeError():
	print "Your Rhythmbox version doesn't support this operation"
    return xchat.EAT_ALL

def rb_command_cb(word, word_eol, userdata):
    try:
	if word[1].lower() == 'psong':
	    return psong(word[1:], word_eol[1:], userdata)
	if word[1].lower() == 'next':
	    return rb_next(word[1:], word_eol[1:], userdata)
	if word[1].lower() == 'prev':
	    return rb_prev(word[1:], word_eol[1:], userdata)
	if word[1].lower() == 'play':
	    return rb_play(word[1:], word_eol[1:], userdata)
    except IndexError:
	print rb_command_help_text
    return xchat.EAT_ALL

# ----------------------------------------------------------------------------
xchat.hook_command("rb", rb_command_cb, help=rb_command_help_text)

print "XChat-Rhythmbox (xchatrb %s) module loaded" % __module_version__
print "Type /help rb for help"

# EOF