better session handling:
- when a new contact with higher prio connect, detach session from chat control. Fixes #5021 - don't re-use a session that was for another sessin Tests are more than welcome!
This commit is contained in:
parent
07277df1e2
commit
0d37f4f64b
|
@ -1287,14 +1287,12 @@ class ChatControl(ChatControlBase):
|
||||||
self.handlers[id_] = widget
|
self.handlers[id_] = widget
|
||||||
|
|
||||||
if not session:
|
if not session:
|
||||||
session = gajim.connections[self.account]. \
|
# Don't use previous session if we want to a specific resource
|
||||||
find_controlless_session(self.contact.jid)
|
# and it's not the same
|
||||||
if session:
|
if not resource:
|
||||||
# Don't use previous session if we want to a specific resource
|
resource = contact.resource
|
||||||
# and it's not the same
|
session = gajim.connections[self.account].find_controlless_session(
|
||||||
r = gajim.get_room_and_nick_from_fjid(str(session.jid))[1]
|
self.contact.jid, resource)
|
||||||
if resource and resource != r:
|
|
||||||
session = None
|
|
||||||
|
|
||||||
if session:
|
if session:
|
||||||
session.control = self
|
session.control = self
|
||||||
|
|
|
@ -1408,12 +1408,11 @@ sent a message to.'''
|
||||||
|
|
||||||
if chat_sessions:
|
if chat_sessions:
|
||||||
# return the session that we last sent a message in
|
# return the session that we last sent a message in
|
||||||
return sorted(chat_sessions,
|
return sorted(chat_sessions, key=operator.attrgetter("last_send"))[-1]
|
||||||
key=operator.attrgetter("last_send"))[-1]
|
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_controlless_session(self, jid):
|
def find_controlless_session(self, jid, resource=None):
|
||||||
'''find an active session that doesn't have a control attached'''
|
'''find an active session that doesn't have a control attached'''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1425,6 +1424,9 @@ sent a message to.'''
|
||||||
|
|
||||||
orphaned = [s for s in chat_sessions if not s.control]
|
orphaned = [s for s in chat_sessions if not s.control]
|
||||||
|
|
||||||
|
if resource:
|
||||||
|
orphaned = [s for s in orphaned if s.resource == resource]
|
||||||
|
|
||||||
return orphaned[0]
|
return orphaned[0]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
return None
|
return None
|
||||||
|
@ -2184,7 +2186,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
ptype = prs.getType()
|
ptype = prs.getType()
|
||||||
if ptype == 'available':
|
if ptype == 'available':
|
||||||
ptype = None
|
ptype = None
|
||||||
rfc_types = ('unavailable', 'error', 'subscribe', 'subscribed', 'unsubscribe', 'unsubscribed')
|
rfc_types = ('unavailable', 'error', 'subscribe', 'subscribed',
|
||||||
|
'unsubscribe', 'unsubscribed')
|
||||||
if ptype and not ptype in rfc_types:
|
if ptype and not ptype in rfc_types:
|
||||||
ptype = None
|
ptype = None
|
||||||
log.debug('PresenceCB: %s' % ptype)
|
log.debug('PresenceCB: %s' % ptype)
|
||||||
|
@ -2432,19 +2435,22 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.dispatch('NOTIFY', (jid_stripped, 'error', errmsg, resource,
|
self.dispatch('NOTIFY', (jid_stripped, 'error', errmsg, resource,
|
||||||
prio, keyID, timestamp, None))
|
prio, keyID, timestamp, None))
|
||||||
|
|
||||||
if ptype == 'unavailable' and jid_stripped in self.sessions:
|
if ptype == 'unavailable':
|
||||||
# automatically terminate sessions that they haven't sent a thread ID
|
for jid in [jid_stripped, who]:
|
||||||
# in, only if other part support thread ID
|
if jid not in self.sessions:
|
||||||
for sess in self.sessions[jid_stripped].values():
|
continue
|
||||||
if not sess.received_thread_id:
|
# automatically terminate sessions that they haven't sent a thread
|
||||||
contact = gajim.contacts.get_contact(self.name, jid_stripped)
|
# ID in, only if other part support thread ID
|
||||||
|
for sess in self.sessions[jid].values():
|
||||||
|
if not sess.received_thread_id:
|
||||||
|
contact = gajim.contacts.get_contact(self.name, jid)
|
||||||
|
|
||||||
session_supported = gajim.capscache.is_supported(contact,
|
session_supported = gajim.capscache.is_supported(contact,
|
||||||
common.xmpp.NS_SSN) or gajim.capscache.is_supported(contact,
|
common.xmpp.NS_SSN) or gajim.capscache.is_supported(
|
||||||
common.xmpp.NS_ESESSION)
|
contact, common.xmpp.NS_ESESSION)
|
||||||
if session_supported:
|
if session_supported:
|
||||||
sess.terminate()
|
sess.terminate()
|
||||||
del self.sessions[jid_stripped][sess.thread_id]
|
del self.sessions[jid][sess.thread_id]
|
||||||
|
|
||||||
if avatar_sha is not None and ptype != 'error':
|
if avatar_sha is not None and ptype != 'error':
|
||||||
if jid_stripped not in self.vcard_shas:
|
if jid_stripped not in self.vcard_shas:
|
||||||
|
|
|
@ -79,7 +79,7 @@ class StanzaSession(object):
|
||||||
|
|
||||||
def get_to(self):
|
def get_to(self):
|
||||||
to = str(self.jid)
|
to = str(self.jid)
|
||||||
if self.resource:
|
if self.resource and not to.endswith(self.resource):
|
||||||
to += '/' + self.resource
|
to += '/' + self.resource
|
||||||
return to
|
return to
|
||||||
|
|
||||||
|
|
|
@ -746,9 +746,9 @@ class Interface:
|
||||||
lcontact.append(contact1)
|
lcontact.append(contact1)
|
||||||
elif contact1.show in statuss:
|
elif contact1.show in statuss:
|
||||||
old_show = statuss.index(contact1.show)
|
old_show = statuss.index(contact1.show)
|
||||||
# FIXME: What am I?
|
|
||||||
if (resources != [''] and (len(lcontact) != 1 or \
|
if (resources != [''] and (len(lcontact) != 1 or \
|
||||||
lcontact[0].show != 'offline')) and jid.find('@') > 0:
|
lcontact[0].show != 'offline')) and jid.find('@') > 0:
|
||||||
|
# Another resource of an existing contact connected
|
||||||
old_show = 0
|
old_show = 0
|
||||||
contact1 = gajim.contacts.copy_contact(contact1)
|
contact1 = gajim.contacts.copy_contact(contact1)
|
||||||
lcontact.append(contact1)
|
lcontact.append(contact1)
|
||||||
|
@ -883,6 +883,7 @@ class Interface:
|
||||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||||
|
|
||||||
if ctrl:
|
if ctrl:
|
||||||
|
ctrl.no_autonegotiation = False
|
||||||
ctrl.set_session(None)
|
ctrl.set_session(None)
|
||||||
ctrl.contact = highest
|
ctrl.contact = highest
|
||||||
|
|
||||||
|
@ -2945,7 +2946,6 @@ class Interface:
|
||||||
|
|
||||||
def on_open_chat_window(self, widget, contact, account, resource=None,
|
def on_open_chat_window(self, widget, contact, account, resource=None,
|
||||||
session=None):
|
session=None):
|
||||||
|
|
||||||
# Get the window containing the chat
|
# Get the window containing the chat
|
||||||
fjid = contact.jid
|
fjid = contact.jid
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,12 @@ class MessageControl:
|
||||||
conn = gajim.connections[self.account]
|
conn = gajim.connections[self.account]
|
||||||
|
|
||||||
if not self.session:
|
if not self.session:
|
||||||
sess = conn.find_controlless_session(jid)
|
if not resource:
|
||||||
|
if self.resource:
|
||||||
|
resource = self.resource
|
||||||
|
else:
|
||||||
|
resource = self.contact.resource
|
||||||
|
sess = conn.find_controlless_session(jid, resource=resource)
|
||||||
|
|
||||||
if self.resource:
|
if self.resource:
|
||||||
jid += '/' + self.resource
|
jid += '/' + self.resource
|
||||||
|
|
|
@ -86,8 +86,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
'''dispatch a received <message> stanza'''
|
'''dispatch a received <message> stanza'''
|
||||||
msg_type = msg.getType()
|
msg_type = msg.getType()
|
||||||
subject = msg.getSubject()
|
subject = msg.getSubject()
|
||||||
if self.jid != full_jid_with_resource:
|
resource = gajim.get_nick_from_fjid(full_jid_with_resource)
|
||||||
self.resource = gajim.get_nick_from_fjid(full_jid_with_resource)
|
if self.resource != resource:
|
||||||
|
self.resource = resource
|
||||||
if self.control and self.control.resource:
|
if self.control and self.control.resource:
|
||||||
self.control.change_resource(self.resource)
|
self.control.change_resource(self.resource)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue