diff --git a/pyweb/mumble/models.py b/pyweb/mumble/models.py index 50e1a36..e0fd2e8 100644 --- a/pyweb/mumble/models.py +++ b/pyweb/mumble/models.py @@ -14,9 +14,9 @@ * GNU General Public License for more details. """ -from PIL import Image -from struct import pack -from zlib import compress +from PIL import Image +from struct import pack, unpack +from zlib import compress, decompress from django.contrib.auth.models import User from django.db import models @@ -223,6 +223,28 @@ class MumbleUser( models.Model ): bus.setACL( *acl.pack() ); return value; + def getTexture( self ): + murmur = self.server.getDbusObject(); + texture = murmur.getTexture( dbus.Int32( self.mumbleid ) ); + if len(texture) == 0: + raise ValueError( "No Texture has been set." ); + # this returns a list of bytes. + # first 4 bytes: Length of uncompressed string, rest: compressed data + orig_len = ( texture[0] << 24 ) | ( texture[1] << 16 ) | ( texture[2] << 8 ) | ( texture[3] ); + # convert rest to string and run decompress + bytestr = ""; + for byte in texture[4:]: + bytestr += pack( "B", int(byte) ); + decompressed = decompress( bytestr ); + # iterate over 4 byte chunks of the string + imgdata = ""; + for idx in range( 0, orig_len, 4 ): + # read 4 bytes = BGRA and convert to RGBA + bgra = unpack( "4B", decompressed[idx:idx+4] ); + imgdata += pack( "4B", bgra[2], bgra[1], bgra[0], bgra[3] ); + # return an 600x60 RGBA image object created from the data + return Image.fromstring( "RGBA", ( 600, 60 ), imgdata ); + def setTexture( self, infile ): # open image, convert to RGBA, and resize to 600x60 img = Image.open( infile ).convert( "RGBA" ).transform( ( 600, 60 ), Image.EXTENT, ( 0, 0, 600, 60 ) ); diff --git a/pyweb/mumble/urls.py b/pyweb/mumble/urls.py index 6608d12..d18fb4e 100644 --- a/pyweb/mumble/urls.py +++ b/pyweb/mumble/urls.py @@ -17,7 +17,8 @@ from django.conf.urls.defaults import * urlpatterns = patterns( - '', - ( r'(?P\d+)', 'mumble.views.show' ), - ( r'$', 'mumble.views.mumbles' ), + 'mumble.views', + ( r'(?P\d+)/texture.jpg', 'showTexture' ), + ( r'(?P\d+)', 'show' ), + ( r'$', 'mumbles' ), ) diff --git a/pyweb/mumble/views.py b/pyweb/mumble/views.py index 357d42a..ee5bdff 100644 --- a/pyweb/mumble/views.py +++ b/pyweb/mumble/views.py @@ -14,9 +14,11 @@ * GNU General Public License for more details. """ +from StringIO import StringIO + from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404 from django.template import RequestContext -from django.http import HttpResponseRedirect +from django.http import Http404, HttpResponse, HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required @@ -124,6 +126,20 @@ def show( request, server ): ); +def showTexture( request, server ): + if request.user.is_authenticated(): + srv = Mumble.objects.get( id=int(server) ); + user = MumbleUser.objects.get( server=srv, owner=request.user ); + try: + img = user.getTexture(); + except ValueError: + raise Http404(); + else: + buffer = StringIO(); + img.save( buffer, "JPEG" ); + return HttpResponse( buffer.getvalue(), "image/jpeg" ); + raise Http404(); + def showContent( server, user = None ): "Renders and returns the channel list for the given Server ID." from django.template import Context, loader diff --git a/template/mumble/mumble.htm b/template/mumble/mumble.htm index 8fb7083..9c3c7c2 100644 --- a/template/mumble/mumble.htm +++ b/template/mumble/mumble.htm @@ -40,7 +40,11 @@ {% if Registered %}

User Texture

- You can upload an image that you would like to use as your user texture here.
+

+ You can upload an image that you would like to use as your user texture here.
+ Your current texture is:
+ user texture
+

{{ TextureForm }}