comparison libervia_server/__init__.py @ 444:b64e528fb524

server side: use of bridge's getReady to be sure that backend is initialised at launch
author Goffi <goffi@goffi.org>
date Thu, 15 May 2014 20:27:52 +0200
parents 582c435dab6b
children c0ff91cabea0
comparison
equal deleted inserted replaced
443:eca26481176f 444:b64e528fb524
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from twisted.application import internet, service 20 from twisted.application import service
21 from twisted.internet import glib2reactor 21 from twisted.internet import glib2reactor
22 glib2reactor.install() 22 glib2reactor.install()
23 from twisted.internet import reactor, defer 23 from twisted.internet import reactor, defer
24 from twisted.web import server 24 from twisted.web import server
25 from twisted.web.static import File 25 from twisted.web.static import File
713 #and now we disconnect the profile 713 #and now we disconnect the profile
714 self.sat_host.bridge.disconnect(profile) 714 self.sat_host.bridge.disconnect(profile)
715 715
716 _session.notifyOnExpire(onExpire) 716 _session.notifyOnExpire(onExpire)
717 717
718 d = defer.Deferred()
719 return result('LOGGED') 718 return result('LOGGED')
720 719
721 def _logginError(self, login, request, error_type): 720 def _logginError(self, login, request, error_type):
722 """Something went wrong during loggin, return an error""" 721 """Something went wrong during loggin, return an error"""
723 self.__cleanWaiting(login) 722 self.__cleanWaiting(login)
997 if not kwargs: 996 if not kwargs:
998 # During the loading of the twisted plugins, we just need the default values. 997 # During the loading of the twisted plugins, we just need the default values.
999 # This part is not executed when the plugin is actually started. 998 # This part is not executed when the plugin is actually started.
1000 for name, value in [(option[0], option[2]) for option in self.OPT_PARAMETERS]: 999 for name, value in [(option[0], option[2]) for option in self.OPT_PARAMETERS]:
1001 kwargs[name] = value 1000 kwargs[name] = value
1002 1001 self.initialised = defer.Deferred()
1003 self.connection_type = kwargs['connection_type'] 1002 self.connection_type = kwargs['connection_type']
1004 self.port = kwargs['port'] 1003 self.port = kwargs['port']
1005 self.port_https = kwargs['port_https'] 1004 self.port_https = kwargs['port_https']
1006 self.port_https_ext = kwargs['port_https_ext'] 1005 self.port_https_ext = kwargs['port_https_ext']
1007 if not self.port_https_ext: 1006 if not self.port_https_ext:
1023 try: 1022 try:
1024 self.bridge=DBusBridgeFrontend() 1023 self.bridge=DBusBridgeFrontend()
1025 except BridgeExceptionNoService: 1024 except BridgeExceptionNoService:
1026 print(u"Can't connect to SàT backend, are you sure it's launched ?") 1025 print(u"Can't connect to SàT backend, are you sure it's launched ?")
1027 sys.exit(1) 1026 sys.exit(1)
1028 self.bridge.register("connected", self.signal_handler.connected) 1027 def backendReady(dummy):
1029 self.bridge.register("disconnected", self.signal_handler.disconnected) 1028 self.bridge.register("connected", self.signal_handler.connected)
1030 self.bridge.register("connectionError", self.signal_handler.connectionError) 1029 self.bridge.register("disconnected", self.signal_handler.disconnected)
1031 self.bridge.register("actionResult", self.action_handler.actionResultCb) 1030 self.bridge.register("connectionError", self.signal_handler.connectionError)
1032 #core 1031 self.bridge.register("actionResult", self.action_handler.actionResultCb)
1033 for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted', 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']: 1032 #core
1034 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name)) 1033 for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted', 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']:
1035 #plugins 1034 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
1036 for signal_name in ['personalEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat', 1035 #plugins
1037 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers', 1036 for signal_name in ['personalEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat',
1038 'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers', 1037 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers',
1039 'roomLeft', 'roomUserChangedNick', 'chatStateReceived']: 1038 'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers',
1040 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name), "plugin") 1039 'roomLeft', 'roomUserChangedNick', 'chatStateReceived']:
1041 self.media_dir = self.bridge.getConfig('', 'media_dir') 1040 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name), "plugin")
1042 self.local_dir = self.bridge.getConfig('', 'local_dir') 1041 self.media_dir = self.bridge.getConfig('', 'media_dir')
1043 root.putChild('', Redirect('libervia.html')) 1042 self.local_dir = self.bridge.getConfig('', 'local_dir')
1044 root.putChild('json_signal_api', self.signal_handler) 1043 root.putChild('', Redirect('libervia.html'))
1045 root.putChild('json_api', MethodHandler(self)) 1044 root.putChild('json_signal_api', self.signal_handler)
1046 root.putChild('register_api', _register) 1045 root.putChild('json_api', MethodHandler(self))
1047 root.putChild('upload_radiocol', _upload_radiocol) 1046 root.putChild('register_api', _register)
1048 root.putChild('upload_avatar', _upload_avatar) 1047 root.putChild('upload_radiocol', _upload_radiocol)
1049 root.putChild('blog', MicroBlog(self)) 1048 root.putChild('upload_avatar', _upload_avatar)
1050 root.putChild('css', ProtectedFile("server_css/")) 1049 root.putChild('blog', MicroBlog(self))
1051 root.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir)) 1050 root.putChild('css', ProtectedFile("server_css/"))
1052 root.putChild(os.path.dirname(C.AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, C.AVATARS_DIR))) 1051 root.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir))
1053 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 1052 root.putChild(os.path.dirname(C.AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, C.AVATARS_DIR)))
1054 self.site = server.Site(root) 1053 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
1055 self.site.sessionFactory = LiberviaSession 1054 self.site = server.Site(root)
1055 self.site.sessionFactory = LiberviaSession
1056
1057 self.bridge.getReady(lambda: self.initialised.callback(None),
1058 lambda failure: self.initialised.errback(Exception(failure)))
1059 self.initialised.addCallback(backendReady)
1060 self.initialised.addErrback(lambda failure: log.error("Init error: %s" % failure))
1056 1061
1057 def addCleanup(self, callback, *args, **kwargs): 1062 def addCleanup(self, callback, *args, **kwargs):
1058 """Add cleaning method to call when service is stopped 1063 """Add cleaning method to call when service is stopped
1059 cleaning method will be called in reverse order of they insertion 1064 cleaning method will be called in reverse order of they insertion
1060 @param callback: callable to call on service stop 1065 @param callback: callable to call on service stop
1061 @param *args: list of arguments of the callback 1066 @param *args: list of arguments of the callback
1062 @param **kwargs: list of keyword arguments of the callback""" 1067 @param **kwargs: list of keyword arguments of the callback"""
1063 self._cleanup.insert(0, (callback, args, kwargs)) 1068 self._cleanup.insert(0, (callback, args, kwargs))
1064 1069
1065 def startService(self): 1070 def startService(self):
1066 if self.connection_type in ('https', 'both'): 1071 def initOk(dummy):
1067 if not ssl_available: 1072 if self.connection_type in ('https', 'both'):
1068 raise(ImportError(_("Python module pyOpenSSL is not installed!"))) 1073 if not ssl_available:
1069 try: 1074 raise(ImportError(_("Python module pyOpenSSL is not installed!")))
1070 with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert: 1075 try:
1071 try: 1076 with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert:
1072 cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read()) 1077 try:
1073 except OpenSSL.crypto.Error as e: 1078 cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read())
1074 log.error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate) 1079 except OpenSSL.crypto.Error as e:
1075 raise e 1080 log.error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate)
1076 except IOError as e: 1081 raise e
1077 log.error(_("The file '%s' doesn't exist") % self.ssl_certificate) 1082 except IOError as e:
1078 raise e 1083 log.error(_("The file '%s' doesn't exist") % self.ssl_certificate)
1079 reactor.listenSSL(self.port_https, self.site, cert.options()) 1084 raise e
1080 if self.connection_type in ('http', 'both'): 1085 reactor.listenSSL(self.port_https, self.site, cert.options())
1081 if self.connection_type == 'both' and self.redirect_to_https: 1086 if self.connection_type in ('http', 'both'):
1082 reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext))) 1087 if self.connection_type == 'both' and self.redirect_to_https:
1083 else: 1088 reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext)))
1084 reactor.listenTCP(self.port, self.site) 1089 else:
1090 reactor.listenTCP(self.port, self.site)
1091 self.initialised.addCallback(initOk)
1085 1092
1086 def stopService(self): 1093 def stopService(self):
1087 print "launching cleaning methods" 1094 print "launching cleaning methods"
1088 for callback, args, kwargs in self._cleanup: 1095 for callback, args, kwargs in self._cleanup:
1089 callback(*args, **kwargs) 1096 callback(*args, **kwargs)