comparison libervia.tac @ 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 8635bc9db9bf
children ada146bac8fe
comparison
equal deleted inserted replaced
150:a201e368fc86 151:a159cc29b556
46 import re, glob 46 import re, glob
47 import os.path, sys 47 import os.path, sys
48 import tempfile, shutil, uuid 48 import tempfile, shutil, uuid
49 from server_side.blog import MicroBlog 49 from server_side.blog import MicroBlog
50 from zope.interface import Interface, Attribute, implements 50 from zope.interface import Interface, Attribute, implements
51 51 #import time
52 TIMEOUT = 10 #Session's time out, after that the user will be disconnected 52
53 TIMEOUT = 600 #Session's time out, after that the user will be disconnected
53 LIBERVIA_DIR = "output/" 54 LIBERVIA_DIR = "output/"
54 MEDIA_DIR = "media/" 55 MEDIA_DIR = "media/"
55 AVATARS_DIR = "avatars/" 56 AVATARS_DIR = "avatars/"
56 CARDS_DIR = "games/cards/tarot" 57 CARDS_DIR = "games/cards/tarot"
57 58
661 return jsonrpc.JSONRPC.render(self, request) 662 return jsonrpc.JSONRPC.render(self, request)
662 663
663 class UploadManager(Resource): 664 class UploadManager(Resource):
664 """This class manage the upload of a file 665 """This class manage the upload of a file
665 It redirect the stream to SàT core backend""" 666 It redirect the stream to SàT core backend"""
666 #XXX: only used for RadioCol so far
667 isLeaf = True 667 isLeaf = True
668 NAME = 'path' #name use by the FileUpload
668 669
669 def __init__(self, sat_host): 670 def __init__(self, sat_host):
670 self.sat_host=sat_host 671 self.sat_host=sat_host
671 self.upload_dir = tempfile.mkdtemp() 672 self.upload_dir = tempfile.mkdtemp()
672 self.sat_host.addCleanup(shutil.rmtree, self.upload_dir) 673 self.sat_host.addCleanup(shutil.rmtree, self.upload_dir)
673 674
674 def getTmpDir(self): 675 def getTmpDir(self):
675 return self.upload_dir 676 return self.upload_dir
677
678 def _getFileName(self, request):
679 """Generate unique filename for a file"""
680 raise NotImplementedError
681
682 def _fileWritten(self, request, filepath):
683 """Called once the file is actually written on disk"""
684 raise NotImplementedError
676 685
677 def render(self, request): 686 def render(self, request):
678 """ 687 """
679 Render method with some hacks: 688 Render method with some hacks:
680 - if login is requested, try to login with form data 689 - if login is requested, try to login with form data
681 - except login, every method is jsonrpc 690 - except login, every method is jsonrpc
682 - user doesn't need to be authentified for isRegistered, but must be for all other methods 691 - user doesn't need to be authentified for isRegistered, but must be for all other methods
683 """ 692 """
684 filename = "%s.ogg" % str(uuid.uuid4()) #XXX: chromium doesn't seem to play song without the .ogg extension, even with audio/ogg mime-type 693 #start = time.time()
694 filename = self._getFileName(request)
685 filepath = os.path.join(self.upload_dir, filename) 695 filepath = os.path.join(self.upload_dir, filename)
696 #FIXME: the uploaded file is fully loaded in memory at form parsing time so far
697 # (see twisted.web.http.Request.requestReceived). A custom requestReceived should
698 # be written in the futur. In addition, it is not yet possible to get progression informations
699 # (see http://twistedmatrix.com/trac/ticket/288)
700
686 with open(filepath,'w') as f: 701 with open(filepath,'w') as f:
687 f.write(request.args['song'][0]) 702 f.write(request.args[self.NAME][0])
703 self._fileWritten(request, filepath)
704 #end = time.time()
705 #print "time spent in render: %fs" % (end - start)
706 return "OK"
707
708 class UploadManagerRadioCol(UploadManager):
709 NAME = 'song'
710
711 def _getFileName(self, request):
712 return "%s.ogg" % str(uuid.uuid4()) #XXX: chromium doesn't seem to play song without the .ogg extension, even with audio/ogg mime-type
713
714 def _fileWritten(self, request, filepath):
715 """Called once the file is actually written on disk"""
688 profile = ISATSession(request.getSession()).profile 716 profile = ISATSession(request.getSession()).profile
689 self.sat_host.bridge.radiocolSongAdded(request.args['referee'][0], filepath, profile) 717 self.sat_host.bridge.radiocolSongAdded(request.args['referee'][0], filepath, profile)
690 return "OK" 718
719 class UploadManagerAvatar(UploadManager):
720 NAME = 'avatar_path'
721
722 def _getFileName(self, request):
723 return str(uuid.uuid4())
724
725 def _fileWritten(self, request, filepath):
726 """Called once the file is actually written on disk"""
727 profile = ISATSession(request.getSession()).profile
728 print u"fichier écrit:", filepath
729 self.sat_host.bridge.setAvatar(filepath, profile)
691 730
692 class Libervia(service.Service): 731 class Libervia(service.Service):
693 732
694 def __init__(self): 733 def __init__(self):
695 self._cleanup = [] 734 self._cleanup = []
696 root = ProtectedFile(LIBERVIA_DIR) 735 root = ProtectedFile(LIBERVIA_DIR)
697 self.signal_handler = SignalHandler(self) 736 self.signal_handler = SignalHandler(self)
698 _register = Register(self) 737 _register = Register(self)
699 _upload = UploadManager(self) 738 _upload_radiocol = UploadManagerRadioCol(self)
739 _upload_avatar = UploadManagerAvatar(self)
700 self.signal_handler.plugRegister(_register) 740 self.signal_handler.plugRegister(_register)
701 self.sessions = {} #key = session value = user 741 self.sessions = {} #key = session value = user
702 self.prof_connected = set() #Profiles connected 742 self.prof_connected = set() #Profiles connected
703 self.action_handler = SATActionIDHandler() 743 self.action_handler = SATActionIDHandler()
704 ## bridge ## 744 ## bridge ##
721 self.media_dir = self.bridge.getConfig('','media_dir') 761 self.media_dir = self.bridge.getConfig('','media_dir')
722 self.local_dir = self.bridge.getConfig('','local_dir') 762 self.local_dir = self.bridge.getConfig('','local_dir')
723 root.putChild('json_signal_api', self.signal_handler) 763 root.putChild('json_signal_api', self.signal_handler)
724 root.putChild('json_api', MethodHandler(self)) 764 root.putChild('json_api', MethodHandler(self))
725 root.putChild('register_api', _register) 765 root.putChild('register_api', _register)
726 root.putChild('upload', _upload) 766 root.putChild('upload_radiocol', _upload_radiocol)
767 root.putChild('upload_avatar', _upload_avatar)
727 root.putChild('blog', MicroBlog(self)) 768 root.putChild('blog', MicroBlog(self))
728 root.putChild('css', ProtectedFile("server_css/")) 769 root.putChild('css', ProtectedFile("server_css/"))
729 root.putChild(os.path.dirname(MEDIA_DIR), ProtectedFile(self.media_dir)) 770 root.putChild(os.path.dirname(MEDIA_DIR), ProtectedFile(self.media_dir))
730 root.putChild(os.path.dirname(AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, AVATARS_DIR))) 771 root.putChild(os.path.dirname(AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, AVATARS_DIR)))
731 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 772 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
732 self.site = server.Site(root) 773 self.site = server.Site(root)
733 self.site.sessionFactory = LiberviaSession 774 self.site.sessionFactory = LiberviaSession
734 775
735 def addCleanup(self, callback, *args, **kwargs): 776 def addCleanup(self, callback, *args, **kwargs):
736 """Add cleaning method to call when service is stopped 777 """Add cleaning method to call when service is stopped