Makefile: add pickrand
[cmccabe-bin] / browse.py
1 #!/usr/bin/env python
2 import curses
3 import dircache
4 import os
5 import string
6 import time
7 import sys
8 import traceback
9
10 def MyColor(str):
11     if (str == "BLACK"):
12         return 0;
13     if (str == "BLUE"):
14         return 1;
15     if (str == "GREEN"):
16         return 2;
17     if (str == "CYAN"):
18         return 3;
19     if (str == "RED"):
20         return 4;
21     if (str == "MAGENTA"):
22         return 5;
23     if (str == "YELLOW"):
24         return 6;
25     if (str == "WHITE"):
26         return 7;
27     if (str == "BLACK_GREEN"):
28         return 8;
29     if (str == "BLACK_CYAN"):
30         return 9;
31     if (str == "BLACK_RED"):
32         return 10;
33
34 def GetFileTy(dirname, fileName):
35     if (dirname == '/kroot/media_unmount'): 
36         return 'umount_dir'
37     elif (os.path.isdir(dirname + fileName)): 
38         return 'dir'
39     else:
40         periodNum = string.rfind(fileName, '.')
41         if (periodNum < 0):
42             return 'notype'
43         extension = fileName[periodNum:].lower()
44         if extension == '.sh': return 'script'
45         elif extension == '.mp3': return 'music'
46         elif extension == '.mov': return 'movie'
47         elif extension == '.iso': return 'movieiso'
48         elif extension == '.divx': return 'movie'
49         elif extension == '.mpg': return 'movie'
50         elif extension == '.mp4': return 'movie'
51         elif extension == '.vob': return 'movie'
52         elif extension == '.avi': return 'movie'
53         elif extension == '.nes': return 'nes'
54         elif extension == '.smc': return 'snes'
55         elif extension == '.wav': return 'music' 
56     return ''
57
58 def UseFile(filePath, fileTy):
59     StopCurses()
60     if fileTy == "script":
61         os.spawnl(os.P_WAIT, filePath, filePath)
62     elif fileTy == "music":
63         os.spawnl(os.P_NOWAIT, "/usr/bin/xmms", "/usr/bin/xmms", filePath)
64     elif fileTy == "movie":
65         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-v", "85");
66         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-w", "89");
67         os.spawnl(os.P_WAIT, "/usr/local/bin/mplayer", "/usr/local/bin/mplayer", filePath);
68     elif fileTy == "movieiso":
69         os.spawnl(os.P_WAIT, "/usr/local/bin/mplayer", "/usr/local/bin/mplayer", filePath);
70     elif fileTy == "nes":
71         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-v", "65");
72         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-w", "65");
73         #start ines
74         os.spawnl(os.P_NOWAIT, ines_path, ines_path,\
75 "-ntsc", "-uperiod", "1", "-sync", "60", filePath) #"-nosound", 
76         #start the program that converts joystick presses to keypresses
77         os.spawnl(os.P_WAIT, joy2keyy_path, joy2keyy_path, "iNES Unix/X 3.0") 
78     elif fileTy == "snes":
79         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-v", "65");
80         os.spawnl(os.P_WAIT, "/usr/bin/aumix", "/usr/bin/aumix", "-w", "65");
81         os.spawnl(os.P_WAIT, "/usr/bin/snes9x", "/usr/bin/snes9x", \
82                   "-no",\
83 "-joydev1", "/dev/input/js0",\
84 "-joymap1", "1", "0", "3", "2", "10", "11", "5", "4",\
85 "-joydev2", "/dev/input/js1",\
86 "-joymap2", "1", "0", "3", "2", "10", "11", "5", "4",\
87 filePath); #'"' +filePath + '"')
88 #"-joymap1", "1", "2", "0", "3", "10", "11", "5", "4",\
89 #"-joymap2", "1", "2", "0", "3", "10", "11", "5", "4",\
90     InitCurses()
91     stdscr.getch()
92     return
93
94 def StopCurses():
95     #Stop the program
96     curses.nocbreak(); stdscr.keypad(0); curses.echo()
97     curses.endwin()
98     return
99
100
101 def InitCurses():
102     global stdscr
103     stdscr = curses.initscr()
104     curses.noecho()
105     curses.cbreak()
106     stdscr.keypad(1)
107     curses.start_color()
108
109     curses.init_pair(1,curses.COLOR_BLACK,   curses.COLOR_BLACK)
110     curses.init_pair(1,curses.COLOR_BLUE,    curses.COLOR_BLACK)
111     curses.init_pair(2,curses.COLOR_GREEN,   curses.COLOR_BLACK)
112     curses.init_pair(3,curses.COLOR_CYAN,    curses.COLOR_BLACK)
113     curses.init_pair(4,curses.COLOR_RED,     curses.COLOR_BLACK)
114     curses.init_pair(5,curses.COLOR_MAGENTA, curses.COLOR_BLACK)
115     curses.init_pair(6,curses.COLOR_YELLOW,  curses.COLOR_BLACK)
116     curses.init_pair(7,curses.COLOR_WHITE,   curses.COLOR_BLACK)
117     curses.init_pair(12,curses.COLOR_BLACK,   curses.COLOR_GREEN)
118     curses.init_pair(13,curses.COLOR_BLACK,   curses.COLOR_CYAN)
119     curses.init_pair(14,curses.COLOR_BLACK,   curses.COLOR_RED)
120     return
121
122 try:
123     #consts
124     global mplayer_path
125     global ines_path
126     global joy2key_path
127
128     #globals
129     global sleeping
130     global stdscr
131     global highNum 
132     global curdir
133     global boostX, topFileNum 
134     global numSongsOnScreen 
135
136     global TRUE
137     TRUE = 1
138     global FALSE
139     FALSE = 0
140
141     #curses initialization
142     InitCurses()
143
144     #consts
145     mplayer_path = "/usr/bin/mplayer"
146     ines_path = "/usr/bin/ines"
147     joy2keyy_path ="/home/tvman/bin/joy2keyy" 
148
149     #variable initialization
150     highNum = 0
151     boostX, topFileNum = (0,0)
152     maxY, maxX = stdscr.getmaxyx()
153     numSongsOnScreen = maxY - 2 - 2
154     sleepingPid = -1
155     sleepingFile = ""
156     curdir = "/b/"
157
158 #    ShutDown();
159 #    print numSongsOnScreen;
160 #    sys.exit(0);
161
162     #pad = curses.newpad(100, 100)
163
164     #These loops fill the pad with letters; this is
165     #explained in the next section
166 #    for y in range(0, 100):
167 #       for x in range(0, 100):
168 #           try: stdscr.addch(y,x, ord('a') + (x*x+y*y) % 26 )
169 #           except curses.error: pass
170
171 #    s = curses.newwin(5,10,2,1)
172 #    s.box()
173 #    s.refresh();
174
175     def Redraw():
176         y = 0
177         stdscr.clear()
178         stdscr.addstr(0, 0, "*" * (maxX - 1))
179         stdscr.addstr(1, 0, " " * 32 + "Welcome to Korhal")
180         stdscr.addstr(2, 0, "*" * (maxX - 1))
181         stdscr.addstr(maxY - 1, 0, "*" * (maxX - 1))
182         for f in dircache.listdir(curdir)[topFileNum:]:
183             if (y + topFileNum == highNum):
184                 stdscr.addstr(2+y+1, 1, f[:maxX-1], curses.A_STANDOUT)
185             else:
186                 fileTy = GetFileTy(curdir, f)
187                 if (fileTy == "script"): color = "RED"
188                 elif (fileTy == "mp3"): color = "GREEN"
189                 elif (fileTy == "dir"): color = "BLUE"
190                 elif (fileTy == "movie"): color = "YELLOW"
191                 elif (fileTy == "movieiso"): color = "YELLOW"
192                 elif (fileTy == "nes"): color = "MAGENTA"
193                 elif (fileTy == "snes"): color = "MAGENTA"
194                 else: color = "WHITE"
195                 stdscr.addstr(2+y+1, 1, f[:maxX-1], \
196                     curses.color_pair(MyColor(color)))
197             y = y + 1;
198             if (y == numSongsOnScreen):
199                 break
200         return
201     
202     def MoveUp(i):
203         global highNum
204         global topFileNum 
205
206         highNum = highNum - i
207         if (highNum < 0):
208             highNum = 0
209         if (highNum < topFileNum):
210             topFileNum = highNum
211         return
212
213     def MoveDown(i):
214         global highNum
215         global topFileNum 
216
217         highNum = highNum + i
218         if highNum >= len(dircache.listdir(curdir)):
219             highNum = len(dircache.listdir(curdir)) - 1
220         if (highNum >= topFileNum + numSongsOnScreen):
221             topFileNum = highNum - (numSongsOnScreen - 1)
222         return
223
224 #    def Play(s):
225 #       global stdscr
226 #       global sleepingPid
227 #       global sleepingFile
228 #
229 #       stdscr.clear()
230 #       stdscr.addstr(int(maxY / 2), 1, "Now Playing \"" + s + "\"")
231 #
232 #       if (sleepingFile == s):
233 #           #if this is the player process we put to sleep earlier,
234 #           #wake it up
235 #           os.spawnl(os.P_WAIT, '/usr/bin/kill', '/usr/bin/kill', 
236 #                       '-s', 'SIGCONT', str(sleepingPid))
237 #           pid = sleepingPid
238 #       else:
239 #           #kill any lingering sleeping player that might exist
240 #           if (sleepingPid != -1):
241 #               os.spawnl(os.P_WAIT, '/usr/bin/kill', '/usr/bin/kill', 
242 #                       '-s', 'SIGCONT', str(sleepingPid))
243 #               os.spawnl(os.P_WAIT, '/usr/bin/kill', '/usr/bin/kill', 
244 #                       '-s', 'SIGTERM', str(sleepingPid))
245 #           try:
246 #               os.wait()
247 #           except:
248 #               pass
249 #
250 #           #create new player
251 #           pid = os.fork()
252 #           if (pid == 0):
253 #               #curses.endwin()
254 #               os.execl(mpg123path, mpg123path, "-o", "esd", s)
255 #               #stdscr = curses.initscr()
256 #           
257 #       sleepingPid = -1
258 #       sleepingFile = ""
259 #       while 1:
260 #           c = stdscr.getch()
261 #           #stdscr.clear()
262 #           try:
263 #               (_,waitret) = os.waitpid(pid, os.WNOHANG)
264 #           except:
265 #               return c
266 #           #if (os.WIFEXITED(waitret) or os.WIFSIGNALED(waitret)):
267 #           if (waitret != 0):
268 #               #Mpg123 process has exited; break from this loop 
269 #               #and treat this keypress as if it had happened in the main
270 #               #input loop.
271 #               return c
272 #           if (c == ord('q')):
273 #               os.spawnl(os.P_WAIT, '/usr/bin/kill', '/usr/bin/kill', str(pid))
274 #               try:
275 #                   os.wait()
276 #               except:
277 #                   pass
278 #               #stdscr.addstr(int(maxY / 2), 1, "/usr/bin/kill"+str(pid))
279 #               #os.spawnl('/usr/bin/kill', '/usr/bin/kill', str(pid))
280 #               return -1
281 #           elif (c == ord(' ')):
282 #               sleepingPid = pid
283 #               sleepingFile = s
284 #               os.spawnl(os.P_WAIT, '/usr/bin/kill', '/usr/bin/kill',
285 #                           '-s', 'SIGSTOP', str(sleepingPid))
286 #               return -1
287
288     #Displays a section of the pad in the middle of the screen
289     #pad.refresh( 0,0, 5,5, 20,75)
290 #    dirl = dircache.listdir(curdir)
291 #    stdscr.addstr(1, 1, curdir + dirl[2], curses.A_STANDOUT)
292
293     #wait for user input
294     while 1:
295         Redraw()
296         nextc = stdscr.getch()
297         #if nextc == ord('q'):
298             #StopCurses()
299             #break
300         if nextc == curses.KEY_UP:
301             MoveUp(1)
302         elif nextc == curses.KEY_DOWN:
303             MoveDown(1)
304         elif nextc == curses.KEY_PPAGE:
305             MoveUp(numSongsOnScreen)
306         elif nextc == curses.KEY_NPAGE:
307             MoveDown(numSongsOnScreen)
308         elif nextc == ord(' '):
309             MoveDown(int(numSongsOnScreen / 2))
310         elif nextc == ord('a'):
311             fileName = dircache.listdir(curdir)[highNum]
312             path = curdir + fileName
313             UseFile(path, "music")
314         elif nextc == 10 or nextc == curses.KEY_RIGHT:
315             #Special case: if the current directory contains no items,
316             #do nothing.
317             if (dircache.listdir(curdir) != []):
318                 fileName = dircache.listdir(curdir)[highNum]
319                 path = curdir + fileName
320                 fileTy = GetFileTy(curdir, fileName)
321                 if (fileTy == 'umount_dir'):
322                     os.execl("umount", "umount", path)
323                     os.execl("eject", "eject", path)
324                 elif (fileTy == 'dir'):
325                     curdir = path + "/"
326                     highNum = 0
327                     topFileNum = 0
328                 else:
329                     UseFile(path, fileTy)
330
331         elif nextc == curses.KEY_LEFT:
332             highSlash = string.rfind(curdir[:-1], "/")
333             if (highSlash > 0):
334                 ncurdir = curdir[0:highSlash+1]
335             else:
336                 ncurdir = "/"
337
338             #Only really change the directory if we haven't 
339             #stepped out of the kroot area
340             hasRoot = string.find(ncurdir, "/b/")
341             if (hasRoot >= 0):
342                 curdir = ncurdir
343
344             highNum = 0
345             topFileNum = 0
346             nextc = -1
347
348 except:
349     StopCurses()
350     traceback.print_exc()