changeset 151:a159cc29b556

server side: file upload is now more generic: - RadioCol upload is managed by a specialized class - A new Avatar upload specialized class is used to set avatar browser side: radiocol.py has been updated to follow upload change
author Goffi <goffi@goffi.org>
date Fri, 28 Dec 2012 01:05:22 +0100
parents a201e368fc86
children 7e87c87b7952
files browser_side/radiocol.py libervia.tac
diffstat 2 files changed, 50 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/browser_side/radiocol.py	Mon Dec 10 20:10:33 2012 +0100
+++ b/browser_side/radiocol.py	Fri Dec 28 01:05:22 2012 +0100
@@ -82,7 +82,7 @@
         self._timer = Timer(notify=self._timeCb)
         self.setEncoding(FormPanel.ENCODING_MULTIPART)
         self.setMethod(FormPanel.METHOD_POST)
-        self.setAction("upload") # set this as appropriate
+        self.setAction("upload_radiocol")
         vPanel = VerticalPanel()
 
         hPanel = HorizontalPanel()
--- a/libervia.tac	Mon Dec 10 20:10:33 2012 +0100
+++ b/libervia.tac	Fri Dec 28 01:05:22 2012 +0100
@@ -48,8 +48,9 @@
 import tempfile, shutil, uuid
 from server_side.blog import MicroBlog
 from zope.interface import Interface, Attribute, implements
+#import time
 
-TIMEOUT = 10 #Session's time out, after that the user will be disconnected
+TIMEOUT = 600 #Session's time out, after that the user will be disconnected
 LIBERVIA_DIR = "output/"
 MEDIA_DIR = "media/"
 AVATARS_DIR = "avatars/"
@@ -663,8 +664,8 @@
 class UploadManager(Resource):
     """This class manage the upload of a file
     It redirect the stream to SàT core backend"""
-    #XXX: only used for RadioCol so far
     isLeaf = True
+    NAME = 'path' #name use by the FileUpload
 
     def __init__(self, sat_host):
         self.sat_host=sat_host
@@ -674,6 +675,14 @@
     def getTmpDir(self):
         return self.upload_dir
 
+    def _getFileName(self, request):
+        """Generate unique filename for a file"""
+        raise NotImplementedError
+
+    def _fileWritten(self, request, filepath):
+        """Called once the file is actually written on disk"""
+        raise NotImplementedError
+
     def render(self, request):
         """
         Render method with some hacks:
@@ -681,13 +690,43 @@
            - except login, every method is jsonrpc
            - user doesn't need to be authentified for isRegistered, but must be for all other methods
         """
-        filename = "%s.ogg" % str(uuid.uuid4()) #XXX: chromium doesn't seem to play song without the .ogg extension, even with audio/ogg mime-type
+        #start = time.time()
+        filename = self._getFileName(request)
         filepath = os.path.join(self.upload_dir, filename)
+        #FIXME: the uploaded file is fully loaded in memory at form parsing time so far
+        #       (see twisted.web.http.Request.requestReceived). A custom requestReceived should
+        #       be written in the futur. In addition, it is not yet possible to get progression informations
+        #       (see http://twistedmatrix.com/trac/ticket/288) 
+        
         with open(filepath,'w') as f:
-            f.write(request.args['song'][0])
+            f.write(request.args[self.NAME][0])
+        self._fileWritten(request, filepath)
+        #end = time.time()
+        #print "time spent in render: %fs" % (end - start)
+        return "OK"
+
+class UploadManagerRadioCol(UploadManager):
+    NAME = 'song'
+
+    def _getFileName(self, request):
+        return "%s.ogg" % str(uuid.uuid4()) #XXX: chromium doesn't seem to play song without the .ogg extension, even with audio/ogg mime-type
+        
+    def _fileWritten(self, request, filepath):
+        """Called once the file is actually written on disk"""
         profile = ISATSession(request.getSession()).profile
         self.sat_host.bridge.radiocolSongAdded(request.args['referee'][0], filepath, profile)
-        return "OK"
+
+class UploadManagerAvatar(UploadManager):
+    NAME = 'avatar_path'
+
+    def _getFileName(self, request):
+        return str(uuid.uuid4())
+        
+    def _fileWritten(self, request, filepath):
+        """Called once the file is actually written on disk"""
+        profile = ISATSession(request.getSession()).profile
+        print u"fichier écrit:", filepath
+        self.sat_host.bridge.setAvatar(filepath, profile)
 
 class Libervia(service.Service):
    
@@ -696,7 +735,8 @@
         root = ProtectedFile(LIBERVIA_DIR) 
         self.signal_handler = SignalHandler(self)
         _register = Register(self)
-        _upload = UploadManager(self)
+        _upload_radiocol = UploadManagerRadioCol(self)
+        _upload_avatar = UploadManagerAvatar(self)
         self.signal_handler.plugRegister(_register)
         self.sessions = {} #key = session value = user
         self.prof_connected = set() #Profiles connected
@@ -723,12 +763,13 @@
         root.putChild('json_signal_api', self.signal_handler)
         root.putChild('json_api', MethodHandler(self))
         root.putChild('register_api', _register)
-        root.putChild('upload', _upload)
+        root.putChild('upload_radiocol', _upload_radiocol)
+        root.putChild('upload_avatar', _upload_avatar)
         root.putChild('blog', MicroBlog(self))
         root.putChild('css', ProtectedFile("server_css/"))
         root.putChild(os.path.dirname(MEDIA_DIR), ProtectedFile(self.media_dir))
         root.putChild(os.path.dirname(AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, AVATARS_DIR)))
-        root.putChild('radiocol', ProtectedFile(_upload.getTmpDir(), defaultType="audio/ogg")) #We cheat for PoC because we know we are on the same host, so we use directly upload dir
+        root.putChild('radiocol', ProtectedFile(_upload_radiocol.getTmpDir(), defaultType="audio/ogg")) #We cheat for PoC because we know we are on the same host, so we use directly upload dir
         self.site = server.Site(root)
         self.site.sessionFactory = LiberviaSession