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.

174 lines
4.8 KiB

16 years ago
  1. import dbus
  2. import datetime
  3. from time import time
  4. # base = ice.stringToProxy( "Meta:tcp -h 127.0.0.1 -p 6502" );
  5. # srv = Murmur.ServerPrx.checkedCast( base );
  6. # met = Murmur.MetaPrx.checkedCast( base );
  7. class mmServer( object ):
  8. # channels = dict();
  9. # players = dict();
  10. # id = int();
  11. # rootName = str();
  12. def __init__( self, serverID, serverObj, rootName = '' ):
  13. if not isinstance( serverObj, dbus.ProxyObject ):
  14. raise Exception, "mmServer: I need the object returned by dbus.get_object!"
  15. self.dbusObj = serverObj;
  16. self.channels = dict();
  17. self.players = dict();
  18. self.id = serverID;
  19. self.rootName = rootName;
  20. links = dict();
  21. for theChan in serverObj.getChannels():
  22. # Channels - Fields: 0 = ID, 1 = Name, 2 = Parent-ID, 3 = Links
  23. if( theChan[2] == -1 ):
  24. # No parent
  25. self.channels[theChan[0]] = mmChannel( theChan );
  26. else:
  27. self.channels[theChan[0]] = mmChannel( theChan, self.channels[theChan[2]] );
  28. # process links - if the linked channels are known, link; else save their ids to link later
  29. for linked in theChan[3]:
  30. if linked in self.channels:
  31. self.channels[theChan[0]].linked.append( self.channels[linked] );
  32. else:
  33. if linked not in links:
  34. links[linked] = list();
  35. links[linked].append( self.channels[theChan[0]] );
  36. #print "Saving link: %s <- %s" % ( linked, self.channels[theChan[0]] );
  37. # check if earlier round trips saved channel ids to be linked to the current channel
  38. if theChan[0] in links:
  39. for targetChan in links[theChan[0]]:
  40. targetChan.linked.append( self.channels[theChan[0]] );
  41. if self.rootName:
  42. self.channels[0].name = self.rootName;
  43. for thePlayer in serverObj.getPlayers():
  44. # Players - Fields: 0 = UserID, 6 = ChannelID
  45. self.players[ thePlayer[0] ] = mmPlayer( thePlayer, self.channels[ thePlayer[6] ] );
  46. playerCount = property(
  47. lambda self: len( self.players ),
  48. None
  49. );
  50. def __str__( self ):
  51. return '<Server "%s" (%d)>' % ( self.rootName, self.id );
  52. def visit( self, callback, lvl = 0 ):
  53. if not callable( callback ):
  54. raise Exception, "a callback should be callable...";
  55. # call callback first on myself, then visit my root chan
  56. callback( self, lvl );
  57. self.channels[0].visit( callback, lvl + 1 );
  58. class mmChannel( object ):
  59. # channels = list();
  60. # subchans = list();
  61. # id = int();
  62. # name = str();
  63. # parent = mmChannel();
  64. # linked = list();
  65. # linkedIDs = list();
  66. def __init__( self, channelObj, parentChan = None ):
  67. self.players = list();
  68. self.subchans = list();
  69. self.linked = list();
  70. (self.id, self.name, parent, self.linkedIDs ) = channelObj;
  71. self.parent = parentChan;
  72. if self.parent is not None:
  73. self.parent.subchans.append( self );
  74. def parentChannels( self ):
  75. if self.parent is None or isinstance( self.parent, mmServer ):
  76. return [];
  77. return self.parent.parentChannels() + [self.parent.name];
  78. playerCount = property(
  79. lambda self: len( self.players ) + sum( [ chan.playerCount for chan in self.subchans ] ),
  80. None
  81. );
  82. def __str__( self ):
  83. return '<Channel "%s" (%d)>' % ( self.name, self.id );
  84. def visit( self, callback, lvl = 0 ):
  85. # call callback on myself, then visit my subchans, then my players
  86. callback( self, lvl );
  87. for sc in self.subchans:
  88. sc.visit( callback, lvl + 1 );
  89. for pl in self.players:
  90. pl.visit( callback, lvl + 1 );
  91. class mmPlayer( object ):
  92. # muted = bool;
  93. # deafened = bool;
  94. # suppressed = bool;
  95. # selfmuted = bool;
  96. # selfdeafened = bool;
  97. # channel = mmChannel();
  98. # dbaseid = int();
  99. # userid = int();
  100. # name = str();
  101. # onlinesince = time();
  102. # bytesPerSec = int();
  103. def __init__( self, playerObj, playerChan ):
  104. ( self.userid, self.muted, self.deafened, self.suppressed, self.selfmuted, self.selfdeafened, chanID, self.dbaseid, self.name, onlinetime, self.bytesPerSec ) = playerObj;
  105. self.onlinesince = datetime.datetime.fromtimestamp( float( time() - onlinetime ) );
  106. self.channel = playerChan;
  107. self.channel.players.append( self );
  108. def __str__( self ):
  109. return '<Player "%s" (%d, %d)>' % ( self.name, self.userid, self.dbaseid );
  110. def isAuthed( self ):
  111. return self.dbaseid != -1;
  112. # kept for compatibility to mmChannel (useful for traversal funcs)
  113. playerCount = property(
  114. lambda self: -1,
  115. None
  116. );
  117. def visit( self, callback, lvl = 0 ):
  118. callback( self, lvl );
  119. if __name__ == '__main__':
  120. # connect to dbus
  121. bus = dbus.SystemBus();
  122. # get our murmur servers
  123. dbus_base = 'net.sourceforge.mumble.murmur';
  124. murmur = bus.get_object( dbus_base, '/' );
  125. # example callback
  126. def travrz( obj, lvl ):
  127. print lvl*'-', str(obj);
  128. # show each server
  129. for srv in murmur.getBootedServers():
  130. theSrv = bus.get_object( dbus_base, '/%d' % srv );
  131. srvobj = mmServer( srv, theSrv, 'teh %d srvz root' % srv );
  132. srvobj.visit( travrz );