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
This commit is contained in:
souliane 2013-11-17 16:59:12 +01:00
commit 8190f82caf
6 changed files with 67 additions and 32 deletions

View file

@ -61,7 +61,7 @@ class Quiz(RoomGame):
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)

View file

@ -61,7 +61,7 @@ class Radiocol(RoomGame):
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

View file

@ -60,7 +60,7 @@ class Tarot(RoomGame):
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

View file

@ -55,12 +55,12 @@ class XEP_0045(object):
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 @@ class XEP_0045(object):
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 @@ class XEP_0045(object):
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 @@ class XEP_0045(object):
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 @@ class XEP_0045(object):
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)

View file

@ -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=""):

View file

@ -44,9 +44,14 @@ class RoomGame(object):
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 @@ class RoomGame(object):
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,