Files
q-tools/foldermenu.py
2012-11-27 13:47:04 +02:00

229 lines
6.0 KiB
Python
Executable File

#!/usr/bin/python
import os
import sys
import subprocess
import termios
import tty
import readline
import math
readline.parse_and_bind('tab: complete')
readline.parse_and_bind('set editing-mode vi')
MENUFILE='.foldermenu'
def termsize():
rows, columns = os.popen('stty size', 'r').read().split()
return (int(rows),int(columns))
class bc:
MAG = '\033[95m'
BLU = '\033[94m'
GRE = '\033[92m'
YEL = '\033[93m'
RED = '\033[91m'
CYA = '\033[96m'
WHI = '\033[1m'
END = '\033[0m'
CLR = '\033[2J'
def disable(self):
self.MAG = ''
self.BLU = ''
self.GRE = ''
self.YEL = ''
self.RED = ''
self.END = ''
self.CLR = ''
self.CYA = ''
self.WHI = ''
def pos(self,y,x):
return "\033["+str(y)+";"+str(x)+"H"
class getch:
def __init__(self):
import sys, tty, termios
def get(self):
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def read_menu():
''' Read menu file '''
entries=[]
if os.path.exists(MENUFILE):
f=file(MENUFILE,'r')
for row in f:
if row.strip()=='':
continue
if row[0]=='#':
continue
row=row.strip().split(':',1)
if len(row)==1:
row=[row[0], row[0]]
else:
row=[row[0].strip()+' ('+row[1]+')', row[1]]
entries.append(row)
return entries
def read_folder():
''' Read folder contents, return executable files and dirs '''
dirs=[]
dirs.append(['..','..'])
executables=[]
for f in os.listdir('.'):
if os.path.isfile(f):
if os.access(f,os.X_OK):
executables.append([f,f])
if os.path.isdir(f) and f[0]!='.':
dirs.append([f,f])
dirs.sort(key=lambda x: x[0])
executables.sort(key=lambda x: x[0])
return (executables,dirs)
def print_help():
if not os.path.exists(MENUFILE):
print('Consider having a '+MENUFILE+' file containing shell commands / line.')
print('Command may be of format "My Description: my_command" or simply "my_command -switch"')
def ichr(i):
''' convert integer to 1-9, a-z, A-Z, omitting x '''
if i < 10:
return str(i)
i=i + 87
if i>119:
i=i+1
if i>122:
i=i-122+64
return chr(i)
def drawmenu(entries,dir_mode,args=""):
maxrows,maxcolumns = termsize()
maxrows-=5
maxcolumns-=10
twocol=False
co=bc()
if dir_mode:
helptext=".:execs"
else:
helptext='-:args ('+co.END+args+co.YEL+') .:folders'
print(co.END+co.CLR+co.pos(1,3)+co.YEL+'FolderMenu x:exit '+helptext+co.END)
if len(entries)>10:
twocol=True
maxrows=int(math.ceil(min(maxrows/2.0, len(entries)/2.0)))
maxcolumns=int(math.ceil(maxcolumns/2.0))
r=1
for e in range(len(entries)):
if r>maxrows:
break
printline=entries[e][1]
if len(printline)>maxcolumns:
printline=printline[:maxcolumns]+"..."
print(co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END)
r=1+r
if twocol:
r=1
for e in range(e,len(entries)):
if r>maxrows:
break
printline=entries[e][1]
if len(printline)>maxcolumns:
printline=printline[:maxcolumns]+"..."
print(co.pos(r+1,maxcolumns)+'| '+co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END)
r=1+r
print(co.pos(maxrows+2,0))
def append_index(entries,offset=0,color=None,t='menu'):
e=1+offset
for el in range(len(entries)):
entries[el]=[ichr(e), entries[el][0], entries[el][1], color,t]
e=e+1
return entries
def launch(key,entries,args=""):
''' launch the given program '''
bg=False
idx=[i for i in range(len(entries)) if entries[i][0]==key][0]
command_str=entries[idx][2]
if command_str[-1]=='&':
command_str=command_str[:-1]
bg=True
if len(args)>0:
command_str=command_str+" "+args
if entries[idx][4]=='exec':
command_str='./'+command_str
if entries[idx][4]=='dir':
os.chdir(command_str)
return
try:
print('#$ '+command_str)
if bg:
subprocess.Popen(command_str, stderr=subprocess.PIPE, shell=True,executable="/bin/bash")
else:
subprocess.call(command_str, stderr=subprocess.STDOUT, shell=True,executable="/bin/bash")
except:
print('Unable to run: "'+command_str+'"')
print('Press any key...')
ch=getch()
inkey=ord(ch.get())
def initialize():
entries=read_menu()
entries=append_index(entries, color=bc.CYA,t='menu')
[execs,dirs]=read_folder()
execs=append_index(execs, offset=len(entries), color=bc.GRE,t='exec')
entries.extend(execs)
dirs=append_index(dirs,color=bc.BLU+bc.WHI,t='dir')
return (entries,dirs)
def main():
[entries,dirs]=initialize()
show_entries=entries
dir_mode=False
ch=getch()
args=""
drawmenu(show_entries,dir_mode,args)
while True:
inkey=ord(ch.get())
#print('-'+str((inkey))+'-')
if inkey in [120,27,3,24,4]:
print_help()
print('Exited in: '+os.getcwd())
sys.exit(0)
if inkey==45: # -
readline.set_startup_hook(lambda: readline.insert_text(args))
args=raw_input('args: ')
readline.set_startup_hook(None)
if inkey==46: # .
dir_mode = not dir_mode
if chr(inkey) in [x[0] for x in show_entries]:
launch(chr(inkey),show_entries,args)
[entries,dirs]=initialize()
if dir_mode:
show_entries=dirs
else:
show_entries=entries
drawmenu(show_entries,dir_mode,args)
main()