Browse Source

merged mmServer class into Mumble model, changed channel viewer to use divs instead of a table (can be more cleanly generated), cleaned up views and removed a whole lot of bad(tm) code

Natenom/support-murmur-13-1446181288462
Michael Ziegler 15 years ago
parent
commit
61b80ddf72
  1. 37
      htdocs/mumble/style.css
  2. 139
      pyweb/mumble/mmobjects.py
  3. 184
      pyweb/mumble/models.py
  4. 22
      pyweb/mumble/templatetags/mumble_extras.py
  5. 75
      pyweb/mumble/views.py
  6. 17
      template/mumble/channel.htm
  7. 62
      template/mumble/content.htm
  8. 55
      template/mumble/mumble.htm
  9. 25
      template/mumble/player.htm
  10. 9
      template/mumble/server.htm

37
htdocs/mumble/style.css

@ -1,29 +1,26 @@
td.mumble img {
padding: 0px;
margin: 0px;
}
a.dingen:link, a.dingen:visited, a.dingen:hover, a.dingen:active {
a.mumble:link, a.mumble:visited, a.mumble:hover, a.mumble:active {
font-weight: bold;
font-size: 8pt;
color: #283E53;
text-decoration: none;
}
}
div.mumble {
background-image: url( /static/mumble/linie_v.png );
background-repeat: repeat-y;
margin-left: 20px;
margin-bottom: 0;
padding-bottom: 0;
}
td.mumble {
height: 20px;
div.mumble img {
padding: 0px;
margin: 0px;
line-height: 6px;
border: none;
}
}
span.mumble {
width: 10em;
float:right;
}
div.mumble {
background-color: #FFFFFF;
color: #283E53;
padding: 10px;
margin-top: 20px;
margin-bottom: 20px;
width: 80%;
min-height: 250px;
}

139
pyweb/mumble/mmobjects.py

@ -18,98 +18,9 @@ import mctl
import datetime
from time import time
from os.path import join
# base = ice.stringToProxy( "Meta:tcp -h 127.0.0.1 -p 6502" );
# srv = Murmur.ServerPrx.checkedCast( base );
# met = Murmur.MetaPrx.checkedCast( base );
class mmServer( object ):
# channels = dict();
# players = dict();
# id = int();
# rootName = str();
def __init__( self, model, ctl ):
#self.dbusObj = serverObj;
self.channels = dict();
self.players = dict();
self.id = model.srvid;
self.rootName = model.name;
self.model = model;
links = dict();
chanlist = ctl.getChannels(model.srvid);
# sometimes, ICE seems to return the Channel list in a weird order.
# itercount prevents infinite loops.
itercount = 0;
maxiter = len(chanlist) * 3;
while len(chanlist) and itercount < maxiter:
itercount += 1;
#print len(chanlist)
for theChan in chanlist:
# Channels - Fields: 0 = ID, 1 = Name, 2 = Parent-ID, 3 = Links
if( theChan[2] == -1 ):
# No parent
self.channels[theChan[0]] = mmChannel( theChan );
elif theChan[2] in self.channels:
# parent already known
self.channels[theChan[0]] = mmChannel( theChan, self.channels[theChan[2]] );
else:
continue;
chanlist.remove( theChan );
self.channels[theChan[0]].serverId = self.id;
# process links - if the linked channels are known, link; else save their ids to link later
for linked in theChan[3]:
if linked in self.channels:
self.channels[theChan[0]].linked.append( self.channels[linked] );
else:
if linked not in links:
links[linked] = list();
links[linked].append( self.channels[theChan[0]] );
#print "Saving link: %s <- %s" % ( linked, self.channels[theChan[0]] );
# check if earlier round trips saved channel ids to be linked to the current channel
if theChan[0] in links:
for targetChan in links[theChan[0]]:
targetChan.linked.append( self.channels[theChan[0]] );
if self.rootName:
self.channels[0].name = self.rootName;
for thePlayer in ctl.getPlayers(model.srvid):
# in DBus
# Players - Fields: 0 = UserID, 6 = ChannelID
self.players[ thePlayer[0] ] = mmPlayer( self.model, thePlayer, self.channels[ thePlayer[6] ] );
playerCount = property(
lambda self: len( self.players ),
None
);
def is_server( self ):
return True;
def is_channel( self ):
return False;
def is_player( self ):
return False;
def __str__( self ):
return '<Server "%s" (%d)>' % ( self.rootName, self.id );
def visit( self, callback, lvl = 0 ):
if not callable( callback ):
raise Exception, "a callback should be callable...";
# call callback first on myself, then visit my root chan
callback( self, lvl );
self.channels[0].visit( callback, lvl + 1 );
from django.utils.http import urlquote
class mmChannel( object ):
@ -121,7 +32,8 @@ class mmChannel( object ):
# linked = list();
# linkedIDs = list();
def __init__( self, channelObj, parentChan = None ):
def __init__( self, server, channelObj, parentChan = None ):
self.server = server;
self.players = list();
self.subchans = list();
self.linked = list();
@ -131,19 +43,18 @@ class mmChannel( object ):
self.parent = parentChan;
if self.parent is not None:
self.parent.subchans.append( self );
self.serverId = self.parent.serverId;
def parentChannels( self ):
if self.parent is None or self.parent.is_server() or self.parent.chanid == 0:
if self.parent is None or self.parent.is_server or self.parent.chanid == 0:
return [];
return self.parent.parentChannels() + [self.parent.name];
def is_server( self ):
return False;
def is_channel( self ):
return True;
def is_player( self ):
return False;
is_server = False;
is_channel = True;
is_player = False;
playerCount = property(
lambda self: len( self.players ) + sum( [ chan.playerCount for chan in self.subchans ] ),
@ -163,6 +74,25 @@ class mmChannel( object ):
pl.visit( callback, lvl + 1 );
def getURL( self, forUser = None ):
# mumble://username@host:port/parentchans/self.name
userstr = "";
if forUser is not None:
userstr = "%s@" % forUser.name;
# create list of all my parents and myself
chanlist = self.parentChannels() + [self.name];
# urlencode channel names
chanlist = [ urlquote( chan ) for chan in chanlist ];
# create a path by joining the channel names
chanpath = join( *chanlist );
return "mumble://%s%s:%d/%s" % ( userstr, self.server.addr, self.server.port, chanpath );
url = property( getURL, None );
class mmPlayer( object ):
# muted = bool;
@ -206,12 +136,9 @@ class mmPlayer( object ):
None
);
def is_server( self ):
return False;
def is_channel( self ):
return False;
def is_player( self ):
return True;
is_server = False;
is_channel = False;
is_player = True;
# kept for compatibility to mmChannel (useful for traversal funcs)
playerCount = property( lambda self: -1, None );

184
pyweb/mumble/models.py

@ -14,6 +14,7 @@
* GNU General Public License for more details.
"""
import socket
from PIL import Image
from struct import pack, unpack
from zlib import compress, decompress
@ -21,13 +22,11 @@ from zlib import compress, decompress
from django.contrib.auth.models import User
from django.db import models
from mmobjects import mmServer, mmACL
from django.conf import settings
from mmobjects import *
from mctl import *
import socket
class Mumble( models.Model ):
name = models.CharField( 'Server Name', max_length = 200 );
@ -49,12 +48,30 @@ class Mumble( models.Model ):
defchan= models.IntegerField( 'Default channel', default=0 );
booted = models.BooleanField( 'Boot Server', default = True );
def getServerObject( self ):
return mmServer( self, MumbleCtlBase.newInstance( self.dbus ) );
def __init__( self, *args, **kwargs ):
models.Model.__init__( self, *args, **kwargs );
self._ctl = None;
self._channels = None;
self._rootchan = None;
def __unicode__( self ):
return u'Murmur "%s" (%d)' % ( self.name, self.srvid );
is_server = True;
is_channel = False;
is_player = False;
# Ctl instantiation
def getCtl( self ):
if not self._ctl:
self._ctl = MumbleCtlBase.newInstance( self.dbus );
return self._ctl;
ctl = property( getCtl, None );
def save( self, dontConfigureMurmur=False ):
if dontConfigureMurmur:
# skip murmur configuration, e.g. because we're inserting models for existing servers.
@ -62,57 +79,57 @@ class Mumble( models.Model ):
# check if this server already exists, if not call newServer and set my srvid first
ctl = MumbleCtlBase.newInstance( self.dbus );
if self.id is None:
self.srvid = ctl.newServer();
self.srvid = self.ctl.newServer();
ctl.setConf( self.srvid, 'host', socket.gethostbyname( self.addr ) );
ctl.setConf( self.srvid, 'registername', self.name );
ctl.setConf( self.srvid, 'registerurl', self.url );
ctl.setConf( self.srvid, 'welcometext', self.motd );
ctl.setConf( self.srvid, 'password', self.passwd );
ctl.setConf( self.srvid, 'certificate', self.sslcrt );
ctl.setConf( self.srvid, 'key', self.sslkey );
ctl.setConf( self.srvid, 'obfuscate', str(self.obfsc).lower() );
ctl.setConf( self.srvid, 'playername', self.player );
ctl.setConf( self.srvid, 'channelname', self.channel );
ctl.setConf( self.srvid, 'defaultchannel', str(self.defchan) );
self.ctl.setConf( self.srvid, 'host', socket.gethostbyname( self.addr ) );
self.ctl.setConf( self.srvid, 'registername', self.name );
self.ctl.setConf( self.srvid, 'registerurl', self.url );
self.ctl.setConf( self.srvid, 'welcometext', self.motd );
self.ctl.setConf( self.srvid, 'password', self.passwd );
self.ctl.setConf( self.srvid, 'certificate', self.sslcrt );
self.ctl.setConf( self.srvid, 'key', self.sslkey );
self.ctl.setConf( self.srvid, 'obfuscate', str(self.obfsc).lower() );
self.ctl.setConf( self.srvid, 'playername', self.player );
self.ctl.setConf( self.srvid, 'channelname', self.channel );
self.ctl.setConf( self.srvid, 'defaultchannel', str(self.defchan) );
if self.port is not None:
ctl.setConf( self.srvid, 'port', str(self.port) );
self.ctl.setConf( self.srvid, 'port', str(self.port) );
else:
ctl.setConf( self.srvid, 'port', '' );
self.ctl.setConf( self.srvid, 'port', '' );
if self.users is not None:
ctl.setConf( self.srvid, 'users', str(self.users) );
self.ctl.setConf( self.srvid, 'users', str(self.users) );
else:
ctl.setConf( self.srvid, 'users', '' );
self.ctl.setConf( self.srvid, 'users', '' );
if self.bwidth is not None:
ctl.setConf( self.srvid, 'bandwidth', str(self.bwidth) );
self.ctl.setConf( self.srvid, 'bandwidth', str(self.bwidth) );
else:
ctl.setConf( self.srvid, 'bandwidth', '' );
self.ctl.setConf( self.srvid, 'bandwidth', '' );
# registerHostname needs to take the port no into account
if self.port and self.port != 64738:
ctl.setConf( self.srvid, 'registerhostname', "%s:%d" % ( self.addr, self.port ) );
self.ctl.setConf( self.srvid, 'registerhostname', "%s:%d" % ( self.addr, self.port ) );
else:
ctl.setConf( self.srvid, 'registerhostname', self.addr );
self.ctl.setConf( self.srvid, 'registerhostname', self.addr );
if self.supw:
ctl.setSuperUserPassword( self.srvid, self.supw );
self.ctl.setSuperUserPassword( self.srvid, self.supw );
self.supw = '';
if self.booted != ctl.isBooted( self.srvid ):
if self.booted != self.ctl.isBooted( self.srvid ):
if self.booted:
ctl.start( self.srvid );
self.ctl.start( self.srvid );
else:
ctl.stop( self.srvid );
self.ctl.stop( self.srvid );
# Now allow django to save the record set
return models.Model.save( self );
def isUserAdmin( self, user ):
if user.is_authenticated():
try:
@ -121,15 +138,83 @@ class Mumble( models.Model ):
return False;
return False;
# Deletion handler
def deleteServer( self ):
# Unregister this player in Murmur via ctroller.
#print MumbleCtlBase.newInstance()
MumbleCtlBase.newInstance( self.dbus ).deleteServer(self.srvid)
self.ctl.deleteServer(self.srvid)
@staticmethod
def pre_delete_listener( **kwargs ):
kwargs['instance'].deleteServer();
# Channel lists: flat list
def getChannels( self ):
if self._channels is None:
self._channels = {};
chanlist = self.ctl.getChannels(self.srvid);
links = {};
# sometimes, ICE seems to return the Channel list in a weird order.
# itercount prevents infinite loops.
itercount = 0;
maxiter = len(chanlist) * 3;
while len(chanlist) and itercount < maxiter:
itercount += 1;
for theChan in chanlist:
# Channels - Fields: 0 = ID, 1 = Name, 2 = Parent-ID, 3 = Links
if( theChan[2] == -1 ):
# No parent
self._channels[theChan[0]] = mmChannel( self, theChan );
elif theChan[2] in self.channels:
# parent already known
self._channels[theChan[0]] = mmChannel( self, theChan, self.channels[theChan[2]] );
else:
continue;
chanlist.remove( theChan );
self._channels[theChan[0]].serverId = self.id;
# process links - if the linked channels are known, link; else save their ids to link later
for linked in theChan[3]:
if linked in self._channels:
self._channels[theChan[0]].linked.append( self._channels[linked] );
else:
if linked not in links:
links[linked] = list();
links[linked].append( self._channels[theChan[0]] );
# check if earlier round trips saved channel ids to be linked to the current channel
if theChan[0] in links:
for targetChan in links[theChan[0]]:
targetChan.linked.append( self._channels[theChan[0]] );
self._channels[0].name = self.name;
self.players = {};
for thePlayer in self.ctl.getPlayers(self.srvid):
# Players - Fields: 0 = UserID, 6 = ChannelID
self.players[ thePlayer[0] ] = mmPlayer( self, thePlayer, self._channels[ thePlayer[6] ] );
return self._channels;
channels = property( getChannels, None );
rootchan = property( lambda self: self.channels[0], None );
def getURL( self, forUser = None ):
# mumble://username@host:port/
userstr = "";
if forUser is not None:
userstr = "%s@" % forUser.name;
return "mumble://%s%s:%d/" % ( userstr, self.addr, self.port );
url = property( getURL, None );
class MumbleUser( models.Model ):
mumbleid = models.IntegerField( 'Mumble player_id', editable = False, default = -1 );
name = models.CharField( 'User name and Login', max_length = 200 );
@ -138,16 +223,24 @@ class MumbleUser( models.Model ):
owner = models.ForeignKey( User, null=True, blank=True );
isAdmin = models.BooleanField( 'Admin on root channel', default = False );
is_server = False;
is_channel = False;
is_player = True;
def __unicode__( self ):
return u"Mumble user %s on %s owned by Django user %s" % ( self.name, self.server, self.owner );
def save( self, dontConfigureMurmur=False ):
if dontConfigureMurmur:
# skip murmur configuration, e.g. because we're inserting models for existing players.
return models.Model.save( self );
# Before the record set is saved, update Murmur via ctroller.
ctl = MumbleCtlBase.newInstance( self.server.dbus );
# Before the record set is saved, update Murmur via controller.
ctl = self.server.ctl;
if self.id is None:
# This is a new user record, so Murmur doesn't know about it yet
@ -177,9 +270,11 @@ class MumbleUser( models.Model ):
return models.Model.save( self );
# Admin handlers
def getAdmin( self ):
# Get ACL of root Channel, get the admin group and see if I'm in it
acl = mmACL( 0, MumbleCtlBase.newInstance( self.server.dbus ).getACL(self.server.srvid, 0) );
acl = mmACL( 0, self.server.ctl.getACL(self.server.srvid, 0) );
if not hasattr( acl, "admingroup" ):
raise ValueError( "The admin group was not found in the ACL's groups list!" );
@ -187,7 +282,7 @@ class MumbleUser( models.Model ):
def setAdmin( self, value ):
# Get ACL of root Channel, get the admin group and see if I'm in it
ctl = MumbleCtlBase.newInstance( self.server.dbus );
ctl = self.server.ctl;
acl = mmACL( 0, ctl.getACL(self.server.srvid, 0) );
if not hasattr( acl, "admingroup" ):
@ -202,11 +297,17 @@ class MumbleUser( models.Model ):
ctl.setACL(self.server.srvid, acl);
return value;
# Texture handlers
def getTexture( self ):
return MumbleCtlBase.newInstance( self.server.dbus ).getTexture(self.server.srvid, self.mumbleid);
return self.server.ctl.getTexture(self.server.srvid, self.mumbleid);
def setTexture( self, infile ):
MumbleCtlBase.newInstance( self.server.dbus ).setTexture(self.server.srvid, self.mumbleid, infile)
self.server.ctl.setTexture(self.server.srvid, self.mumbleid, infile)
# Deletion handler
@staticmethod
def pre_delete_listener( **kwargs ):
@ -214,7 +315,10 @@ class MumbleUser( models.Model ):
def unregister( self ):
# Unregister this player in Murmur via dbus.
MumbleCtlBase.newInstance( self.server.dbus ).unregisterPlayer(self.server.srvid, self.mumbleid)
self.server.ctl.unregisterPlayer(self.server.srvid, self.mumbleid)
# "server" field protection
def __setattr__( self, name, value ):
if name == 'server':
@ -224,6 +328,8 @@ class MumbleUser( models.Model ):
models.Model.__setattr__( self, name, value );
from django.db.models import signals
signals.pre_delete.connect( Mumble.pre_delete_listener, sender=Mumble );

22
pyweb/mumble/templatetags/mumble_extras.py

@ -14,6 +14,7 @@
"""
from django import template
from django.template.loader import render_to_string
register = template.Library();
@ -35,3 +36,24 @@ def trunc( string, maxlen = 50 ):
return string[:(maxlen - 3)] + "...";
register.filter( 'trunc', trunc );
### FILTER: chanview -- renders an mmChannel / mmPlayer object with the correct template.
def chanview( obj, user = None ):
if obj.is_server:
return render_to_string( 'mumble/server.htm', { 'Server': obj, 'MumbleAccount': user } );
elif obj.is_channel:
return render_to_string( 'mumble/channel.htm', { 'Channel': obj, 'MumbleAccount': user } );
elif obj.is_player:
return render_to_string( 'mumble/player.htm', { 'Player': obj, 'MumbleAccount': user } );
register.filter( 'chanview', chanview );
### FILTER: chanurl -- creates a connection URL and takes the user's login into account
def chanurl( obj, user ):
return obj.getURL( user );
register.filter( 'chanurl', chanurl );

75
pyweb/mumble/views.py

@ -24,13 +24,8 @@ from django.contrib.auth.decorators import login_required
from models import Mumble, MumbleUser
from forms import *
from mmobjects import mmServer, mmChannel
from mmobjects import *
# Handler class for all Server specific views
class Storage( object ):
s = list();
r = None;
def mumbles( request ):
@ -51,7 +46,7 @@ def mumbles( request ):
def show( request, server ):
"Displays the channel list for the given Server ID."
srv, o = createChannelList( server );
srv = get_object_or_404( Mumble, id=server );
isAdmin = srv.isUserAdmin( request.user );
@ -114,12 +109,20 @@ def show( request, server ):
regform = None;
textureform = None;
# ChannelTable is a somewhat misleading name, as it actually contains channels and players.
channelTable = [];
for id in srv.channels:
if id != 0:
channelTable.append( srv.channels[id] );
for id in srv.players:
channelTable.append( srv.players[id] );
return render_to_response(
'mumble/mumble.htm',
{
'DBaseObject': srv,
'ServerObject': o,
'ChannelTable': Storage.s,
'ChannelTable': channelTable,
'CurrentUserIsAdmin': isAdmin,
'AdminForm': adminform,
'RegForm': regform,
@ -147,59 +150,5 @@ def showTexture( request, server ):
return HttpResponse( buffer.getvalue(), "image/png" );
raise Http404();
def showContent( server, user = None ):
"Renders and returns the channel list for the given Server ID."
from django.template import Context, loader
srv, o = createChannelList( server );
mumbleAcc = None;
if user.is_authenticated():
mmUsers = MumbleUser.objects.filter( owner = user );
if mmUsers:
mumbleAcc = mmUsers[0];
t_content = loader.get_template( 'mumble/content.htm' );
c_content = Context( {
'DBaseObject': srv,
'ServerObject': o,
'ChannelTable': Storage.s,
'user': user,
'mumbleAccount': mumbleAcc,
"CurrentUserIsAdmin": srv.isUserAdmin( request.user ),
'MumbleActive': True,
} );
r_content = t_content.render( c_content );
return r_content;
def createChannelList( server ):
"Renders the channel list."
srv = get_object_or_404( Mumble, id=server );
o = srv.getServerObject();
Storage.s = list();
Storage.r = o.channels[0];
o.channels[0].visit( renderListItem, 0 );
return srv, o;
def renderListItem( item, level ):
"Stores a line in the channel list."
if item == Storage.r:
return;
# Filter channels that don't have players in them and are not a subchannel of root
if level > 1 and item.playerCount == 0:
# I used to test if item is an instance of mmChannel here. For some reason, that doesn't work. Dunno why.
return;
if isinstance( item, mmChannel ):
Storage.s.append( ( level, item, item.parentChannels() ) );
else:
Storage.s.append( ( level, item ) );

17
template/mumble/channel.htm

@ -0,0 +1,17 @@
{% load mumble_extras %}
<div class="mumble">
<img src="/static/mumble/knoten_v.png" />
{% if Channel.linked %}
<img src="/static/mumble/channel_linked.png" alt="linked channel" />
{% else %}
<img src="/static/mumble/channel.png" alt="channel" />
{% endif %}
<a href="{{ Channel|chanurl:MumbleAccount }}" class="mumble" id="link_{{ Channel.id }}" title="{{ Channel.name }}">
{{ Channel.name|trunc:30 }}
</a>
{% for sub in Channel.subchans %}
{{ sub|chanview:MumbleAccount }}
{% endfor %}
{% for player in Channel.players %}{{ player|chanview }}{% endfor %}
</div>

62
template/mumble/content.htm

@ -1,62 +0,0 @@
{% load mumble_extras %}
<div class="mumble">
<table cellspacing="0" cellpadding="0" style="width:100%; border:none">
<tr>
<td class="mumble" id="server" colspan="2">
<img src="/static/mumble/mumble.16x16.png" alt="mumble" />
<a href="mumble://{% if MumbleAccount %}{{ MumbleAccount.name }}@{% endif %}{{ DBaseObject.addr }}:{{ DBaseObject.port }}/" class="dingen" id="link_server">
{{ ServerObject.rootName }}
</a>
</tr>
{% for item in ChannelTable %}
<tr>
<td class="mumble" id="{{ item.1.id }}">
<span {% spaceless %}
{% if item.1.is_channel %}
class="mumble_channel"
{% else %}
class="mumble_player"
{% endif %}
{% endspaceless %} title="{{ item.1.name }}">
{% spaceless %}
{% for num in item.0|mrange %}
<img src="/static/mumble/linie_v_trans.png" alt="|" />
{% endfor %}
<img src="/static/mumble/knoten_v_trans.png" alt="+-" />
{% endspaceless %}
{% if item.1.is_player %}
<img src="/static/mumble/talking_off.png" alt="player" />
<a id="link_{{ item.1.id }}" class="dingen" href="#" title="{{ item.1.name }}">{{ item.1.name|trunc:30 }}</a>
{% else %}
{% if item.1.linked %}
<img src="/static/mumble/channel_linked.png" alt="linked channel"/>
{% else %}
<img src="/static/mumble/channel.png" alt="channel"/>
{% endif %}
<a href="mumble://{% if MumbleAccount %}{{ MumbleAccount.name }}@{% endif %}{{ DBaseObject.addr }}:{{ DBaseObject.port }}/{% for chan in item.2 %}{{ chan|urlencode }}/{% endfor %}{{ item.1.name|urlencode }}" class="dingen" id="link_{{ item.1.id }}" title="{{ item.1.name }}">{{ item.1.name|trunc:30 }}</a>
{% endif %}
</span>
</td>
<td class="mumble">
{% if item.1.userid %}
{% if item.1.isAuthed %}
<img src="/static/mumble/authenticated.png" alt="authed" title="Authenticated" />
{% endif %}
{% if item.1.muted %}
<img src="/static/mumble/muted_server.png" alt="muted" title="Muted by server" />
{% endif %}
{% if item.1.deafened %}
<img src="/static/mumble/deafened_server.png" alt="deafened" title="Deafened by server" />
{% endif %}
{% if item.1.selfmuted %}
<img src="/static/mumble/muted_self.png" alt="self-muted" title="Muted by themselves" />
{% endif %}
{% if item.1.selfdeafened %}
<img src="/static/mumble/deafened_self.png" alt="self-deafened" title="Deafened by themselves" />
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>

55
template/mumble/mumble.htm

@ -1,12 +1,10 @@
{% extends "index.htm" %}
{% block headtags %}
<meta http-equiv="refresh" content="30" />
{% endblock %}
{% load mumble_extras %}
{% block Headline %}
{{ ServerObject.rootName }}
{{ DBaseObject.name }}
{% endblock %}
{% block LeftColumn %}
{% include "mumble/content.htm" %}
{{ DBaseObject|chanview:MumbleAccount }}
{% endblock %}
{% block Content %}
<noscript>
@ -34,7 +32,7 @@
<input type="submit" />
</form>
{% else %}
<p>You need to be <a href="/accounts/login">logged in</a> to be able to register an account on this Mumble server.</p>
<p>You need to be <a href="/accounts/login?next=%2Fmumble%2F{{ DBaseObject.id }}">logged in</a> to be able to register an account on this Mumble server.</p>
{% endif %}
</div>
@ -72,33 +70,33 @@
{% endif %}
{% for item in ChannelTable %}
{% if item.1.is_player %}
<div id="mumble_{{ item.1.id }}" class="x-hide-display">
<h2>Player {{ item.1.name }}</h2>
{% if item.is_player %}
<div id="mumble_{{ item.id }}" class="x-hide-display">
<h2>Player {{ item.name }}</h2>
<ul>
<li>Online since {{item.1.onlinesince|time:"H:i"}}</li>
<li>Authenticated: {% if item.1.isAuthed %}Yes{% else %}No{% endif %}</li>
<li>Admin: {% if item.1.isAdmin %}Yes{% else %}No{% endif %}</li>
<li>Muted: {% if item.1.muted %}Yes{% else %}No{% endif %}</li>
<li>Deafened: {% if item.1.deafened %}Yes{% else %}No{% endif %}</li>
<li>Self-Muted: {% if item.1.selfmuted %}Yes{% else %}No{% endif %}</li>
<li>Self-Deafened: {% if item.1.selfdeafened %}Yes{% else %}No{% endif %}</li>
<li>Online since {{item.onlinesince|time:"H:i"}}</li>
<li>Authenticated: {% if item.isAuthed %}Yes{% else %}No{% endif %}</li>
<li>Admin: {% if item.isAdmin %}Yes{% else %}No{% endif %}</li>
<li>Muted: {% if item.muted %}Yes{% else %}No{% endif %}</li>
<li>Deafened: {% if item.deafened %}Yes{% else %}No{% endif %}</li>
<li>Self-Muted: {% if item.selfmuted %}Yes{% else %}No{% endif %}</li>
<li>Self-Deafened: {% if item.selfdeafened %}Yes{% else %}No{% endif %}</li>
</ul>
{% if item.1.mumbleuser and item.1.mumbleuser.owner %}
<h2>User {{ item.1.mumbleuser.owner.username|capfirst }}</h2>
{% if item.mumbleuser and item.mumbleuser.owner %}
<h2>User {{ item.mumbleuser.owner.username|capfirst }}</h2>
<ul>
{% if item.1.mumbleuser.owner.first_name and item.1.mumbleuser.owner.last_name %}
<li>Full Name: {{ item.1.mumbleuser.owner.first_name }} {{ item.1.mumbleuser.owner.last_name }}</li>
{% if item.mumbleuser.owner.first_name and item.mumbleuser.owner.last_name %}
<li>Full Name: {{ item.mumbleuser.owner.first_name }} {{ item.mumbleuser.owner.last_name }}</li>
{% endif %}
<li>Admin: {% if item.1.mumbleuser.owner.is_staff %}Yes{% else %}No{% endif %}</li>
<li>Sign-up date: {{ item.1.mumbleuser.owner.date_joined }}</li>
<li>Admin: {% if item.mumbleuser.owner.is_staff %}Yes{% else %}No{% endif %}</li>
<li>Sign-up date: {{ item.mumbleuser.owner.date_joined }}</li>
</ul>
{% endif %}
</div>
{% else %}
<div id="mumble_{{ item.1.id }}" class="x-hide-display">
<h2>Channel {{ item.1.name }}</h2>
<a href="mumble://{% if MumbleAccount %}{{ MumbleAccount.name }}@{% endif %}{{ DBaseObject.addr }}:{{ DBaseObject.port }}/{% for chan in item.2 %}{{ chan|urlencode }}/{% endfor %}{{ item.1.name|urlencode }}" class="dingen">Connect</a>
<div id="mumble_{{ item.id }}" class="x-hide-display">
<h2>Channel {{ item.name }}</h2>
<a href="{{ item|chanurl:MumbleAccount }}" class="mumble">Connect</a>
</div>
{% endif %}
{% endfor %}
@ -138,7 +136,7 @@
]
},
{% for item in ChannelTable %}
{ contentEl: 'mumble_{{ item.1.id }}', id: 'carditem_{{ item.1.id }}' },
{ contentEl: 'mumble_{{ item.id }}', id: 'carditem_{{ item.id }}' },
{% endfor %}
],
});
@ -148,11 +146,12 @@
event.preventDefault();
});
{% for item in ChannelTable %}
Ext.get( 'link_{{ item.1.id }}' ).on( 'click', function( event, target ){
cardpanel.layout.setActiveItem( 'carditem_{{ item.1.id }}' );
Ext.get( 'link_{{ item.id }}' ).on( 'click', function( event, target ){
cardpanel.layout.setActiveItem( 'carditem_{{ item.id }}' );
event.preventDefault();
});
{% endfor %}
} );
</script>
<meta http-equiv="refresh" content="300" />
{% endblock %}

25
template/mumble/player.htm

@ -0,0 +1,25 @@
{% load mumble_extras %}
<div class="mumble">
<span class="mumble">
{% if Player.isAuthed %}
<img src="/static/mumble/authenticated.png" alt="authed" title="Authenticated" />
{% endif %}
{% if Player.muted %}
<img src="/static/mumble/muted_server.png" alt="muted" title="Muted by server" />
{% endif %}
{% if Player.deafened %}
<img src="/static/mumble/deafened_server.png" alt="deafened" title="Deafened by server" />
{% endif %}
{% if Player.selfmuted %}
<img src="/static/mumble/muted_self.png" alt="self-muted" title="Muted by themselves" />
{% endif %}
{% if Player.selfdeafened %}
<img src="/static/mumble/deafened_self.png" alt="self-deafened" title="Deafened by themselves" />
{% endif %}
</span>
<span>
<img src="/static/mumble/knoten_v.png" />
<img src="/static/mumble/talking_off.png" alt="Player" />
<a id="link_{{ Player.id }}" class="mumble" href="#" title="{{ Player.name }}">{{ Player.name|trunc:30 }}</a>
</span>
</div>

9
template/mumble/server.htm

@ -0,0 +1,9 @@
{% load mumble_extras %}
<div style="margin-left: 20px">
<img src="/static/mumble/mumble.16x16.png" alt="server" />
<a class="mumble" id="link_server" href="{{ Server|chanurl:MumbleAccount }}">{{ Server.name|trunc:30 }}</a>
</div>
{% for sub in Server.rootchan.subchans %}
{{ sub|chanview:MumbleAccount }}
{% endfor %}
{% for player in Server.rootchan.players %}{{ player|chanview }}{% endfor %}
Loading…
Cancel
Save