Mercurial > vixm
view vixm/ui.py @ 42:bc6db55448e1 pure
statistics engine
author | Josef "Jeff" Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sun, 05 Nov 2006 19:25:30 -0500 |
parents | 06b5a7db3d19 |
children | 2bf81d95246a |
line wrap: on
line source
# ui.py - user interface # # Copyright (C) 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. import time, sys, re from threading import Thread import playlist, song, util, control, player def run(filename): """ this is where we start execution """ # first, let's create the two playlists print "Creating playlists..." lists = {} lists[playlist.LIST_PRIO] = playlist.playlist() lists[playlist.LIST_DEFAULT] = playlist.playlist(allowrandom=True) # read in the info for all the songs in XMMS's playlist print "Loading songs from XMMS's playlist..." songs = [] idx = 0 for l in open(filename, "r").readlines(): if l[0] == "#": continue s = song.song(l[:-1], idx) lists[playlist.LIST_DEFAULT].enqueue(s) idx += 1 print "Instanciating player thread..." play = player.playerThread() play.start() print "Instanciating ui thread..." ui = uiThread(play, lists) ui.start() while not play.shutdown: # check which song we are playing now if not play.playing: play.play_next(lists) # sleep time.sleep(0.5) class uiThread(Thread): """ This is the main ui thread class, it does all the magic necessary to have a vi-like interface """ def __init__(self, play, lists): Thread.__init__(self) self.play = play self.lists = lists # commad list: # quit 'q[!]' # quit fails if there are list changes in # memory that haven't been saved. The optional # '!' forces the quit # # number '[range]n [playlistid]' # prints playlist [playlistid] (default is # LIST_PRIO) with each entry being numbered. # If optional range is supplied, only the # songs in that range are printed. The range # string is standard ed-like line range (see # below for details) # # list '[range]l [playlistid]' # virtually identical to the number command # above, however the lines are not numbered. # The same rules apply to the range and # playlistid arguments # # enqueue 'a songid' # enqueue a song songid from LIST_DEFAULT onto # LIST_PRIO. The enqueued song is added to the # end of LIST_PRIO # # dequeue '[range]d' # remove songs in range from LIST_PRIO. The # range is in LIST_PRIO, NOT LIST_DEFAULT # # range: # '' first entry; shortcut for '1' # '%' entire list; shortcut for '1,$' # '$' last entry # 'n' entry on line n # 'm,n' range of entries starting on line m and # ending on line n. Both m and n are included # in the list. m or n can both be an integer, # '' or '$'. # # command table format: # "command regexp": # (function to call, range allowed, help str) self.cmdtable = { "q([!]){,1}": (control.cmd_quit, False), "n( *([0-9]+)){,1}": (control.cmd_number, True), "l( *([0-9]+)){,1}": (control.cmd_list, True), "a *([0-9]+)": (control.cmd_enqueue, False), "d": (control.cmd_dequeue, True), "h": (control.cmd_help, False), # the following commands are there do allow some, # more direct control over which songs we play "z": (control.cmd_prev, False), "x": (control.cmd_play, False), "c": (control.cmd_pause, False), "v": (control.cmd_stop, False), "b": (control.cmd_next, False), # the following commands are there to make the # experience more like ed/ex/vi/vim "!(.*)": (control.cmd_shell, False), "=": (control.cmd_location, False), } def __cmd(self, txt): if not txt: return range_str = "(%|\\$|(\\$|[0-9]+){,1}(,(\\$|[0-9]+)){,1}){,1}" cmdtable = self.cmdtable for c in cmdtable: rstr = "^" rstr += (cmdtable[c][1] and range_str or "") rstr += c rstr += "$" m = re.search(rstr, txt) if not m: continue gr = m.groups() start = end = -1 if cmdtable[c][1]: # parse range info if gr[3]: # we got a 'm,n' start = (gr[1] or '') end = gr[3] elif gr[1]: # we got a 'n' start = gr[1] end = gr[1] elif gr[0]: # we got a '$' or '%' start = (gr[0] == '%' and '1' or '$') end = '$' else: # no range specified start = '1' end = '1' start = util.special2int(start) end = util.special2int(end) gr = list(gr) gr.pop(0) gr.pop(0) gr.pop(0) gr.pop(0) gr = list(gr) gr.append(self.cmdtable) try: cmdtable[c][0](self, start, end, gr) except ValueError: print "Invalid argument/value" return print "Invalid command \"%s\"" % (txt,) def search(self, lid, regexp): print "Seaching list %d for '%s':" % (lid, regexp) for song in self.lists[lid].search(regexp): idx = self.lists[lid].index(song)+1 print "%d. %s" % (idx, str(song)) def run(self): while not self.play.shutdown: tmp = sys.stdin.readline().strip() if tmp.startswith("/"): # '/ABC' - searching self.search(playlist.LIST_PRIO, tmp[1:]) self.search(playlist.LIST_DEFAULT, tmp[1:]) else: # 'ABC' - commands self.__cmd(tmp)