-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Today I updated PokerImageUploadTestCase to fully cover the
implementation. and I added a new /AVATAR resource to pokersite, that
allow retrieval of avatar using GET /AVATAR/player_serial.

Patch #1 is attached.

I updated jpoker code in order to retrieve the avatar from
/AVATAR/player_serial resource if available.

And I also begun implementing selection and uploading of avatar image
from userInfo plugin, using: http://plugins.jquery.com/project/form

But form plugin rely on a  for uploading files:
http://malsup.com/jquery/form/#sample7

And the iframe proxy doesn't seems to forward the authentifiaction
cookie. ( alert('not logged') is called ).

Patch #2 is attached.

Feedbacks and advises are very welcome.
- --
bou ^


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: http://getfiregpg.org

iD8DBQFIoc9SZmEdV9SHoe4RAhmIAJ0Vew3tVSKj/Fx84cTHNQ8B/2JqpACfe8zy
nrrjG0Fp/rPMpEUXL8lgr+M=
=Rfvv
-----END PGP SIGNATURE-----
Index: pokernetwork/pokerservice.py
===================================================================
--- pokernetwork/pokerservice.py	(revision 4242)
+++ pokernetwork/pokerservice.py	(working copy)
@@ -87,7 +87,7 @@
 from pokernetwork.user import checkName, checkPassword
 from pokernetwork.pokerdatabase import PokerDatabase
 from pokernetwork.pokerpackets import *
-from pokernetwork.pokersite import PokerResource, packets2maps, args2packets, fromutf8, toutf8
+from pokernetwork.pokersite import PokerImageUpload, PokerAvatarResource, PokerResource, packets2maps, args2packets, fromutf8, toutf8
 from pokernetwork.pokertable import PokerTable
 from pokernetwork import pokeravatar
 from pokernetwork.user import User
@@ -1777,6 +1777,8 @@
         resource.Resource.__init__(self)
         self.service = service
         self.putChild("POKER_REST", PokerResource(self.service))
+        self.putChild("UPLOAD", PokerImageUpload(self.service))
+        self.putChild("AVATAR", PokerAvatarResource(self.service))
         self.putChild("", self)
 
     def render_GET(self, request):
Index: pokernetwork/pokersite.py
===================================================================
--- pokernetwork/pokersite.py	(revision 4242)
+++ pokernetwork/pokersite.py	(working copy)
@@ -21,6 +21,7 @@
 import re
 import imp
 import time
+import base64
 from types import *
 
 from traceback import format_exc
@@ -270,7 +271,93 @@
             return True
         d.addCallbacks(render, processingFailed)
         return d
-        
+
+class PokerImageUpload(resource.Resource):
+
+    def __init__(self, service):
+        resource.Resource.__init__(self)
+        self.service = service
+        self.verbose = service.verbose
+        self.deferred = defer.succeed(None)
+        self.isLeaf = True
+
+    def message(self, string):
+        print "PokerImageUpload: " + string
+
+#    def error(self, string):
+#        self.message("*ERROR* " + string)
+
+    def render(self, request):
+        if self.verbose > 3:
+            self.message("render " + request.content.read())
+        request.content.seek(0, 0)
+        data = request.args['filename'][0]        
+        self.deferred.addCallback(lambda result: self.deferRender(request, data))
+        return server.NOT_DONE_YET
+
+    def deferRender(self, request, data):
+        session = request.getSession()
+        if session.avatar.isLogged():
+            serial = request.getSession().avatar.getSerial()
+            packet = PacketPokerPlayerImage(image = base64.b64encode(data), serial = serial)
+            self.service.setPlayerImage(packet)
+            result_string = 'image uploaded'
+            request.setHeader("Content-length", str(len(result_string)))
+            request.setHeader("Content-type", 'text/plain; charset="UTF-8"')
+            request.write(result_string)
+            request.finish()
+            return
+        else:
+            session.expire()
+            body = 'not logged'
+            request.setResponseCode(http.UNAUTHORIZED)
+            request.setHeader('content-type',"text/html")
+            request.setHeader('content-length', str(len(body)))
+            request.write(body)
+            request.finish()
+            return
+
+class PokerAvatarResource(resource.Resource):
+
+    def __init__(self, service):
+        resource.Resource.__init__(self)
+        self.service = service
+        self.verbose = service.verbose
+        self.deferred = defer.succeed(None)
+        self.isLeaf = True
+
+    def message(self, string):
+        print "PokerAvatarResource: " + string
+
+#    def error(self, string):
+#        self.message("*ERROR* " + string)
+
+    def render(self, request):
+        if self.verbose > 3:
+            self.message("render " + request.content.read())
+        request.content.seek(0, 0)
+        serial = int(request.path.split('/')[-1])
+        self.deferred.addCallback(lambda result: self.deferRender(request, serial))
+        return server.NOT_DONE_YET
+
+    def deferRender(self, request, serial):
+        packet  = self.service.getPlayerImage(serial)
+        if len(packet.image):
+            result_string = base64.b64decode(packet.image)
+            request.setHeader("Content-length", str(len(result_string)))
+            request.setHeader("Content-type", packet.image_type)
+            request.write(result_string)
+            request.finish()
+            return
+        else:
+            body = 'not found'
+            request.setResponseCode(http.NOT_FOUND)
+            request.setHeader('content-type',"text/html")
+            request.setHeader('content-length', str(len(body)))
+            request.write(body)
+            request.finish()
+            return
+
 class PokerSite(server.Site):
 
     requestFactory = Request
Index: tests/test-pokersite.py.in
===================================================================
--- tests/test-pokersite.py.in	(revision 4242)
+++ tests/test-pokersite.py.in	(working copy)
@@ -23,6 +23,8 @@
 sys.path.insert(0, "..")
 
 import libxml2
+import base64
+import cgi
 
 from twisted.trial import unittest, runner, reporter
 from twisted.internet import defer
@@ -55,6 +57,14 @@
       def destroyAvatar(self, avatar):
             pass
 
+      player_image = None
+      def setPlayerImage(self, player_image):
+            self.player_image = player_image      
+      player_serial = None
+      def getPlayerImage(self, serial):
+            self.player_serial = serial
+            return self.player_image
+
 class HelpersTestCase(unittest.TestCase):
 
       def test_fromutf8(self):
@@ -226,6 +236,130 @@
             r.requestReceived('GET', '/', '')
             return d
 
+class PokerImageUploadTestCase(unittest.TestCase):
+
+      class Transport:
+            def getPeer(self):
+                  return None
+            def getHost(self):
+                  return None
+
+      class Channel:
+            def __init__(self, site):
+                  self.transport = PokerImageUploadTestCase.Transport()
+                  self.site = site
+
+      def setUp(self):
+            testclock._seconds_reset()        
+            settings_xml = """<?xml version="1.0" encoding="ISO-8859-1"?>
+<server verbose="6" />
+"""
+            self.settings = pokernetworkconfig.Config([])
+            self.settings.loadFromString(settings_xml)
+            pokersite.memcache = pokersite.MemcacheMockup
+            self.service = PokerServiceMockup()
+            self.site = pokersite.PokerSite(self.settings, pokersite.PokerImageUpload(self.service))
+            self.image_data = "image data"
+            def parse_multipart_mockup(content, dict):
+                  return {'filename':[self.image_data]}
+            self.cgi_parse_multipart = cgi.parse_multipart
+            cgi.parse_multipart = parse_multipart_mockup
+            
+      def tearDown(self):
+            cgi.parse_multipart = self.cgi_parse_multipart
+
+      def test01_render(self):            
+            r = pokersite.Request(self.Channel(self.site), True)
+            r.site = r.channel.site
+            
+            r.args = {}
+            session = self.site.makeSession()
+            r.session = session
+            self.assertNotEquals(None, r.getSession().avatar);
+            user_serial = 111
+            r.getSession().avatar.user.serial = user_serial
+            self.assertEquals(True, r.getSession().avatar.isLogged());
+
+            image_data = "image data"
+            r.received_headers['content-type'] = 'multipart/form-data'
+            input = ''
+            r.gotLength(len(input))
+            r.handleContentChunk(input)
+            import cgi
+            def parse_multipart_mockup(content, dict):
+                  return {'filename':[image_data]}
+            cgi.parse_multipart = parse_multipart_mockup
+            r.requestReceived('POST', '/', '')
+            self.assertSubstring('image uploaded', r.transport.getvalue())
+            self.assertEquals(base64.b64encode(self.image_data),
+                              self.service.player_image.image)
+            session.expire()
+
+      def test02_unauthorized(self):            
+            r = pokersite.Request(self.Channel(self.site), True)
+            r.site = r.channel.site
+            
+            r.args = {}
+            session = self.site.makeSession()
+            r.session = session
+            self.assertNotEquals(None, r.getSession().avatar);
+            self.assertEquals(False, r.getSession().avatar.isLogged());
+
+            r.received_headers['content-type'] = 'multipart/form-data'
+            input = ''
+            r.gotLength(len(input))
+            r.handleContentChunk(input)
+            r.requestReceived('POST', '/', '')
+            self.assertSubstring('not logged', r.transport.getvalue())
+            self.assertEquals(None, self.service.player_image)
+
+class PokerAvatarResourceTestCase(unittest.TestCase):
+
+      class Transport:
+            def getPeer(self):
+                  return None
+            def getHost(self):
+                  return None
+
+      class Channel:
+            def __init__(self, site):
+                  self.transport = PokerImageUploadTestCase.Transport()
+                  self.site = site
+
+      def setUp(self):
+            testclock._seconds_reset()        
+            settings_xml = """<?xml version="1.0" encoding="ISO-8859-1"?>
+<server verbose="6" />
+"""
+            self.settings = pokernetworkconfig.Config([])
+            self.settings.loadFromString(settings_xml)
+            pokersite.memcache = pokersite.MemcacheMockup
+            self.service = PokerServiceMockup()
+            self.site = pokersite.PokerSite(self.settings, pokersite.PokerAvatarResource(self.service))
+
+      def test01_render(self):
+            data = 'image data'
+            serial = 64
+            self.service.setPlayerImage(PacketPokerPlayerImage(image = base64.b64encode(data), serial = serial))
+            r = pokersite.Request(self.Channel(self.site), True)
+            r.site = r.channel.site
+            r.gotLength(0)
+            r.handleContentChunk('')
+            r.requestReceived('GET', '/%i' % serial, '')
+            self.assertSubstring('\r\n\r\n%s' % data, r.transport.getvalue())
+            self.assertEquals(serial, self.service.player_serial)
+
+      def test02_render_error(self):
+            serial = 100
+            self.service.setPlayerImage(PacketPokerPlayerImage(image = '', serial = serial))
+            r = pokersite.Request(self.Channel(self.site), True)
+            r.site = r.channel.site
+            r.gotLength(0)
+            r.handleContentChunk('')
+            r.requestReceived('GET', '/%i' % serial, '')
+            self.assertSubstring('not found', r.transport.getvalue())
+            self.assertEquals(serial, self.service.player_serial)
+
 class FilterTestCase(unittest.TestCase):
 
       def setUp(self):
@@ -501,6 +635,8 @@
     suite.addTest(loader.loadClass(FilterErrorTestCase))
     suite.addTest(loader.loadClass(FilterTestCase))
     suite.addTest(loader.loadClass(PokerResourceTestCase))
+    suite.addTest(loader.loadClass(PokerImageUploadTestCase))
+    suite.addTest(loader.loadClass(PokerAvatarResourceTestCase))
     suite.addTest(loader.loadClass(SessionTestCase))
     suite.addTest(loader.loadClass(RequestTestCase))
     suite.addTest(loader.loadClass(PokerSiteTestCase))
diff -r 69f779f2dd33 debian/apache2/sites-available/jpoker
--- a/debian/apache2/sites-available/jpoker	Mon Aug 11 17:41:40 2008 +0000
+++ b/debian/apache2/sites-available/jpoker	Tue Aug 12 17:54:56 2008 +0000
@@ -6,3 +6,7 @@
 </Proxy>
 ProxyPass /REST http://pokersource.eu/REST
 ProxyPassReverse /REST http://pokersource.eu/REST
+ProxyPass /AVATAR http://pokersource.eu/AVATAR
+ProxyPassReverse /AVATAR http://pokersource.eu/AVATAR
+ProxyPass /UPLOAD http://pokersource.eu/UPLOAD
+ProxyPassReverse /UPLOAD http://pokersource.eu/UPLOAD
diff -r 69f779f2dd33 jpoker/js/jquery.jpoker.js
--- a/jpoker/js/jquery.jpoker.js	Mon Aug 11 17:41:40 2008 +0000
+++ b/jpoker/js/jquery.jpoker.js	Tue Aug 12 17:54:57 2008 +0000
@@ -2705,6 +2705,17 @@
                 avatar_element.removeClass().addClass('jpoker_avatar jpoker_ptable_player_seat' + seat + '_avatar jpoker_avatar_default_' + avatar);
 		avatar_element.show();
 	    }
+	    var avatar_url = '/AVATAR/'+serial;
+	    server.ajax({url: avatar_url,
+			type: 'GET',
+			global: false,
+			success: function(data, status) {
+			avatar_element.css({
+				'background-image': 'url("' + avatar_url + '")',
+				    'display': 'block'
+				    });
+		    }
+		});
 	    var timeout_element = $('#player_seat' + seat  + '_timeout' + id);
 	    timeout_element.removeClass().addClass('jpoker_timeout jpoker_ptable_player_seat' + seat + '_timeout');
 
@@ -3185,7 +3196,7 @@
                     if(element) {
 			if(packet && packet.type == 'PacketPokerPersonalInfo') {
 			    $(element).html(userInfo.getHTML(packet));
-			    $('input[type=submit]').click(function() {
+			    $('.jpoker_user_info_submit').click(function() {
 				    $('.feedback').text(_("Updating..."));
 				    var info = {};
 				    $("input[type=text]", element).each(function() {
@@ -3193,6 +3204,7 @@
 					});
 				    server.setPersonalInfo(info);
 				});
+			    $('.jpoker_user_info_avatar_upload', element).ajaxForm(function(data) {alert(data);});
 			    if (packet.set_account) {
 				$('.feedback').text(_("Updated"));
 			    }
@@ -3216,17 +3228,19 @@
     jpoker.plugins.userInfo.getHTML = function(packet) {
         var t = this.templates;
 	var html = [];
-	var userInfo = t.info.supplant($.extend({
+	html.push(t.info.supplant($.extend({
 		    'firstname_title': _("First name"),
 		    'lastname_title': _("Last name"),
 		    'email_title': _("Email"),
 		    'submit_title': _("Update personal info")
-		}, packet));
-	return userInfo;
+		}, packet)));
+	html.push(t.avatar.supplant({'upload': _("Upload avatar")}));
+        return html.join('\n');
     };
 
     jpoker.plugins.userInfo.templates = {
-      info: '<table><tr><td>{firstname_title}</td><td><input type=\'text\' name=\'firstname\' value=\'{firstname}\'></input></td></tr><tr><td>{lastname_title}</td><td><input type=\'text\' name=\'lastname\' value=\'{lastname}\'></input></td></tr><tr><td>{email_title}</td><td><input type=\'text\' name=\'email\' value=\'{email}\'</td></tr><tr><td><input type=\'submit\' value=\'{submit_title}\'></td><td><div class=\'feedback\'></div></td></tr></table>'
+	info: '<table><tr><td>{firstname_title}</td><td><input type=\'text\' name=\'firstname\' value=\'{firstname}\'></input></td></tr><tr><td>{lastname_title}</td><td><input type=\'text\' name=\'lastname\' value=\'{lastname}\'></input></td></tr><tr><td>{email_title}</td><td><input type=\'text\' name=\'email\' value=\'{email}\'</td></tr><tr><td><input class=\'jpoker_user_info_submit\' type=\'submit\' value=\'{submit_title}\'></td><td><div class=\'feedback\'></div></td></tr></table>',
+	avatar: '<form class=\'jpoker_user_info_avatar_upload\' action=\'/UPLOAD\' method=\'post\' enctype=\'multipart/form-data\'><input type=\'file\' name=\'filename\'></input><input type=\'submit\' value=\'{upload}\'></input></form>'
     };
 
 })(jQuery);
diff -r 69f779f2dd33 jpoker/js/test-jpoker.js
--- a/jpoker/js/test-jpoker.js	Mon Aug 11 17:41:40 2008 +0000
+++ b/jpoker/js/test-jpoker.js	Tue Aug 12 17:54:57 2008 +0000
@@ -3342,6 +3342,33 @@
         start_and_cleanup();
     });
 
+test("jpoker.plugins.player: /AVATAR", function(){
+        expect(1);
+        stop();
+
+        var server = jpoker.serverCreate({ url: 'url' });
+        var place = $("#main");
+        var id = 'jpoker' + jpoker.serial;
+        var game_id = 100;
+
+        table_packet = { id: game_id };
+        server.tables[game_id] = new jpoker.table(server, table_packet);
+        var table = server.tables[game_id];
+
+        place.jpoker('table', 'url', game_id);
+        var player_serial = 1;
+        server.serial = player_serial;
+        var player_seat = 2;
+	server.ajax = function(options) {
+	    options.success('data', 'status');
+	};
+        table.handler(server, game_id, { type: 'PacketPokerPlayerArrive', seat: player_seat, serial: player_serial, game_id: game_id });
+        var player = server.tables[game_id].serial2player[player_serial];
+        var background = $("#player_seat2_avatar" + id).css('background-image');
+	ok(background.indexOf("AVATAR/1") >= 0, "AVATAR serial");
+        start_and_cleanup();
+    });
+
 test("jpoker.plugins.player: PacketPokerPlayerCards", function(){
         expect(6);
         stop();
@@ -3889,7 +3916,7 @@
 
 
 test("jpoker.plugins.userInfo", function(){
-        expect(6);
+        expect(8);
 	stop();
 
         var server = jpoker.serverCreate({ url: 'url' });
@@ -3922,6 +3949,8 @@
 			equals($('input[name=firstname]', element).val(), 'John');
 			equals($('input[name=lastname]', element).val(), 'Doe');
 			equals($('input[name=email]', element).val(), '[EMAIL PROTECTED]');
+			equals($('input[type=submit]').length, 2, 'user info submit');
+			equals($('.jpoker_user_info_avatar_upload input[type=submit]').length, 1, 'user info avatar submit');
 			$('#' + id).remove();
 		    }
 		    return true;
@@ -3969,7 +3998,7 @@
 				    server.notifyUpdate(packet);
 				}, 0);
 			};
-			$('input[type=submit]').click(function() {
+			$('input[type=submit]').eq(0).click(function() {
 				equals($(".feedback", element).text(), _("Updating..."));
 			    }).click();
 			return false;
diff -r 69f779f2dd33 jpoker/markup/MarkupPostBody.tiddler
--- a/jpoker/markup/MarkupPostBody.tiddler	Mon Aug 11 17:41:40 2008 +0000
+++ b/jpoker/markup/MarkupPostBody.tiddler	Tue Aug 12 17:54:57 2008 +0000
@@ -10,6 +10,7 @@
 <script src="js/jquery.ajaxQueue.js" type="text/javascript"></script>
 <script src="js/jquery.tablesorter.js" type="text/javascript"></script>
 <script src="js/jquery.progression.js" type="text/javascript"></script>
+<script src="js/jquery.form.js" type="text/javascript"></script>
 <script src="js/jquery.jpoker.js" type="text/javascript"></script>
 <script src="js/mockup.js" type="text/javascript"></script>
 <!--}}}-->
diff -r 69f779f2dd33 jpoker/test-jpoker.html
--- a/jpoker/test-jpoker.html	Mon Aug 11 17:41:40 2008 +0000
+++ b/jpoker/test-jpoker.html	Tue Aug 12 17:54:57 2008 +0000
@@ -34,6 +34,7 @@
 	<script language="JavaScript" type="text/javascript" src="js/jquery.gettext.js"></script>
 	<script language="JavaScript" type="text/javascript" src="js/jquery.tablesorter.js"></script>
 	<script language="JavaScript" type="text/javascript" src="js/jquery.progression.js"></script>
+	<script language="JavaScript" type="text/javascript" src="js/jquery.form.js"></script>
 	<script language="JavaScript" type="text/javascript" src="js/testrunner.js"></script>
 	<script language="JavaScript" type="text/javascript" src="js/json2.js"></script>
         <script>
diff -r 69f779f2dd33 jpoker/tiddlers/Copyright.tiddler
--- a/jpoker/tiddlers/Copyright.tiddler	Mon Aug 11 17:41:40 2008 +0000
+++ b/jpoker/tiddlers/Copyright.tiddler	Tue Aug 12 17:54:57 2008 +0000
@@ -55,6 +55,11 @@
 	Dual licensed under the MIT and GPL licenses
 
 Copyright for:
+	jpoker/jquery.from.js
+
+        Dual licensed under the MIT and GPL licenses
+
+Copyright for:
 	tiddlywiki as found in jpoker/poker.html
 
    (c) UnaMesa Association 2004-2007
_______________________________________________
Pokersource-users mailing list
[email protected]
https://mail.gna.org/listinfo/pokersource-users

Reply via email to