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
This commit is contained in:
parent
89cfefbacf
commit
42167b6ae9
3 changed files with 47 additions and 20 deletions
|
|
@ -526,8 +526,7 @@ class QuickApp(object):
|
|||
"""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()
|
||||
|
||||
|
|
|
|||
|
|
@ -218,10 +218,9 @@ class Occupant(object):
|
|||
|
||||
|
||||
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 @@ class QuickChat(quick_widgets.QuickWidget):
|
|||
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 @@ class QuickChat(quick_widgets.QuickWidget):
|
|||
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"""
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ CONFIG_SECTION = u'plugin muc'
|
|||
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 @@ class XEP_0045(object):
|
|||
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 @@ class XEP_0045(object):
|
|||
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 @@ class XEP_0045(object):
|
|||
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 @@ class XEP_0045(object):
|
|||
"""
|
||||
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 @@ class XEP_0045(object):
|
|||
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 @@ class XEP_0045(object):
|
|||
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 @@ class SatMUCClient(muc.MUCClient):
|
|||
|
||||
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 @@ class SatMUCClient(muc.MUCClient):
|
|||
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 @@ class SatMUCClient(muc.MUCClient):
|
|||
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 @@ class SatMUCClient(muc.MUCClient):
|
|||
# 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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue