changeset 8:79340745c952

Reimplemented enqueuing & quit properly, implemented list and number commands
author Josef "Jeff" Sipek <jeffpc@josefsipek.net>
date Sat, 19 Aug 2006 19:41:06 -0400
parents f87b969fa973
children eaa800169f5b
files vixm/playlist.py vixm/ui.py
diffstat 2 files changed, 158 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/vixm/playlist.py	Sat Aug 19 17:23:15 2006 -0400
+++ b/vixm/playlist.py	Sat Aug 19 19:41:06 2006 -0400
@@ -26,3 +26,7 @@
 		""" Get item at position i """
 		return self.__list[i]
 
+	def __len__(self):
+		""" Return the length of the playlist """
+		return len(self.__list)
+
--- a/vixm/ui.py	Sat Aug 19 17:23:15 2006 -0400
+++ b/vixm/ui.py	Sat Aug 19 19:41:06 2006 -0400
@@ -1,6 +1,6 @@
 # all the user interface related bits
 
-import time, sys
+import time, sys, re
 from threading import Thread
 import xmms
 
@@ -41,33 +41,12 @@
 
 	def __enqueue(self, id):
 		s = self.lists[playlist.LIST_DEFAULT][id]
-		print "Enqueuing song: %d. %s (%s)" % (id, s["title"],
+		print "Enqueuing song: %s (%s)" % (s["title"],
 				util.strtime(s["time"]))
 		self.lists[playlist.LIST_PRIO].enqueue(s)
 
-	def __list(self, cmd, parts):
-		i = 1
-
-		if len(parts) > 1:
-			try:
-				listid = int(parts[1])
-				if listid < 0 or listid >= len(self.lists):
-					raise ValueError
-			except:
-				print "Invalid list number"
-				return
-		else:
-			listid = playlist.LIST_PRIO
-
-		for s in self.lists[listid]:
-			print "%d. %s (%s)" % (i, s["title"],
-					util.strtime(s["time"]))
-			i += 1
 
 	def __cmd(self, txt):
-		parts = txt.split()
-		cmd = parts[0]
-
 		# commad list:
 		#	quit	'q[!]'
 		#		quit fails if there are list changes in
@@ -107,15 +86,156 @@
 		#		in the list. m or n can both be an integer,
 		#		'' or '$'.
 
-		if cmd == "quit":
-			self.shutdown = True
-		elif cmd == "list":
-			self.__list(cmd, parts)
-		elif cmd == "lists":
-			print "#0 LIST_PRIO"
-			print "#1 LIST_DEFAULT"
-		else:
-			print "Invalid command \"%s\"" % (cmd,)
+		# command table format:
+		#	"command regexp":
+		#		(function to call, range allowed)
+		def __cmd_quit(ui, start, stop, args):
+			ui.shutdown = True
+
+		def __cmd_number(ui, start, stop, args):
+			__do_list(ui, start, stop, True, args)
+
+		def __cmd_list(ui, start, stop, args):
+			__do_list(ui, start, stop, False, args)
+
+		def __cmd_enqueue(ui, start, stop, args):
+			try:
+				id = int(args[0])-1
+
+				if (id < 0) or \
+				   (id >= len(ui.lists[playlist.LIST_DEFAULT])):
+					raise ValueError
+
+			except ValueError:
+				print "Invalid song id"
+				return
+
+			ui.__enqueue(id)
+
+		def __cmd_dequeue(ui, start, stop, args):
+			print "not implemented yet"
+
+		def __do_list(ui, start, stop, number, args):
+			# get the list id from the argument or default to
+			# LIST_PRIO
+			try:
+				if args[1]:
+					listid = int(args[1])
+				else:
+					listid = playlist.LIST_PRIO
+
+				if listid < 0 or listid >= len(ui.lists):
+					raise ValueError
+			except ValueError, e:
+				print "Invalid list number"
+				raise e
+	
+			max = len(ui.lists[listid])
+			if not max:
+				return
+
+			start = fixupint(start, max)
+			stop = fixupint(stop, max)
+
+			# starting number should be less than the ending
+			# number, as well as positive; ending number should
+			# be less than or equal to the size of the playlist
+			if start > stop or \
+			   start < 1 or \
+			   stop > max:
+				raise ValueError
+
+			i = 1
+			pfx = ""
+			for s in ui.lists[listid]:
+				if i < start or i > stop:
+					i += 1
+					continue
+
+				if number:
+					pfx = "%d. " % (i,)
+
+				print "%s%s (%s)" % (pfx, s["title"],
+						util.strtime(s["time"]))
+				i += 1
+
+		cmdtable = {
+			"q([!]){,1}":
+				(__cmd_quit, False),
+			"n( ([0-9]+)){,1}":
+				(__cmd_number, True),
+			"l( ([0-9]+)){,1}":
+				(__cmd_list, True),
+			"a ([0-9]+)":
+				(__cmd_enqueue, False),
+			"d ([0-9]+)":
+				(__cmd_dequeue, False),
+		}
+
+		def special2int(s):
+			if s == '$':
+				return -1
+			if s == '':
+				return 1
+			return int(s)
+
+		def fixupint(i, m):
+			if i == -1:
+				return m
+			return i
+
+		range_str = "(%|\\$|(\\$|[0-9]+){,1}(,(\\$|[0-9]+)){,1}){,1}"
+		
+		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 = special2int(start)
+				end = special2int(end)
+
+				gr = list(gr)
+				gr.pop(0)
+				gr.pop(0)
+				gr.pop(0)
+				gr.pop(0)
+				gr = tuple(gr)
+
+			try:
+				cmdtable[c][0](self, start, end, gr)
+			except ValueError:
+				print "Invalid argument/value"
+			return
+		
+		print "Invalid command \"%s\"" % (txt,)
 
 	def run(self):
 		while not self.shutdown:
@@ -131,13 +251,6 @@
 				# '/ABC' - searching
 				print "Searching not yet implemented"
 			else:
-				# 'ABC' - commands and enqueues
-				try:
-					id = int(tmp[1:])
-				except:
-					self.__cmd(tmp[1:])
-					continue
+				# 'ABC' - commands
+				self.__cmd(tmp)
 
-				# we got something numeric, let's enqueue
-				self.__enqueue(id)
-