changeset 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 c9792d0be499
children 8bd63daecdbf
files src/plugins/plugin_misc_quiz.py src/plugins/plugin_misc_radiocol.py src/plugins/plugin_misc_tarot.py src/plugins/plugin_xep_0045.py src/tools/frontends/misc.py src/tools/plugins/games.py
diffstat 6 files changed, 67 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_misc_quiz.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/plugins/plugin_misc_quiz.py	Sun Nov 17 16:59:12 2013 +0100
@@ -61,7 +61,7 @@
         info(_("Plugin Quiz initialization"))
         RoomGame.__init__(self, host, PLUGIN_INFO, (NS_QG, QG_TAG), player_init_data={'score': 0},
                           options={'stage': None})
-        host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.prepareRoom)  # args: players, profile
+        host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom)  # args: players, room_jid, profile
         host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame)  # args: room_jid, players, profile
         host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady)  # args: player, referee, profile
         host.bridge.addMethod("quizGameAnswer", ".plugin", in_sign='ssss', out_sign='', method=self.playerAnswer)
--- a/src/plugins/plugin_misc_radiocol.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/plugins/plugin_misc_radiocol.py	Sun Nov 17 16:59:12 2013 +0100
@@ -61,7 +61,7 @@
         RoomGame.__init__(self, host, PLUGIN_INFO, (NC_RADIOCOL, RADIOC_TAG),
                           options={'queue': [], 'upload': True, 'playing': False, 'to_delete': {}})
         self.host = host
-        host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='ass', out_sign='', method=self.prepareRoom)
+        host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom)
         host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='ss', out_sign='', method=self.createCollectiveGame)
         host.bridge.addMethod("radiocolSongAdded", ".plugin", in_sign='sss', out_sign='', method=self.radiocolSongAdded)
         host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss')  # room_jid, referee, profile
--- a/src/plugins/plugin_misc_tarot.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/plugins/plugin_misc_tarot.py	Sun Nov 17 16:59:12 2013 +0100
@@ -60,7 +60,7 @@
         RoomGame.__init__(self, host, PLUGIN_INFO, (NS_CG, CG_TAG), player_init_data={'score': 0},
                           options={'hand_size': 18, 'init_player': 0, 'current_player': None, 'contrat': None, 'stage': None})
         self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')]
-        host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.prepareRoom)  # args: room_jid, players, profile
+        host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom)  # args: players, room_jid, profile
         host.bridge.addMethod("tarotGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame)  # args: room_jid, players, profile
         host.bridge.addMethod("tarotGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady)  # args: player, referee, profile
         host.bridge.addMethod("tarotGameContratChoosed", ".plugin", in_sign='ssss', out_sign='', method=self.contratChoosed)  # args: player, referee, contrat, profile
--- 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)
--- a/src/tools/frontends/misc.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/tools/frontends/misc.py	Sun Nov 17 16:59:12 2013 +0100
@@ -18,6 +18,10 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
+# Default value for the "New discussion room" user input
+DEFAULT_MUC = 'sat@chat.jabberfr.org'
+
+
 class InputHistory(object):
 
     def _updateInputHistory(self, text=None, step=None, callback=None, mode=""):
--- a/src/tools/plugins/games.py	Sun Nov 17 16:30:46 2013 +0100
+++ b/src/tools/plugins/games.py	Sun Nov 17 16:59:12 2013 +0100
@@ -44,9 +44,14 @@
         self.games = {}
         self.waiting_inv = {}  # Invitation waiting for people to join to launch a game
 
-    def prepareRoom(self, other_players, profile_key='@NONE@'):
+    def getUniqueName(self, muc_service="", profile_key='@DEFAULT@'):
+        room = self.host.plugins["XEP-0045"].getUniqueName(muc_service, profile_key=profile_key)
+        return "sat_%s_%s" % (self.name.lower(), room) if room != "" else ""
+
+    def prepareRoom(self, other_players, room_jid=None, profile_key='@NONE@'):
         """Prepare the room for a game: create it and invite players.
         @param other_players: list for other players JID userhosts
+        @param room_jid: JID of the room to reuse or None to create a new room
         """
         debug(_('Preparing room for %s game') % self.name)
         profile = self.host.memory.getProfileName(profile_key)
@@ -69,30 +74,25 @@
             for player in other_players:
                 self.host.plugins["XEP-0249"].invite(JID(player), room.occupantJID.userhostJID(), {"game": self.name}, profile)
 
-        def after_init(ignore):
-            room_name = "sat_%s_%s" % (self.name.lower(), self.host.plugins["XEP-0045"].getUniqueName(profile_key))
-            print "\n\n===> room_name:", room_name
-            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
-            if not muc_service:
-                error(_("Can't find a MUC service"))
-                return
-
-            d = self.host.plugins["XEP-0045"].join(JID("%s@%s" % (room_name, muc_service.userhost())), _jid.user, {}, profile)
+        def after_init(room_jid):
+            if room_jid is not None and room_jid != "":
+                # a room name has been specified...
+                if room_jid in self.host.plugins["XEP-0045"].clients[profile].joined_rooms:
+                    # and we're already in
+                    roomJoined(self.host.plugins["XEP-0045"].clients[profile].joined_rooms[room_jid])
+                    return
+            else:
+                room_jid = self.getUniqueName(profile_key=profile_key)
+                if room_jid == "":
+                    return
+            d = self.host.plugins["XEP-0045"].join(JID(room_jid), _jid.user, {}, profile)
             d.addCallback(roomJoined)
 
         client = self.host.getClient(profile)
         if not client:
             error(_('No client for this profile key: %s') % profile_key)
             return
-        client.client_initialized.addCallback(after_init)
+        client.client_initialized.addCallback(lambda ignore: after_init(room_jid))
 
     def userJoinedTrigger(self, room, user, profile):
         """This trigger is used to check if we are waiting for people in this room,