Mercurial > libervia-web
comparison src/server/server.py @ 451:1a0cec9b0f1e
better PEP-8 compliance
author | souliane <souliane@mailoo.org> |
---|---|
date | Tue, 20 May 2014 10:54:03 +0200 |
parents | 981ed669d3b3 |
children | da2a7f2b34c9 |
comparison
equal
deleted
inserted
replaced
450:41aae13cab2b | 451:1a0cec9b0f1e |
---|---|
65 jid = Attribute("JID associated with the profile") | 65 jid = Attribute("JID associated with the profile") |
66 | 66 |
67 | 67 |
68 class SATSession(object): | 68 class SATSession(object): |
69 implements(ISATSession) | 69 implements(ISATSession) |
70 | |
70 def __init__(self, session): | 71 def __init__(self, session): |
71 self.profile = None | 72 self.profile = None |
72 self.jid = None | 73 self.jid = None |
73 | 74 |
74 | 75 |
91 | 92 |
92 def touch(self): | 93 def touch(self): |
93 if not self.__lock: | 94 if not self.__lock: |
94 server.Session.touch(self) | 95 server.Session.touch(self) |
95 | 96 |
97 | |
96 class ProtectedFile(File): | 98 class ProtectedFile(File): |
97 """A File class which doens't show directory listing""" | 99 """A File class which doens't show directory listing""" |
98 | 100 |
99 def directoryListing(self): | 101 def directoryListing(self): |
100 return NoResource() | 102 return NoResource() |
101 | 103 |
104 | |
102 class SATActionIDHandler(object): | 105 class SATActionIDHandler(object): |
103 """Manage SàT action action_id lifecycle""" | 106 """Manage SàT action action_id lifecycle""" |
104 ID_LIFETIME = 30 #after this time (in seconds), action_id will be suppressed and action result will be ignored | 107 ID_LIFETIME = 30 # after this time (in seconds), action_id will be suppressed and action result will be ignored |
105 | 108 |
106 def __init__(self): | 109 def __init__(self): |
107 self.waiting_ids = {} | 110 self.waiting_ids = {} |
108 | 111 |
109 def waitForId(self, callback, action_id, profile, *args, **kwargs): | 112 def waitForId(self, callback, action_id, profile, *args, **kwargs): |
118 reactor.callLater(self.ID_LIFETIME, self.purgeID, action_tuple) | 121 reactor.callLater(self.ID_LIFETIME, self.purgeID, action_tuple) |
119 | 122 |
120 def purgeID(self, action_tuple): | 123 def purgeID(self, action_tuple): |
121 """Called when an action_id has not be handled in time""" | 124 """Called when an action_id has not be handled in time""" |
122 if action_tuple in self.waiting_ids: | 125 if action_tuple in self.waiting_ids: |
123 log.warning ("action of action_id %s [%s] has not been managed, action_id is now ignored" % action_tuple) | 126 log.warning("action of action_id %s [%s] has not been managed, action_id is now ignored" % action_tuple) |
124 del self.waiting_ids[action_tuple] | 127 del self.waiting_ids[action_tuple] |
125 | 128 |
126 def actionResultCb(self, answer_type, action_id, data, profile): | 129 def actionResultCb(self, answer_type, action_id, data, profile): |
127 """Manage the actionResult signal""" | 130 """Manage the actionResult signal""" |
128 action_tuple = (action_id, profile) | 131 action_tuple = (action_id, profile) |
129 if action_tuple in self.waiting_ids: | 132 if action_tuple in self.waiting_ids: |
130 callback, args, kwargs = self.waiting_ids[action_tuple] | 133 callback, args, kwargs = self.waiting_ids[action_tuple] |
131 del self.waiting_ids[action_tuple] | 134 del self.waiting_ids[action_tuple] |
132 callback(answer_type, action_id, data, *args, **kwargs) | 135 callback(answer_type, action_id, data, *args, **kwargs) |
133 | 136 |
137 | |
134 class JSONRPCMethodManager(jsonrpc.JSONRPC): | 138 class JSONRPCMethodManager(jsonrpc.JSONRPC): |
135 | 139 |
136 def __init__(self, sat_host): | 140 def __init__(self, sat_host): |
137 jsonrpc.JSONRPC.__init__(self) | 141 jsonrpc.JSONRPC.__init__(self) |
138 self.sat_host=sat_host | 142 self.sat_host = sat_host |
139 | 143 |
140 def asyncBridgeCall(self, method_name, *args, **kwargs): | 144 def asyncBridgeCall(self, method_name, *args, **kwargs): |
141 """Call an asynchrone bridge method and return a deferred | 145 """Call an asynchrone bridge method and return a deferred |
142 @param method_name: name of the method as a unicode | 146 @param method_name: name of the method as a unicode |
143 @return: a deferred which trigger the result | 147 @return: a deferred which trigger the result |
172 self.session = request.getSession() | 176 self.session = request.getSession() |
173 profile = ISATSession(self.session).profile | 177 profile = ISATSession(self.session).profile |
174 if not profile: | 178 if not profile: |
175 #user is not identified, we return a jsonrpc fault | 179 #user is not identified, we return a jsonrpc fault |
176 parsed = jsonrpclib.loads(request.content.read()) | 180 parsed = jsonrpclib.loads(request.content.read()) |
177 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") #FIXME: define some standard error codes for libervia | 181 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia |
178 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) | 182 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
179 return jsonrpc.JSONRPC.render(self, request) | 183 return jsonrpc.JSONRPC.render(self, request) |
180 | 184 |
181 def jsonrpc_getProfileJid(self): | 185 def jsonrpc_getProfileJid(self): |
182 """Return the jid of the profile""" | 186 """Return the jid of the profile""" |
230 @param presence: value from ("", "chat", "away", "dnd", "xa") | 234 @param presence: value from ("", "chat", "away", "dnd", "xa") |
231 @param status: any string to describe your status | 235 @param status: any string to describe your status |
232 """ | 236 """ |
233 profile = ISATSession(self.session).profile | 237 profile = ISATSession(self.session).profile |
234 self.sat_host.bridge.setPresence('', presence, {'': status}, profile) | 238 self.sat_host.bridge.setPresence('', presence, {'': status}, profile) |
235 | |
236 | 239 |
237 def jsonrpc_sendMessage(self, to_jid, msg, subject, type_, options={}): | 240 def jsonrpc_sendMessage(self, to_jid, msg, subject, type_, options={}): |
238 """send message""" | 241 """send message""" |
239 profile = ISATSession(self.session).profile | 242 profile = ISATSession(self.session).profile |
240 return self.asyncBridgeCall("sendMessage", to_jid, msg, subject, type_, options, profile) | 243 return self.asyncBridgeCall("sendMessage", to_jid, msg, subject, type_, options, profile) |
340 @param node: comments node | 343 @param node: comments node |
341 """ | 344 """ |
342 profile = ISATSession(self.session).profile | 345 profile = ISATSession(self.session).profile |
343 d = self.asyncBridgeCall("getGroupBlogComments", service, node, profile) | 346 d = self.asyncBridgeCall("getGroupBlogComments", service, node, profile) |
344 return d | 347 return d |
345 | |
346 | 348 |
347 def jsonrpc_getPresenceStatuses(self): | 349 def jsonrpc_getPresenceStatuses(self): |
348 """Get Presence information for connected contacts""" | 350 """Get Presence information for connected contacts""" |
349 profile = ISATSession(self.session).profile | 351 profile = ISATSession(self.session).profile |
350 return self.sat_host.bridge.getPresenceStatuses(profile) | 352 return self.sat_host.bridge.getPresenceStatuses(profile) |
359 return {} | 361 return {} |
360 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): | 362 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): |
361 log.error("Trying to get history from a different jid, maybe a hack attempt ?") | 363 log.error("Trying to get history from a different jid, maybe a hack attempt ?") |
362 return {} | 364 return {} |
363 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile) | 365 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile) |
366 | |
364 def show(result_dbus): | 367 def show(result_dbus): |
365 result = [] | 368 result = [] |
366 for line in result_dbus: | 369 for line in result_dbus: |
367 #XXX: we have to do this stupid thing because Python D-Bus use its own types instead of standard types | 370 #XXX: we have to do this stupid thing because Python D-Bus use its own types instead of standard types |
368 # and txJsonRPC doesn't accept D-Bus types, resulting in a empty query | 371 # and txJsonRPC doesn't accept D-Bus types, resulting in a empty query |
427 self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile) | 430 self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile) |
428 | 431 |
429 def jsonrpc_getTarotCardsPaths(self): | 432 def jsonrpc_getTarotCardsPaths(self): |
430 """Give the path of all the tarot cards""" | 433 """Give the path of all the tarot cards""" |
431 _join = os.path.join | 434 _join = os.path.join |
432 _media_dir = _join(self.sat_host.media_dir,'') | 435 _media_dir = _join(self.sat_host.media_dir, '') |
433 return map(lambda x: _join(C.MEDIA_DIR, x[len(_media_dir):]), glob.glob(_join(_media_dir, C.CARDS_DIR, '*_*.png'))); | 436 return map(lambda x: _join(C.MEDIA_DIR, x[len(_media_dir):]), glob.glob(_join(_media_dir, C.CARDS_DIR, '*_*.png'))) |
434 | 437 |
435 def jsonrpc_tarotGameReady(self, player, referee): | 438 def jsonrpc_tarotGameReady(self, player, referee): |
436 """Tell to the server that we are ready to start the game""" | 439 """Tell to the server that we are ready to start the game""" |
437 profile = ISATSession(self.session).profile | 440 profile = ISATSession(self.session).profile |
438 self.sat_host.bridge.tarotGameReady(player, referee, profile) | 441 self.sat_host.bridge.tarotGameReady(player, referee, profile) |
552 """This class manage the registration procedure with SàT | 555 """This class manage the registration procedure with SàT |
553 It provide an api for the browser, check password and setup the web server""" | 556 It provide an api for the browser, check password and setup the web server""" |
554 | 557 |
555 def __init__(self, sat_host): | 558 def __init__(self, sat_host): |
556 JSONRPCMethodManager.__init__(self, sat_host) | 559 JSONRPCMethodManager.__init__(self, sat_host) |
557 self.profiles_waiting={} | 560 self.profiles_waiting = {} |
558 self.request=None | 561 self.request = None |
559 | 562 |
560 def getWaitingRequest(self, profile): | 563 def getWaitingRequest(self, profile): |
561 """Tell if a profile is trying to log in""" | 564 """Tell if a profile is trying to log in""" |
562 if self.profiles_waiting.has_key(profile): | 565 if profile in self.profiles_waiting: |
563 return self.profiles_waiting[profile] | 566 return self.profiles_waiting[profile] |
564 else: | 567 else: |
565 return None | 568 return None |
566 | 569 |
567 def render(self, request): | 570 def render(self, request): |
579 if method not in ['isRegistered', 'registerParams', 'getMenus']: | 582 if method not in ['isRegistered', 'registerParams', 'getMenus']: |
580 #if we don't call these methods, we need to be identified | 583 #if we don't call these methods, we need to be identified |
581 profile = ISATSession(_session).profile | 584 profile = ISATSession(_session).profile |
582 if not profile: | 585 if not profile: |
583 #user is not identified, we return a jsonrpc fault | 586 #user is not identified, we return a jsonrpc fault |
584 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") #FIXME: define some standard error codes for libervia | 587 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia |
585 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) | 588 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
586 self.request = request | 589 self.request = request |
587 return jsonrpc.JSONRPC.render(self, request) | 590 return jsonrpc.JSONRPC.render(self, request) |
588 | 591 |
589 def loginOrRegister(self, request): | 592 def loginOrRegister(self, request): |
741 return self.sat_host.bridge.isConnected(profile) | 744 return self.sat_host.bridge.isConnected(profile) |
742 | 745 |
743 def jsonrpc_connect(self): | 746 def jsonrpc_connect(self): |
744 _session = self.request.getSession() | 747 _session = self.request.getSession() |
745 profile = ISATSession(_session).profile | 748 profile = ISATSession(_session).profile |
746 if self.profiles_waiting.has_key(profile): | 749 if profile in self.profiles_waiting: |
747 raise jsonrpclib.Fault(1,'Already waiting') #FIXME: define some standard error codes for libervia | 750 raise jsonrpclib.Fault(1, 'Already waiting') # FIXME: define some standard error codes for libervia |
748 self.profiles_waiting[profile] = self.request | 751 self.profiles_waiting[profile] = self.request |
749 self.sat_host.bridge.connect(profile) | 752 self.sat_host.bridge.connect(profile) |
750 return server.NOT_DONE_YET | 753 return server.NOT_DONE_YET |
751 | 754 |
752 def jsonrpc_isRegistered(self): | 755 def jsonrpc_isRegistered(self): |
799 | 802 |
800 class SignalHandler(jsonrpc.JSONRPC): | 803 class SignalHandler(jsonrpc.JSONRPC): |
801 | 804 |
802 def __init__(self, sat_host): | 805 def __init__(self, sat_host): |
803 Resource.__init__(self) | 806 Resource.__init__(self) |
804 self.register=None | 807 self.register = None |
805 self.sat_host=sat_host | 808 self.sat_host = sat_host |
806 self.signalDeferred = {} | 809 self.signalDeferred = {} |
807 self.queue = {} | 810 self.queue = {} |
808 | 811 |
809 def plugRegister(self, register): | 812 def plugRegister(self, register): |
810 self.register = register | 813 self.register = register |
812 def jsonrpc_getSignals(self): | 815 def jsonrpc_getSignals(self): |
813 """Keep the connection alive until a signal is received, then send it | 816 """Keep the connection alive until a signal is received, then send it |
814 @return: (signal, *signal_args)""" | 817 @return: (signal, *signal_args)""" |
815 _session = self.request.getSession() | 818 _session = self.request.getSession() |
816 profile = ISATSession(_session).profile | 819 profile = ISATSession(_session).profile |
817 if profile in self.queue: #if we have signals to send in queue | 820 if profile in self.queue: # if we have signals to send in queue |
818 if self.queue[profile]: | 821 if self.queue[profile]: |
819 return self.queue[profile].pop(0) | 822 return self.queue[profile].pop(0) |
820 else: | 823 else: |
821 #the queue is empty, we delete the profile from queue | 824 #the queue is empty, we delete the profile from queue |
822 del self.queue[profile] | 825 del self.queue[profile] |
823 _session.lock() #we don't want the session to expire as long as this connection is active | 826 _session.lock() # we don't want the session to expire as long as this connection is active |
827 | |
824 def unlock(signal, profile): | 828 def unlock(signal, profile): |
825 _session.unlock() | 829 _session.unlock() |
826 try: | 830 try: |
827 source_defer = self.signalDeferred[profile] | 831 source_defer = self.signalDeferred[profile] |
828 if source_defer.called and source_defer.result[0] == "disconnected": | 832 if source_defer.called and source_defer.result[0] == "disconnected": |
844 return | 848 return |
845 if profile in self.signalDeferred: | 849 if profile in self.signalDeferred: |
846 self.signalDeferred[profile].callback((function_name,args[:-1])) | 850 self.signalDeferred[profile].callback((function_name,args[:-1])) |
847 del self.signalDeferred[profile] | 851 del self.signalDeferred[profile] |
848 else: | 852 else: |
849 if not self.queue.has_key(profile): | 853 if profile not in self.queue: |
850 self.queue[profile] = [] | 854 self.queue[profile] = [] |
851 self.queue[profile].append((function_name, args[:-1])) | 855 self.queue[profile].append((function_name, args[:-1])) |
852 return genericCb | 856 return genericCb |
853 | 857 |
854 def connected(self, profile): | 858 def connected(self, profile): |
864 self.sat_host.prof_connected.remove(profile) | 868 self.sat_host.prof_connected.remove(profile) |
865 if profile in self.signalDeferred: | 869 if profile in self.signalDeferred: |
866 self.signalDeferred[profile].callback(("disconnected",)) | 870 self.signalDeferred[profile].callback(("disconnected",)) |
867 del self.signalDeferred[profile] | 871 del self.signalDeferred[profile] |
868 else: | 872 else: |
869 if not self.queue.has_key(profile): | 873 if profile not in self.queue: |
870 self.queue[profile] = [] | 874 self.queue[profile] = [] |
871 self.queue[profile].append(("disconnected",)) | 875 self.queue[profile].append(("disconnected",)) |
872 | 876 |
873 | |
874 def connectionError(self, error_type, profile): | 877 def connectionError(self, error_type, profile): |
875 assert(self.register) #register must be plugged | 878 assert(self.register) # register must be plugged |
876 request = self.register.getWaitingRequest(profile) | 879 request = self.register.getWaitingRequest(profile) |
877 if request: #The user is trying to log in | 880 if request: # The user is trying to log in |
878 if error_type == "AUTH_ERROR": | 881 if error_type == "AUTH_ERROR": |
879 _error_t = "AUTH ERROR" | 882 _error_t = "AUTH ERROR" |
880 else: | 883 else: |
881 _error_t = "UNKNOWN" | 884 _error_t = "UNKNOWN" |
882 self.register._logginError(profile, request, _error_t) | 885 self.register._logginError(profile, request, _error_t) |
888 _session = request.getSession() | 891 _session = request.getSession() |
889 parsed = jsonrpclib.loads(request.content.read()) | 892 parsed = jsonrpclib.loads(request.content.read()) |
890 profile = ISATSession(_session).profile | 893 profile = ISATSession(_session).profile |
891 if not profile: | 894 if not profile: |
892 #user is not identified, we return a jsonrpc fault | 895 #user is not identified, we return a jsonrpc fault |
893 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") #FIXME: define some standard error codes for libervia | 896 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia |
894 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) | 897 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
895 self.request = request | 898 self.request = request |
896 return jsonrpc.JSONRPC.render(self, request) | 899 return jsonrpc.JSONRPC.render(self, request) |
900 | |
897 | 901 |
898 class UploadManager(Resource): | 902 class UploadManager(Resource): |
899 """This class manage the upload of a file | 903 """This class manage the upload of a file |
900 It redirect the stream to SàT core backend""" | 904 It redirect the stream to SàT core backend""" |
901 isLeaf = True | 905 isLeaf = True |
902 NAME = 'path' #name use by the FileUpload | 906 NAME = 'path' # name use by the FileUpload |
903 | 907 |
904 def __init__(self, sat_host): | 908 def __init__(self, sat_host): |
905 self.sat_host=sat_host | 909 self.sat_host = sat_host |
906 self.upload_dir = tempfile.mkdtemp() | 910 self.upload_dir = tempfile.mkdtemp() |
907 self.sat_host.addCleanup(shutil.rmtree, self.upload_dir) | 911 self.sat_host.addCleanup(shutil.rmtree, self.upload_dir) |
908 | 912 |
909 def getTmpDir(self): | 913 def getTmpDir(self): |
910 return self.upload_dir | 914 return self.upload_dir |
934 #FIXME: the uploaded file is fully loaded in memory at form parsing time so far | 938 #FIXME: the uploaded file is fully loaded in memory at form parsing time so far |
935 # (see twisted.web.http.Request.requestReceived). A custom requestReceived should | 939 # (see twisted.web.http.Request.requestReceived). A custom requestReceived should |
936 # be written in the futur. In addition, it is not yet possible to get progression informations | 940 # be written in the futur. In addition, it is not yet possible to get progression informations |
937 # (see http://twistedmatrix.com/trac/ticket/288) | 941 # (see http://twistedmatrix.com/trac/ticket/288) |
938 | 942 |
939 with open(filepath,'w') as f: | 943 with open(filepath, 'w') as f: |
940 f.write(request.args[self.NAME][0]) | 944 f.write(request.args[self.NAME][0]) |
941 | 945 |
942 def finish(d): | 946 def finish(d): |
943 error = isinstance(d, Exception) or isinstance (d, Failure) | 947 error = isinstance(d, Exception) or isinstance(d, Failure) |
944 request.write('KO' if error else 'OK') | 948 request.write('KO' if error else 'OK') |
945 # TODO: would be great to re-use the original Exception class and message | 949 # TODO: would be great to re-use the original Exception class and message |
946 # but it is lost in the middle of the backtrace and encapsulated within | 950 # but it is lost in the middle of the backtrace and encapsulated within |
947 # a DBusException instance --> extract the data from the backtrace? | 951 # a DBusException instance --> extract the data from the backtrace? |
948 request.finish() | 952 request.finish() |
1046 self.signal_handler = SignalHandler(self) | 1050 self.signal_handler = SignalHandler(self) |
1047 _register = Register(self) | 1051 _register = Register(self) |
1048 _upload_radiocol = UploadManagerRadioCol(self) | 1052 _upload_radiocol = UploadManagerRadioCol(self) |
1049 _upload_avatar = UploadManagerAvatar(self) | 1053 _upload_avatar = UploadManagerAvatar(self) |
1050 self.signal_handler.plugRegister(_register) | 1054 self.signal_handler.plugRegister(_register) |
1051 self.sessions = {} #key = session value = user | 1055 self.sessions = {} # key = session value = user |
1052 self.prof_connected = set() #Profiles connected | 1056 self.prof_connected = set() # Profiles connected |
1053 self.action_handler = SATActionIDHandler() | 1057 self.action_handler = SATActionIDHandler() |
1054 ## bridge ## | 1058 ## bridge ## |
1055 try: | 1059 try: |
1056 self.bridge=DBusBridgeFrontend() | 1060 self.bridge = DBusBridgeFrontend() |
1057 except BridgeExceptionNoService: | 1061 except BridgeExceptionNoService: |
1058 print(u"Can't connect to SàT backend, are you sure it's launched ?") | 1062 print(u"Can't connect to SàT backend, are you sure it's launched ?") |
1059 sys.exit(1) | 1063 sys.exit(1) |
1064 | |
1060 def backendReady(dummy): | 1065 def backendReady(dummy): |
1061 self.bridge.register("connected", self.signal_handler.connected) | 1066 self.bridge.register("connected", self.signal_handler.connected) |
1062 self.bridge.register("disconnected", self.signal_handler.disconnected) | 1067 self.bridge.register("disconnected", self.signal_handler.disconnected) |
1063 self.bridge.register("connectionError", self.signal_handler.connectionError) | 1068 self.bridge.register("connectionError", self.signal_handler.connectionError) |
1064 self.bridge.register("actionResult", self.action_handler.actionResultCb) | 1069 self.bridge.register("actionResult", self.action_handler.actionResultCb) |