Mercurial > libervia-backend
changeset 2066:09c18fcd8225
plugin XEP-0045, quick frontend (app,chat): various chat improvments:
- (XEP-0045): join defered is now fired when room is full joined and history is available
- (XEP-0045): mucJOIN signature has changed, it now returns the same arguments as mucRoomJoined and a boolean which is True if the room was alread joined
- quick frontend (app, chat): adapted code to new changes
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 09 Sep 2016 23:54:33 +0200 (2016-09-09) |
parents | f3167c873e7b |
children | 7834743705f0 |
files | frontends/src/quick_frontend/quick_app.py frontends/src/quick_frontend/quick_chat.py src/plugins/plugin_xep_0045.py |
diffstat | 3 files changed, 47 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/frontends/src/quick_frontend/quick_app.py Fri Sep 09 23:54:33 2016 +0200 +++ b/frontends/src/quick_frontend/quick_app.py Fri Sep 09 23:54:33 2016 +0200 @@ -526,8 +526,7 @@ """Called when a MUC room is joined""" log.debug(u"Room [{room_jid}] joined by {profile}, users presents:{users}".format(room_jid=room_jid_s, profile=profile, users=occupants.keys())) room_jid = jid.JID(room_jid_s) - chat_widget = self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, occupants=occupants, subject=subject, profile=profile) - chat_widget.setUserNick(unicode(user_nick)) + self.widgets.getOrCreateWidget(quick_chat.QuickChat, room_jid, type_=C.CHAT_GROUP, nick=user_nick, occupants=occupants, subject=subject, profile=profile) self.contact_lists[profile].setSpecial(room_jid, C.CONTACT_SPECIAL_GROUP) # chat_widget.update()
--- a/frontends/src/quick_frontend/quick_chat.py Fri Sep 09 23:54:33 2016 +0200 +++ b/frontends/src/quick_frontend/quick_chat.py Fri Sep 09 23:54:33 2016 +0200 @@ -218,10 +218,9 @@ class QuickChat(quick_widgets.QuickWidget): - visible_states = ['chat_state'] # FIXME: to be removed, used only in quick_games - def __init__(self, host, target, type_=C.CHAT_ONE2ONE, occupants=None, subject=None, profiles=None): + def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None, subject=None, profiles=None): """ @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC """ @@ -236,12 +235,15 @@ if type_ == C.CHAT_GROUP: if target.resource: raise exceptions.InternalError(u"a group chat entity can't have a resource") - self.nick = None + if nick is None: + raise exceptions.InternalError(u"nick must not be None for group chat") + + self.nick = nick self.occupants = {} self.setOccupants(occupants) else: - if occupants is not None: - raise exceptions.InternalError(u"only group chat can have occupants") + if occupants is not None or nick is not None: + raise exceptions.InternalError(u"only group chat can have occupants or nick") self.messages = OrderedDict() # key: uid, value: Message instance self.games = {} # key=game name (unicode), value=instance of quick_games.RoomGame self.subject = subject @@ -290,6 +292,10 @@ if self.type == C.CHAT_GROUP: kwargs['occupants'] = {o.nick: o.data for o in self.occupants.itervalues()} kwargs['subject'] = self.subject + try: + kwargs['nick'] = self.nick + except AttributeError: + pass def onPrivateCreated(self, widget): """Method called when a new widget for private conversation (MUC) is created"""
--- a/src/plugins/plugin_xep_0045.py Fri Sep 09 23:54:33 2016 +0200 +++ b/src/plugins/plugin_xep_0045.py Fri Sep 09 23:54:33 2016 +0200 @@ -64,6 +64,13 @@ default_conf = {"default_muc": u'sat@chat.jabberfr.org'} +class AlreadyJoined(exceptions.ConflictError): + + def __init__(self, room): + super(AlreadyJoined, self).__init__() + self.room = room + + class XEP_0045(object): # TODO: handle invitations @@ -71,7 +78,7 @@ log.info(_("Plugin XEP_0045 initialization")) self.host = host self._sessions = memory.Sessions() - host.bridge.addMethod("mucJoin", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._join, async=True) + host.bridge.addMethod("mucJoin", ".plugin", in_sign='ssa{ss}s', out_sign='(bsa{sa{ss}}sss)', method=self._join, async=True) # return same arguments as mucRoomJoined + a boolean set to True is the room was already joined (first argument) host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self._nick) host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self._leave, async=True) host.bridge.addMethod("mucSubject", ".plugin", in_sign='sss', out_sign='', method=self._subject) @@ -140,6 +147,15 @@ else: return True + def _getRoomJoinedArgs(self, room, profile): + return [ + room.roomJID.userhost(), + XEP_0045._getOccupants(room), + room.nick, + room.subject, + profile + ] + def _UIRoomJoinCb(self, data, profile): room_jid = jid.JID(data['index']) client = self.host.getClient(profile) @@ -173,7 +189,7 @@ log.debug(_(u"room locked !")) d = client._muc_client.configure(room.roomJID, {}) d.addErrback(lambda dummy: log.error(_(u'Error while configuring the room'))) - return room + return room.fully_joined def _joinEb(self, failure, client, room_jid, nick, password): """Called when something is going wrong when joining the room""" @@ -389,6 +405,11 @@ """ return self.host.memory.getConfig(CONFIG_SECTION, 'default_muc', default_conf['default_muc']) + def _join_eb(self, failure_, client): + failure_.trap(AlreadyJoined) + room = failure_.value.room + return [True] + self._getRoomJoinedArgs(room, client.profile) + def _join(self, room_jid_s, nick, options, profile_key=C.PROF_KEY_NONE): """join method used by bridge @@ -407,7 +428,9 @@ room_jid = self.getUniqueName(profile_key=client.profile) # TODO: error management + signal in bridge d = self.join(client, room_jid, nick, options or None) - return d.addCallback(lambda room: room.roomJID.userhost()) + d.addCallback(lambda room: [False] + self._getRoomJoinedArgs(room, client.profile)) + d.addErrback(self._join_eb, client) + return d def join(self, client, room_jid, nick=None, options=None): if not nick: @@ -420,8 +443,9 @@ return d if room_jid in client._muc_client.joined_rooms: + room = client._muc_client.joined_rooms[room_jid] log.warning(_(u'{profile} is already in room {room_jid}').format(profile=client.profile, room_jid = room_jid.userhost())) - raise failure.Failure(exceptions.ConflictError(_(u"The room has already been joined"))) + return defer.fail(AlreadyJoined(room)) log.info(_(u"[{profile}] is joining room {room} with nick {nick}").format(profile=client.profile, room=room_jid.userhost(), nick=nick)) password = options["password"] if "password" in options else None @@ -745,11 +769,13 @@ def _addRoom(self, room): super(SatMUCClient, self)._addRoom(room) - room._roster_ok = False + room._roster_ok = False # True when occupants list has been fully received room._room_ok = None # False when roster, history and subject are available # True when new messages are saved to database - room._history_d = defer.Deferred() # use to send bridge signal once backlog are written in history + room._history_d = defer.Deferred() # used to send bridge signal once backlog are written in history room._history_d.callback(None) + # FIXME: check if history_d is not redundant with fully_joined + room.fully_joined = defer.Deferred() # called when everything is OK room._cache = [] def _gotLastDbHistory(self, mess_data_list, room_jid, nick, password): @@ -978,12 +1004,8 @@ return muc.MUCClientProtocol.subject(self, room, subject) def _historyCb(self, dummy, room): - self.host.bridge.mucRoomJoined( - room.roomJID.userhost(), - XEP_0045._getOccupants(room), - room.nick, - room.subject, - self.parent.profile) + args = self.plugin_parent._getRoomJoinedArgs(room, self.parent.profile) + self.host.bridge.mucRoomJoined(*args) del room._history_d cache = room._cache del room._cache @@ -991,7 +1013,6 @@ for elem in cache: self.parent.xmlstream.dispatch(elem) - def _historyEb(self, failure_, room): log.error(u"Error while managing history: {}".format(failure_)) self._historyCb(None, room) @@ -1006,6 +1027,7 @@ # that mean that we have received everything we need room._room_ok = False room._history_d.addCallbacks(self._historyCb, self._historyEb, [room], errbackArgs=[room]) + room.fully_joined.callback(room) else: # the subject has been changed log.debug(_(u"New subject for room ({room_id}): {subject}").format(room_id = room.roomJID.full(), subject = subject))