Forked mumble-django project from https://bitbucket.org/Svedrin/mumble-django
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
9.7 KiB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. * Copyright (C) 2009, Michael "Svedrin" Ziegler <diese-addy@funzt-halt.net>
  5. *
  6. * Mumble-Django is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This package is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. """
  16. # Set this to the same path you used in settings.py, or None for auto-detection.
  17. MUMBLE_DJANGO_ROOT = None;
  18. ### DO NOT CHANGE ANYTHING BELOW THIS LINE ###
  19. import os, sys
  20. from os.path import join, dirname, abspath, exists
  21. # Path auto-detection
  22. if not MUMBLE_DJANGO_ROOT or not exists( MUMBLE_DJANGO_ROOT ):
  23. MUMBLE_DJANGO_ROOT = dirname(abspath(__file__));
  24. # environment variables
  25. sys.path.append( MUMBLE_DJANGO_ROOT )
  26. sys.path.append( join( MUMBLE_DJANGO_ROOT, 'pyweb' ) )
  27. os.environ['DJANGO_SETTINGS_MODULE'] = 'pyweb.settings'
  28. # If you get an error about Python not being able to write to the Python
  29. # egg cache, the egg cache path might be set awkwardly. This should not
  30. # happen under normal circumstances, but every now and then, it does.
  31. # Uncomment this line to point the egg cache to /tmp.
  32. #os.environ['PYTHON_EGG_CACHE'] = '/tmp/pyeggs'
  33. import curses
  34. from django.db.models.fields.related import ForeignKey
  35. from mumble.models import *
  36. def getNum( prompt, **kwargs ):
  37. id = None;
  38. while type(id) != int:
  39. print
  40. try:
  41. id = raw_input( "%s >>> " % prompt ).strip();
  42. if id == 'q':
  43. return None;
  44. elif id in kwargs:
  45. return kwargs[id];
  46. id = int( id );
  47. except Exception, instance:
  48. print "Error reading input. Did you type a number?";
  49. print instance;
  50. return id;
  51. def util_editModel( model, blacklist = None ):
  52. while True:
  53. print "Current settings"
  54. print "================"
  55. for field in model._meta.fields:
  56. if blacklist and field.name in blacklist:
  57. continue;
  58. print "#%-5d %-30s %s" % ( model._meta.fields.index( field ), field.verbose_name, getattr( model, field.name ) );
  59. print "================"
  60. print "Enter the index of the parameter you would like to change,"
  61. print "or q to return."
  62. idx = getNum( "Index" );
  63. if idx is None:
  64. save = raw_input( "save? Y/n >>> " );
  65. if not save or save.lower() == 'y':
  66. print "saving changes.";
  67. model.save();
  68. else:
  69. print "NOT saving changes."
  70. return;
  71. field = model._meta.fields[idx];
  72. if blacklist and field.name in blacklist:
  73. print "This field can not be changed.";
  74. elif isinstance( field, ForeignKey ):
  75. print "This is a ForeignKey.";
  76. print field.rel.to.objects.all();
  77. else:
  78. value = None;
  79. while value is None:
  80. print
  81. try:
  82. value = field.to_python( raw_input( "%s >>> " % field.name ).strip() );
  83. except Exception, instance:
  84. print instance;
  85. setattr( model, field.name, value );
  86. def act_serverDetails( server ):
  87. "View or edit server settings."
  88. util_editModel( server, ( "id", "sslcrt", "sslkey" ) );
  89. def act_registeredUsers( server ):
  90. "View or edit user registrations."
  91. mumbleusers_list = server.mumbleuser_set.all();
  92. print "Currently registered accounts";
  93. print "=============================";
  94. for mu in mumbleusers_list:
  95. if mu.owner is not None:
  96. print "#%-5d %-20s Owner: %-20s Admin: %s" % ( mu.id, mu.name, mu.owner.username, mu.getAdmin() );
  97. else:
  98. print "#%-5d %-20s" % ( mu.id, mu.name );
  99. print "=============================";
  100. print "Enter the ID of the account you would like to change, n to create a new one, or q to return."
  101. while True:
  102. idx = getNum( "ID", n=-1 );
  103. if idx is None:
  104. return;
  105. if idx == -1:
  106. mu = MumbleUser();
  107. mu.server = server;
  108. else:
  109. mu = mumbleusers_list.get( id=idx );
  110. util_editModel( mu, ( "id", "mumbleid", "server" ) );
  111. def act_listChannels( server ):
  112. "Display a channel tree."
  113. def printItem( item, level ):
  114. print "%s%s" % ( " "*level, item );
  115. server.rootchan.visit( printItem );
  116. def act_chanDetails( server ):
  117. "Display detailed information about one specific channel."
  118. print "Please choose the channel by entering the according ID (the number in parentheses)."
  119. act_listChannels( server );
  120. id = getNum( "ID" );
  121. if id is None: return;
  122. print "Channel name: %s" % server.channels[id].name
  123. print "Channel ID: %d" % server.channels[id].chanid
  124. print "Users online: %d" % len( server.channels[id].players )
  125. print "Linked chans: %d" % len( server.channels[id].linked )
  126. def cli_chooseServer():
  127. mumble_all = Mumble.objects.all().order_by( 'name', 'id' );
  128. print "Please choose a Server instance by typing the corresponding ID.\n";
  129. for mm in mumble_all:
  130. print "#%d\t%s" % ( mm.id, mm.name );
  131. print "n: Create new instance";
  132. print "q: Exit";
  133. id = getNum( "ID", n = -1 );
  134. if id is None:
  135. return;
  136. elif id == -1:
  137. return Mumble();
  138. return Mumble.objects.get( id=id );
  139. def cli_chooseAction( server ):
  140. actions = {
  141. "LISTCHAN": act_listChannels,
  142. "CHANINFO": act_chanDetails,
  143. "EDITSERVER": act_serverDetails,
  144. "EDITUSERS": act_registeredUsers,
  145. };
  146. while True:
  147. print "What do you want to do?"
  148. keys = actions.keys();
  149. for act in keys:
  150. print "#%-5d %-20s %s" % ( keys.index(act), act, actions[act].__doc__ );
  151. print "q: Return to server selection";
  152. idx = getNum( "Index" );
  153. if idx is None:
  154. return;
  155. # call action function
  156. func = actions[ keys[idx] ]
  157. func( server );
  158. print
  159. def oldmain():
  160. print
  161. while True:
  162. mumble = cli_chooseServer();
  163. if mumble is None:
  164. print "Bye.";
  165. return;
  166. print "Selected %s." % mumble;
  167. print
  168. cli_chooseAction( mumble );
  169. print
  170. class BaseWindow( object ):
  171. tabName = "tehBasez";
  172. def __init__( self, parentwin, mumble, pos_x, pos_y ):
  173. self.pos = ( pos_x, pos_y );
  174. self.win = parentwin.subwin( pos_y, pos_x );
  175. self.mm = mumble;
  176. self.win.keypad(1);
  177. def draw( self ):
  178. self.win.addstr( 1, 1, self.tabName );
  179. def border( self ):
  180. self.win.border();
  181. class WndChannels( BaseWindow ):
  182. tabName = 'Channels';
  183. def printItem( self, item, level ):
  184. if item.is_server or item.is_channel:
  185. self.win.addstr( self.curr_y, 2*level+1, "%s (Channel)" % unicode(item.name) )
  186. else:
  187. self.win.addstr( self.curr_y, 2*level+1, "%s (Player)" % unicode(item.name) )
  188. self.curr_y += 1;
  189. def draw( self ):
  190. self.curr_y = 1;
  191. self.mm.rootchan.visit( self.printItem );
  192. class WndSettings( BaseWindow ):
  193. tabName = 'Server settings';
  194. class WndUsers( BaseWindow ):
  195. tabName = 'Registered users';
  196. class MumbleForm( object ):
  197. def __init__( self, parentwin, mumble, pos_x, pos_y ):
  198. self.pos = ( pos_x, pos_y );
  199. self.win = parentwin.subwin( pos_y, pos_x );
  200. self.mm = mumble;
  201. self.win.keypad(1);
  202. self.windows = (
  203. WndChannels( self.win, mumble, pos_x + 2, pos_y + 2 ),
  204. WndSettings( self.win, mumble, pos_x + 2, pos_y + 2 ),
  205. WndUsers( self.win, mumble, pos_x + 2, pos_y + 2 ),
  206. );
  207. self.curridx = 0;
  208. self.currmax = len( self.windows ) - 1;
  209. currwin = property( lambda self: self.windows[self.curridx], None );
  210. def mvwin( self, pos_x, pos_y ):
  211. self.win.mvwin( pos_y, pos_x );
  212. def mvdefault( self ):
  213. self.win.mvwin( self.pos[1], self.pos[0] );
  214. def draw( self ):
  215. self.win.addstr( 0, 0, self.mm.name );
  216. def drawTabs( self ):
  217. first = True;
  218. for subwin in self.windows:
  219. flags = 0;
  220. if subwin is self.currwin: flags |= curses.A_STANDOUT;
  221. if first:
  222. self.win.addstr( 1, 2, "%-20s" % subwin.tabName, flags );
  223. first = False;
  224. else:
  225. self.win.addstr( "%-20s" % subwin.tabName, flags );
  226. def enter( self ):
  227. self.drawTabs();
  228. self.currwin.draw();
  229. self.currwin.border();
  230. while( True ):
  231. key = self.win.getch();
  232. if key == curses.KEY_LEFT and self.curridx > 0:
  233. self.curridx -= 1;
  234. elif key == curses.KEY_RIGHT and self.curridx < self.currmax:
  235. self.curridx += 1;
  236. elif key in ( ord('q'), ord('Q') ):
  237. return;
  238. self.win.clear();
  239. self.draw();
  240. self.drawTabs();
  241. self.currwin.draw();
  242. self.currwin.border();
  243. self.win.refresh();
  244. def main( stdscr ):
  245. first_y = 3;
  246. curr_y = first_y;
  247. mumbles = list();
  248. for mm in Mumble.objects.all().order_by( "name", "id" ):
  249. mwin = MumbleForm( stdscr, mm, pos_x=5, pos_y=curr_y );
  250. mumbles.append( mwin );
  251. mwin.draw();
  252. curr_y += 1;
  253. selectedIdx = 0;
  254. selectedMax = len(mumbles) - 1;
  255. while( True ):
  256. selectedObj = mumbles[selectedIdx];
  257. # Draw selection marker
  258. stdscr.addstr( first_y + selectedIdx, 3, '*' );
  259. stdscr.refresh();
  260. key = stdscr.getch();
  261. if key == curses.KEY_UP:
  262. stdscr.addstr( first_y + selectedIdx, 3, ' ' );
  263. selectedIdx -= 1;
  264. elif key == curses.KEY_DOWN:
  265. stdscr.addstr( first_y + selectedIdx, 3, ' ' );
  266. selectedIdx += 1;
  267. elif key in ( curses.KEY_ENTER, ord('\n') ):
  268. stdscr.clear();
  269. selectedObj.mvwin( 5, first_y );
  270. selectedObj.draw();
  271. stdscr.refresh();
  272. selectedObj.enter();
  273. stdscr.clear();
  274. selectedObj.mvdefault();
  275. for mwin in mumbles:
  276. mwin.draw();
  277. elif key in ( ord('q'), ord('Q') ):
  278. return;
  279. if selectedIdx < 0: selectedIdx = 0;
  280. elif selectedIdx > selectedMax: selectedIdx = selectedMax;
  281. if __name__ == '__main__':
  282. #parser = OptionParser();
  283. #parser.add_option( "-v", "--verbose", help="verbose output messages", default=False, action="store_true" );
  284. #parser.add_option( "-n", "--num", help="size of the Matrix", default=4, type = 'int' );
  285. #parser.add_option( "-s", "--sure", help="don't prompt if num >= 10", default=False, action="store_true" );
  286. #options, args = parser.parse_args();
  287. curses.wrapper( main );