#!/usr/bin/env python # # Copyright (C) 2005 Gopal Vijayaraghavan # # * 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; version 2 of the License. # # And yes, it might not work for you ? :) # # (Note added by Swaroop ) # To use the new handy 'j' feature: # 1. Press 'j' # 2. Enter the substring to search for. # 3. Look in the log file for the list of songs that has been matched # 4. Press Enter to play the first song in the list of matched songs # 5. Or press Escape to quit the selection # # References : # 1. python-xmms-doc package # 2. http://www.amk.ca/python/howto/curses/curses.html import xmms, curses import sys, select import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', filename='/tmp/cxmms.log', filemode='w') ESCAPE_KEY = 0x1b ENTER_KEY = 0x0a def logo(stdscr): str = ".::Commandline XMMS::." stdscr.insstr(4, 30-len(str)/2, str) stdscr.refresh() copyright = "(C) 2005, Gopal V " % ("dotgnu","org") stdscr.insstr(17, 70-len(copyright), copyright) stdscr.refresh() class xmms_main_window: def __init__(self, stdscr, top = 6): self.stdscr = stdscr self.win = curses.newwin(10, 60, top, 10) self.win.border() self.timers = self.win.subwin(2, 10, top+1, 13) self.title = self.win.subwin(3, 40, top+1, 25) self.playtime = self.win.subwin(2, 40, top+4, 25) self.volume = self.win.subwin(6, 10, top+3, 12) self.windows = [self.timers, self.playtime, self.volume, self.win, self.title] self.keymaps = { ord("x") : xmms.play, ord("c") : xmms.pause, ord("v") : xmms.stop, ord("z") : xmms.playlist_prev, ord("b") : xmms.playlist_next, 0x41 : lambda : xmms.set_main_volume(min(100, xmms.get_main_volume() + 10)), #up 0x42 : lambda : xmms.set_main_volume(max(0, xmms.get_main_volume() - 10)), #down 0x43 : lambda : xmms.jump_to_time(xmms.get_output_time()+5000), #right 0x44 : lambda : xmms.jump_to_time(max(0,xmms.get_output_time()-5000)), #left }; def update(self): secs = xmms.get_output_time()/1000 t = "%02d:%02d:%02d" % (secs/3600, (secs % 3600)/60, secs % 60) self.timers.clear() self.timers.addstr(t) t = xmms.get_playlist_title(xmms.get_playlist_pos()) self.title.clear() self.title.addstr(t) t = (xmms.get_output_time() * 40) /xmms.get_playlist_time(xmms.get_playlist_pos()) self.playtime.clear() self.playtime.hline('.', 40) self.playtime.insnstr(0, t, '%',1, curses.A_BOLD) self.volume.clear() v = xmms.get_main_volume() self.volume.insstr(0,0, 'Vol: %2d' % (v)) v = int(round(v / 10.0)) c = 0 for i in range(0, 5): if (i * 2 < v): self.volume.hline(5-i, 0, '#', 2*i-1, curses.A_BOLD) else: self.volume.hline(5-i, 0, '_', 2*i-1) # gratuitous use of lambda map(lambda a: a.refresh(), self.windows) def keyloop(self): quit = 0 logging.info("%s" % dir(self.timers)) while not quit: self.update() # select() rocks, timeout == 1 sec (read, write, err) = select.select([0], [], [], 1) # if any key pressed if 0 in read: key = self.win.getch() if key == ord('q'): quit = 1 elif key == ord('j'): logging.info("Before select_songs()") self.select_songs() logging.info("After select_songs()") else: logging.info("key pressed 0x%02x" % key) if self.keymaps.has_key(key): self.keymaps[key]() self.update() def songs_that_match(self, name): songs = [] for i in range(0, xmms.control.get_playlist_length()): title = xmms.control.get_playlist_title(i) if title.lower().find(name.lower()) > -1: songs.append((i, title)) # (position, name) return songs def select_songs(self): name = '' songs = [] while True: logging.info('List of songs that match "%s" : %s' % (name, songs)) (read, write, err) = select.select([0], [], []) if 0 in read: key = self.win.getch() if key == ESCAPE_KEY: return if key == ENTER_KEY: xmms.control.set_playlist_pos(songs[0][0]) logging.info("Now playing " + songs[0][1]) # songs[0][0] is the position of the first # (position, name) entry in the list of songs return name += chr(key) songs = self.songs_that_match(name) def main(stdscr): curses.savetty() try: logo(stdscr) w = xmms_main_window(stdscr) w.keyloop() finally: curses.resetty() # Check if XMMS is running if not xmms.control.is_running(): logging.critical('XMMS is not running') print 'XMMS is not running.' sys.exit(1) # Start the Curses UI curses.wrapper(main) # The End