|
@ -43,6 +43,7 @@ import locale |
|
|
import curses |
|
|
import curses |
|
|
from curses.textpad import Textbox |
|
|
from curses.textpad import Textbox |
|
|
|
|
|
|
|
|
|
|
|
from django.core.exceptions import ValidationError |
|
|
from django.db.models.fields.related import ForeignKey |
|
|
from django.db.models.fields.related import ForeignKey |
|
|
from django.db import models |
|
|
from django.db import models |
|
|
|
|
|
|
|
@ -52,187 +53,6 @@ from mumble.forms import * |
|
|
locale.setlocale(locale.LC_ALL, '') |
|
|
locale.setlocale(locale.LC_ALL, '') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getNum( prompt, **kwargs ): |
|
|
|
|
|
id = None; |
|
|
|
|
|
while type(id) != int: |
|
|
|
|
|
print |
|
|
|
|
|
try: |
|
|
|
|
|
id = raw_input( "%s >>> " % prompt ).strip(); |
|
|
|
|
|
if id == 'q': |
|
|
|
|
|
return None; |
|
|
|
|
|
elif id in kwargs: |
|
|
|
|
|
return kwargs[id]; |
|
|
|
|
|
id = int( id ); |
|
|
|
|
|
except Exception, instance: |
|
|
|
|
|
print "Error reading input. Did you type a number?"; |
|
|
|
|
|
print instance; |
|
|
|
|
|
return id; |
|
|
|
|
|
|
|
|
|
|
|
def util_editModel( model, blacklist = None ): |
|
|
|
|
|
while True: |
|
|
|
|
|
print "Current settings" |
|
|
|
|
|
print "================" |
|
|
|
|
|
for field in model._meta.fields: |
|
|
|
|
|
if blacklist and field.name in blacklist: |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
print "#%-5d %-30s %s" % ( model._meta.fields.index( field ), field.verbose_name, getattr( model, field.name ) ); |
|
|
|
|
|
|
|
|
|
|
|
print "================" |
|
|
|
|
|
print "Enter the index of the parameter you would like to change," |
|
|
|
|
|
print "or q to return." |
|
|
|
|
|
|
|
|
|
|
|
idx = getNum( "Index" ); |
|
|
|
|
|
if idx is None: |
|
|
|
|
|
save = raw_input( "save? Y/n >>> " ); |
|
|
|
|
|
if not save or save.lower() == 'y': |
|
|
|
|
|
print "saving changes."; |
|
|
|
|
|
model.save(); |
|
|
|
|
|
else: |
|
|
|
|
|
print "NOT saving changes." |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
field = model._meta.fields[idx]; |
|
|
|
|
|
if blacklist and field.name in blacklist: |
|
|
|
|
|
print "This field can not be changed."; |
|
|
|
|
|
elif isinstance( field, ForeignKey ): |
|
|
|
|
|
print "This is a ForeignKey."; |
|
|
|
|
|
print field.rel.to.objects.all(); |
|
|
|
|
|
else: |
|
|
|
|
|
value = None; |
|
|
|
|
|
while value is None: |
|
|
|
|
|
print |
|
|
|
|
|
try: |
|
|
|
|
|
value = field.to_python( raw_input( "%s >>> " % field.name ).strip() ); |
|
|
|
|
|
except Exception, instance: |
|
|
|
|
|
print instance; |
|
|
|
|
|
setattr( model, field.name, value ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def act_serverDetails( server ): |
|
|
|
|
|
"View or edit server settings." |
|
|
|
|
|
util_editModel( server, ( "id", "sslcrt", "sslkey" ) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def act_registeredUsers( server ): |
|
|
|
|
|
"View or edit user registrations." |
|
|
|
|
|
|
|
|
|
|
|
mumbleusers_list = server.mumbleuser_set.all(); |
|
|
|
|
|
|
|
|
|
|
|
print "Currently registered accounts"; |
|
|
|
|
|
print "============================="; |
|
|
|
|
|
|
|
|
|
|
|
for mu in mumbleusers_list: |
|
|
|
|
|
if mu.owner is not None: |
|
|
|
|
|
print "#%-5d %-20s Owner: %-20s Admin: %s" % ( mu.id, mu.name, mu.owner.username, mu.getAdmin() ); |
|
|
|
|
|
else: |
|
|
|
|
|
print "#%-5d %-20s" % ( mu.id, mu.name ); |
|
|
|
|
|
|
|
|
|
|
|
print "============================="; |
|
|
|
|
|
print "Enter the ID of the account you would like to change, n to create a new one, or q to return." |
|
|
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
|
|
idx = getNum( "ID", n=-1 ); |
|
|
|
|
|
if idx is None: |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
if idx == -1: |
|
|
|
|
|
mu = MumbleUser(); |
|
|
|
|
|
mu.server = server; |
|
|
|
|
|
else: |
|
|
|
|
|
mu = mumbleusers_list.get( id=idx ); |
|
|
|
|
|
|
|
|
|
|
|
util_editModel( mu, ( "id", "mumbleid", "server" ) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def act_listChannels( server ): |
|
|
|
|
|
"Display a channel tree." |
|
|
|
|
|
|
|
|
|
|
|
def printItem( item, level ): |
|
|
|
|
|
print "%s%s" % ( " "*level, item ); |
|
|
|
|
|
|
|
|
|
|
|
server.rootchan.visit( printItem ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def act_chanDetails( server ): |
|
|
|
|
|
"Display detailed information about one specific channel." |
|
|
|
|
|
print "Please choose the channel by entering the according ID (the number in parentheses)." |
|
|
|
|
|
act_listChannels( server ); |
|
|
|
|
|
|
|
|
|
|
|
id = getNum( "ID" ); |
|
|
|
|
|
if id is None: return; |
|
|
|
|
|
|
|
|
|
|
|
print "Channel name: %s" % server.channels[id].name |
|
|
|
|
|
print "Channel ID: %d" % server.channels[id].chanid |
|
|
|
|
|
print "Users online: %d" % len( server.channels[id].players ) |
|
|
|
|
|
print "Linked chans: %d" % len( server.channels[id].linked ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cli_chooseServer(): |
|
|
|
|
|
mumble_all = Mumble.objects.all().order_by( 'name', 'id' ); |
|
|
|
|
|
|
|
|
|
|
|
print "Please choose a Server instance by typing the corresponding ID.\n"; |
|
|
|
|
|
|
|
|
|
|
|
for mm in mumble_all: |
|
|
|
|
|
print "#%d\t%s" % ( mm.id, mm.name ); |
|
|
|
|
|
print "n: Create new instance"; |
|
|
|
|
|
print "q: Exit"; |
|
|
|
|
|
|
|
|
|
|
|
id = getNum( "ID", n = -1 ); |
|
|
|
|
|
|
|
|
|
|
|
if id is None: |
|
|
|
|
|
return; |
|
|
|
|
|
elif id == -1: |
|
|
|
|
|
return Mumble(); |
|
|
|
|
|
|
|
|
|
|
|
return Mumble.objects.get( id=id ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cli_chooseAction( server ): |
|
|
|
|
|
actions = { |
|
|
|
|
|
"LISTCHAN": act_listChannels, |
|
|
|
|
|
"CHANINFO": act_chanDetails, |
|
|
|
|
|
"EDITSERVER": act_serverDetails, |
|
|
|
|
|
"EDITUSERS": act_registeredUsers, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
|
|
print "What do you want to do?" |
|
|
|
|
|
|
|
|
|
|
|
keys = actions.keys(); |
|
|
|
|
|
|
|
|
|
|
|
for act in keys: |
|
|
|
|
|
print "#%-5d %-20s %s" % ( keys.index(act), act, actions[act].__doc__ ); |
|
|
|
|
|
print "q: Return to server selection"; |
|
|
|
|
|
|
|
|
|
|
|
idx = getNum( "Index" ); |
|
|
|
|
|
if idx is None: |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
# call action function |
|
|
|
|
|
func = actions[ keys[idx] ] |
|
|
|
|
|
func( server ); |
|
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def oldmain(): |
|
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
|
|
mumble = cli_chooseServer(); |
|
|
|
|
|
if mumble is None: |
|
|
|
|
|
print "Bye."; |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
print "Selected %s." % mumble; |
|
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
|
|
cli_chooseAction( mumble ); |
|
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BaseWindow( object ): |
|
|
class BaseWindow( object ): |
|
|
tabName = "tehBasez"; |
|
|
tabName = "tehBasez"; |
|
|
|
|
|
|
|
@ -260,13 +80,13 @@ class WndChannels( BaseWindow ): |
|
|
tabName = 'Channels'; |
|
|
tabName = 'Channels'; |
|
|
|
|
|
|
|
|
def printItem( self, item, level ): |
|
|
def printItem( self, item, level ): |
|
|
str = ""; |
|
|
|
|
|
|
|
|
namestr = ""; |
|
|
if item.is_server or item.is_channel: |
|
|
if item.is_server or item.is_channel: |
|
|
str = "%s (Channel)" % item.name; |
|
|
|
|
|
|
|
|
namestr = "%s (Channel)" % item.name; |
|
|
else: |
|
|
else: |
|
|
str = "%s (Player)" % item.name |
|
|
|
|
|
|
|
|
namestr = "%s (Player)" % item.name |
|
|
|
|
|
|
|
|
self.win.addstr( self.curr_y, 4*level+1, str.encode(locale.getpreferredencoding()) ) |
|
|
|
|
|
|
|
|
self.win.addstr( self.curr_y, 4*level+1, namestr.encode(locale.getpreferredencoding()) ) |
|
|
self.curr_y += 1; |
|
|
self.curr_y += 1; |
|
|
|
|
|
|
|
|
def draw( self ): |
|
|
def draw( self ): |
|
@ -355,8 +175,22 @@ class WndSettings( BaseWindow ): |
|
|
self.win.addstr( 1, 5, msg.encode(locale.getpreferredencoding()) ); |
|
|
self.win.addstr( 1, 5, msg.encode(locale.getpreferredencoding()) ); |
|
|
|
|
|
|
|
|
elif key in ( curses.KEY_RIGHT, curses.KEY_ENTER, ord('\n') ): |
|
|
elif key in ( curses.KEY_RIGHT, curses.KEY_ENTER, ord('\n') ): |
|
|
|
|
|
valid = False; |
|
|
|
|
|
while not valid: |
|
|
self.editors[field.name][1].edit(); |
|
|
self.editors[field.name][1].edit(); |
|
|
setattr( self.mm, field.name, field.to_python( self.editors[field.name][1].gather().strip() ) ); |
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
setattr( self.mm, field.name, |
|
|
|
|
|
field.to_python( self.editors[field.name][1].gather().strip() ) |
|
|
|
|
|
); |
|
|
|
|
|
except ValidationError, instance: |
|
|
|
|
|
msg = unicode( instance ); |
|
|
|
|
|
self.win.addstr( 1, 5, msg.encode(locale.getpreferredencoding()), curses.A_STANDOUT ); |
|
|
|
|
|
self.win.refresh(); |
|
|
|
|
|
else: |
|
|
|
|
|
valid = True; |
|
|
|
|
|
self.win.move( 1, 5 ); |
|
|
|
|
|
self.win.clrtoeol(); |
|
|
|
|
|
|
|
|
self.editors[field.name][0].refresh(); |
|
|
self.editors[field.name][0].refresh(); |
|
|
|
|
|
|
|
|
self.win.addstr( |
|
|
self.win.addstr( |
|
@ -364,9 +198,18 @@ class WndSettings( BaseWindow ): |
|
|
field.verbose_name.encode(locale.getpreferredencoding()) |
|
|
field.verbose_name.encode(locale.getpreferredencoding()) |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WndUsers( BaseWindow ): |
|
|
class WndUsers( BaseWindow ): |
|
|
tabName = 'Registered users'; |
|
|
tabName = 'Registered users'; |
|
|
|
|
|
|
|
|
|
|
|
def draw( self ): |
|
|
|
|
|
curr_y = 3; |
|
|
|
|
|
|
|
|
|
|
|
for acc in self.mm.mumbleuser_set.all(): |
|
|
|
|
|
self.win.addstr( curr_y, 1, acc.name.encode(locale.getpreferredencoding()) ); |
|
|
|
|
|
curr_y += 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MumbleForm( object ): |
|
|
class MumbleForm( object ): |
|
|
def __init__( self, parentwin, mumble, pos_x, pos_y ): |
|
|
def __init__( self, parentwin, mumble, pos_x, pos_y ): |
|
@ -453,9 +296,14 @@ def main( stdscr ): |
|
|
selectedIdx = 0; |
|
|
selectedIdx = 0; |
|
|
selectedMax = len(mumbles) - 1; |
|
|
selectedMax = len(mumbles) - 1; |
|
|
|
|
|
|
|
|
|
|
|
myname = "Mumble Commander"; |
|
|
|
|
|
|
|
|
while( True ): |
|
|
while( True ): |
|
|
selectedObj = mumbles[selectedIdx]; |
|
|
selectedObj = mumbles[selectedIdx]; |
|
|
|
|
|
|
|
|
|
|
|
maxyx = stdscr.getmaxyx(); |
|
|
|
|
|
stdscr.addstr( 0, maxyx[1] / 2 - len(myname)/2, myname, curses.A_UNDERLINE ); |
|
|
|
|
|
|
|
|
# Draw selection marker |
|
|
# Draw selection marker |
|
|
stdscr.addstr( first_y + selectedIdx, 3, '*' ); |
|
|
stdscr.addstr( first_y + selectedIdx, 3, '*' ); |
|
|
stdscr.refresh(); |
|
|
stdscr.refresh(); |
|
@ -471,6 +319,7 @@ def main( stdscr ): |
|
|
|
|
|
|
|
|
elif key in ( curses.KEY_RIGHT, curses.KEY_ENTER, ord('\n') ): |
|
|
elif key in ( curses.KEY_RIGHT, curses.KEY_ENTER, ord('\n') ): |
|
|
stdscr.clear(); |
|
|
stdscr.clear(); |
|
|
|
|
|
stdscr.addstr( 0, maxyx[1] / 2 - len(myname)/2, myname, curses.A_UNDERLINE ); |
|
|
selectedObj.mvwin( 5, first_y ); |
|
|
selectedObj.mvwin( 5, first_y ); |
|
|
selectedObj.draw(); |
|
|
selectedObj.draw(); |
|
|
stdscr.refresh(); |
|
|
stdscr.refresh(); |