diff src/plugins/plugin_xep_0045.py @ 712:f610864eb7a5

plugins (MUC, tools, games): generalize the generation of a unique room name when joining a MUC and no room is specified: - method to get the MUC service moved to plugin_xep_0045 - joinMUC returns the muc name (given by user or generated) - getUniqueName can receive a specified service in argument
author souliane <souliane@mailoo.org>
date Sun, 17 Nov 2013 16:59:12 +0100
parents 84a6e83157c2
children 8bd63daecdbf
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0045.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/plugins/plugin_xep_0045.py	Sun Nov 17 16:59:12 2013 +0100
@@ -55,12 +55,12 @@
         info(_("Plugin XEP_0045 initialization"))
         self.host = host
         self.clients = {}
-        host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._join)
+        host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._join)
         host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self.mucNick)
         host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.mucLeave, async = True)
         host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined)
         host.bridge.addMethod("getRoomsSubjects", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjects)
-        host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='s', out_sign='s', method=self.getUniqueName)
+        host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='ss', out_sign='s', method=self.getUniqueName)
         host.bridge.addSignal("roomJoined", ".plugin", signature='sasss')  # args: room_jid, room_nicks, user_nick, profile
         host.bridge.addSignal("roomLeft", ".plugin", signature='ss')  # args: room_jid, profile
         host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s')  # args: room_jid, user_nick, user_data, profile
@@ -101,12 +101,11 @@
 
     def __err_joining_room(self, failure, room_jid, nick, history_options, password, profile):
         """Called when something is going wrong when joining the room"""
-        if failure.value.condition == 'conflict':
+        if hasattr(failure.value, "condition") and failure.value.condition == 'conflict':
             # we have a nickname conflict, we try again with "_" suffixed to current nickname
             nick += '_'
             return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
-
-        mess = _("Error when joining the room")
+        mess = _("Error when joining the room %s" % room_jid.userhost())
         error(mess)
         self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
         raise failure
@@ -147,11 +146,38 @@
             return []
         return self.clients[profile].rec_subjects.values()
 
-    def getUniqueName(self, profile_key='@DEFAULT@'):
-        """Return unique name for room, avoiding collision"""
+    def getMUCService(self, profile):
+        """Return the MUC service or None"""
+        muc_service = None
+        for service in self.host.memory.getServerServiceEntities("conference", "text", profile):
+            if not ".irc." in service.userhost():
+                #FIXME:
+                #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway
+                #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way
+                #to manage this, but this hack fill do it for test purpose
+                muc_service = service
+                break
+        return muc_service
+
+    def getUniqueName(self, muc_service="", profile_key='@DEFAULT@'):
+        """Return unique name for room, avoiding collision
+        @param muc_service: leave empty string to use the default service
+        @return: unique room userhost, or '' if an error occured.
+        """
         #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()
+        profile = self.host.memory.getProfileName(profile_key)
+        if not profile:
+            error(_("Unknown profile"))
+            return ""
+        room_name = uuid.uuid1()
+        print "\n\n===> room_name:", room_name
+        if muc_service == "":
+            muc_service = self.getMUCService(profile)
+            if not muc_service:
+                error(_("Can't find a MUC service"))
+                return ""
+            muc_service = muc_service.userhost()
+        return "%s@%s" % (room_name, muc_service)
 
     def join(self, room_jid, nick, options, profile_key='@DEFAULT@'):
         def _errDeferred(exc_obj=Exception, txt='Error while joining room'):
@@ -173,10 +199,14 @@
         return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
 
     def _join(self, room_jid_s, nick, options={}, profile_key='@DEFAULT@'):
-        """join method used by bridge: use the _join method, but doesn't return any deferred"""
+        """join method used by bridge: use the _join method, but doesn't return any deferred
+        @return the room userhost (given value or unique generated name)
+        """
         profile = self.host.memory.getProfileName(profile_key)
         if not self.__check_profile(profile):
             return
+        if room_jid_s == "":
+            room_jid_s = self.getUniqueName(profile_key=profile_key)
         try:
             room_jid = jid.JID(room_jid_s)
         except:
@@ -186,6 +216,7 @@
             return
         d = self.join(room_jid, nick, options, profile)
         d.addErrback(lambda x: warning(_('Error while joining room')))  # TODO: error management + signal in bridge
+        return room_jid_s
 
     def nick(self, room_jid, nick, profile_key):
         profile = self.host.memory.getProfileName(profile_key)