Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0045.py @ 319:5bb1cfc105d0
plugin xep-0045: misc improvments
- added getUniqueRoomName method to create a room with no name conflict (need improvment)
- if the room is new, the basic configuration is used to create it
- _join is now used for bridge, and join can be used if we need the deferred
- a trigger is added when a user join a room ("MUC user joined")
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 06 May 2011 15:38:32 +0200 |
parents | 7c79d4a8c9e6 |
children | abe08fcb42d7 |
comparison
equal
deleted
inserted
replaced
318:b544bec477dd | 319:5bb1cfc105d0 |
---|---|
24 from twisted.internet import protocol, defer, threads, reactor | 24 from twisted.internet import protocol, defer, threads, reactor |
25 from twisted.words.protocols.jabber import client, jid, xmlstream | 25 from twisted.words.protocols.jabber import client, jid, xmlstream |
26 from twisted.words.protocols.jabber import error as jab_error | 26 from twisted.words.protocols.jabber import error as jab_error |
27 from twisted.words.protocols.jabber.xmlstream import IQ | 27 from twisted.words.protocols.jabber.xmlstream import IQ |
28 import os.path | 28 import os.path |
29 import pdb | 29 import uuid |
30 | 30 |
31 from zope.interface import implements | 31 from zope.interface import implements |
32 | 32 |
33 from wokkel import disco, iwokkel, muc | 33 from wokkel import disco, iwokkel, muc |
34 | 34 |
56 | 56 |
57 def __init__(self, host): | 57 def __init__(self, host): |
58 info(_("Plugin XEP_0045 initialization")) | 58 info(_("Plugin XEP_0045 initialization")) |
59 self.host = host | 59 self.host = host |
60 self.clients={} | 60 self.clients={} |
61 host.bridge.addMethod("joinMUC", ".communication", in_sign='ssss', out_sign='', method=self.join) | 61 host.bridge.addMethod("joinMUC", ".communication", in_sign='ssss', out_sign='', method=self._join) |
62 host.bridge.addMethod("getRoomJoined", ".communication", in_sign='s', out_sign='a(ssass)', method=self.getRoomJoined) | 62 host.bridge.addMethod("getRoomJoined", ".communication", in_sign='s', out_sign='a(ssass)', method=self.getRoomJoined) |
63 host.bridge.addMethod("getRoomSubjects", ".communication", in_sign='s', out_sign='a(sss)', method=self.getRoomSubjects) | 63 host.bridge.addMethod("getRoomSubjects", ".communication", in_sign='s', out_sign='a(sss)', method=self.getRoomSubjects) |
64 host.bridge.addMethod("getUniqueRoomName", ".communication", in_sign='s', out_sign='s', method=self.getUniqueName) | |
64 host.bridge.addSignal("roomJoined", ".communication", signature='ssasss') #args: room_id, room_service, room_nicks, user_nick, profile | 65 host.bridge.addSignal("roomJoined", ".communication", signature='ssasss') #args: room_id, room_service, room_nicks, user_nick, profile |
65 host.bridge.addSignal("roomUserJoined", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile | 66 host.bridge.addSignal("roomUserJoined", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile |
66 host.bridge.addSignal("roomUserLeft", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile | 67 host.bridge.addSignal("roomUserLeft", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile |
67 host.bridge.addSignal("roomNewSubject", ".communication", signature='ssss') #args: room_id, room_service, subject, profile | 68 host.bridge.addSignal("roomNewSubject", ".communication", signature='ssss') #args: room_id, room_service, subject, profile |
68 | 69 |
78 return False | 79 return False |
79 return True | 80 return True |
80 | 81 |
81 def __room_joined(self, room, profile): | 82 def __room_joined(self, room, profile): |
82 """Called when the user is in the requested room""" | 83 """Called when the user is in the requested room""" |
84 def _sendBridgeSignal(ignore=None): | |
85 self.host.bridge.roomJoined(room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick, profile) | |
86 | |
83 room_jid = room.roomIdentifier+'@'+room.service | 87 room_jid = room.roomIdentifier+'@'+room.service |
84 self.clients[profile].joined_rooms[room_jid] = room | 88 self.clients[profile].joined_rooms[room_jid] = room |
85 self.host.bridge.roomJoined(room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick, profile) | 89 if room.status == '201': |
90 #FIXME: the current behaviour is to create an instant room | |
91 #and send the signal only when the room is unlocked | |
92 #a proper configuration management should be done | |
93 #TODO: wokkel's muc currently doesn't manage correctly message from the room | |
94 # service (without resource) in room.getUser | |
95 self.clients[profile].configure(room_jid).addCallbacks(_sendBridgeSignal, lambda x: error(_('Error while configuring the room'))) | |
96 else: | |
97 _sendBridgeSignal() | |
98 return room | |
99 | |
86 | 100 |
87 def __err_joining_room(self, failure, profile): | 101 def __err_joining_room(self, failure, profile): |
88 """Called when something is going wrong when joining the room""" | 102 """Called when something is going wrong when joining the room""" |
89 mess = _("Error when joining the room") | 103 mess = _("Error when joining the room") |
90 error (mess) | 104 error (mess) |
115 """Return received subjects of rooms""" | 129 """Return received subjects of rooms""" |
116 profile = self.host.memory.getProfileName(profile_key) | 130 profile = self.host.memory.getProfileName(profile_key) |
117 if not self.__check_profile(profile): | 131 if not self.__check_profile(profile): |
118 return [] | 132 return [] |
119 return self.clients[profile].rec_subjects.values() | 133 return self.clients[profile].rec_subjects.values() |
134 | |
135 def getUniqueName(self, profile_key='@DEFAULT@'): | |
136 """Return unique name for room, avoiding collision""" | |
137 #TODO: we should use #RFC-0045 10.1.4 when available here | |
138 #TODO: we should be able to select the MUC service here | |
139 return uuid.uuid1() | |
120 | 140 |
121 def join(self, service, roomId, nick, profile_key='@DEFAULT@'): | 141 def join(self, service, roomId, nick, profile_key='@DEFAULT@'): |
122 profile = self.host.memory.getProfileName(profile_key) | 142 profile = self.host.memory.getProfileName(profile_key) |
123 if not self.__check_profile(profile): | 143 if not self.__check_profile(profile): |
124 return | 144 return |
126 if self.clients[profile].joined_rooms.has_key(room_jid): | 146 if self.clients[profile].joined_rooms.has_key(room_jid): |
127 warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid}) | 147 warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid}) |
128 return | 148 return |
129 info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':roomId+'@'+service, 'nick':nick}) | 149 info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':roomId+'@'+service, 'nick':nick}) |
130 try: | 150 try: |
131 self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile}) | 151 return self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile}) |
132 except: | 152 except: |
133 #XXX: this is a ugly workaround as MUCClient thrown an error if there is invalid chars in the room jid (like with the default string) | 153 #XXX: this is a ugly workaround as MUCClient thrown an error if there is invalid chars in the room jid (like with the default string) |
134 #FIXME: must be removed when MUCClient manage this better | 154 #FIXME: must be removed when MUCClient manage this better |
135 self.__err_joining_room(None, profile) | 155 d = defer.Deferred() |
136 | 156 d.addErrback(self.__err_joining_room, profile) |
157 d.errback(Exception("ugly workaround")) | |
158 return d | |
159 | |
160 def _join(self, service, roomId, nick, profile_key='@DEFAULT@'): | |
161 """join method used by bridge: use the _join method, but doesn't return any deferred""" | |
162 self.join(service, roomId, nick, profile_key) | |
163 | |
137 def getHandler(self, profile): | 164 def getHandler(self, profile): |
138 self.clients[profile] = SatMUCClient(self) | 165 self.clients[profile] = SatMUCClient(self) |
139 return self.clients[profile] | 166 return self.clients[profile] |
140 | 167 |
141 | 168 |
154 def receivedGroupChat(self, room, user, body): | 181 def receivedGroupChat(self, room, user, body): |
155 debug('receivedGroupChat: room=%s user=%s body=%s', room, user, body) | 182 debug('receivedGroupChat: room=%s user=%s body=%s', room, user, body) |
156 | 183 |
157 def userJoinedRoom(self, room, user): | 184 def userJoinedRoom(self, room, user): |
158 debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) | 185 debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) |
186 if not self.host.trigger.point("MUC user joined", room, user, self.parent.profile): | |
187 return | |
159 user_data={'entity':user.entity or '', 'affiliation':user.affiliation, 'role':user.role} | 188 user_data={'entity':user.entity or '', 'affiliation':user.affiliation, 'role':user.role} |
160 self.host.bridge.roomUserJoined(room.roomIdentifier, room.service, user.nick, user_data, self.parent.profile) | 189 self.host.bridge.roomUserJoined(room.roomIdentifier, room.service, user.nick, user_data, self.parent.profile) |
161 | 190 |
162 def userLeftRoom(self, room, user): | 191 def userLeftRoom(self, room, user): |
163 debug (_("user %(nick)s left room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) | 192 debug (_("user %(nick)s left room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) |