# HG changeset patch # User Goffi # Date 1304689112 -7200 # Node ID 5bb1cfc105d000fd089e7edf90a25862c62f135b # Parent b544bec477dd936a5056ec47d2daa724b56677e5 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") diff -r b544bec477dd -r 5bb1cfc105d0 src/plugins/plugin_xep_0045.py --- a/src/plugins/plugin_xep_0045.py Fri May 06 15:34:02 2011 +0200 +++ b/src/plugins/plugin_xep_0045.py Fri May 06 15:38:32 2011 +0200 @@ -26,7 +26,7 @@ from twisted.words.protocols.jabber import error as jab_error from twisted.words.protocols.jabber.xmlstream import IQ import os.path -import pdb +import uuid from zope.interface import implements @@ -58,9 +58,10 @@ info(_("Plugin XEP_0045 initialization")) self.host = host self.clients={} - host.bridge.addMethod("joinMUC", ".communication", in_sign='ssss', out_sign='', method=self.join) + host.bridge.addMethod("joinMUC", ".communication", in_sign='ssss', out_sign='', method=self._join) host.bridge.addMethod("getRoomJoined", ".communication", in_sign='s', out_sign='a(ssass)', method=self.getRoomJoined) host.bridge.addMethod("getRoomSubjects", ".communication", in_sign='s', out_sign='a(sss)', method=self.getRoomSubjects) + host.bridge.addMethod("getUniqueRoomName", ".communication", in_sign='s', out_sign='s', method=self.getUniqueName) host.bridge.addSignal("roomJoined", ".communication", signature='ssasss') #args: room_id, room_service, room_nicks, user_nick, profile host.bridge.addSignal("roomUserJoined", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile host.bridge.addSignal("roomUserLeft", ".communication", signature='sssa{ss}s') #args: room_id, room_service, user_nick, user_data, profile @@ -80,9 +81,22 @@ def __room_joined(self, room, profile): """Called when the user is in the requested room""" + def _sendBridgeSignal(ignore=None): + self.host.bridge.roomJoined(room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick, profile) + room_jid = room.roomIdentifier+'@'+room.service self.clients[profile].joined_rooms[room_jid] = room - self.host.bridge.roomJoined(room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick, profile) + if room.status == '201': + #FIXME: the current behaviour is to create an instant room + #and send the signal only when the room is unlocked + #a proper configuration management should be done + #TODO: wokkel's muc currently doesn't manage correctly message from the room + # service (without resource) in room.getUser + self.clients[profile].configure(room_jid).addCallbacks(_sendBridgeSignal, lambda x: error(_('Error while configuring the room'))) + else: + _sendBridgeSignal() + return room + def __err_joining_room(self, failure, profile): """Called when something is going wrong when joining the room""" @@ -118,6 +132,12 @@ return [] return self.clients[profile].rec_subjects.values() + def getUniqueName(self, profile_key='@DEFAULT@'): + """Return unique name for room, avoiding collision""" + #TODO: we should use #RFC-0045 10.1.4 when available here + #TODO: we should be able to select the MUC service here + return uuid.uuid1() + def join(self, service, roomId, nick, profile_key='@DEFAULT@'): profile = self.host.memory.getProfileName(profile_key) if not self.__check_profile(profile): @@ -128,12 +148,19 @@ return info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':roomId+'@'+service, 'nick':nick}) try: - self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile}) + return self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile}) except: #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) #FIXME: must be removed when MUCClient manage this better - self.__err_joining_room(None, profile) + d = defer.Deferred() + d.addErrback(self.__err_joining_room, profile) + d.errback(Exception("ugly workaround")) + return d + def _join(self, service, roomId, nick, profile_key='@DEFAULT@'): + """join method used by bridge: use the _join method, but doesn't return any deferred""" + self.join(service, roomId, nick, profile_key) + def getHandler(self, profile): self.clients[profile] = SatMUCClient(self) return self.clients[profile] @@ -156,6 +183,8 @@ def userJoinedRoom(self, room, user): debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) + if not self.host.trigger.point("MUC user joined", room, user, self.parent.profile): + return user_data={'entity':user.entity or '', 'affiliation':user.affiliation, 'role':user.role} self.host.bridge.roomUserJoined(room.roomIdentifier, room.service, user.nick, user_data, self.parent.profile)