## Implements command /psong, which prints the currently playing song ## in RhythmBox. ## (c) 2003 Gustavo J. A. M. Carneiro ## G-LiTe / ## 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