Destroy session when remote signs off

This commit is contained in:
Thibaut GIRKA 2009-10-16 19:04:04 +02:00
parent ab6510db38
commit bc90bc1157
2 changed files with 39 additions and 19 deletions

View file

@ -1587,6 +1587,16 @@ class ChatControl(ChatControlBase):
if reason: if reason:
str += ', ' + _('reason: %s') % reason str += ', ' + _('reason: %s') % reason
self.print_conversation(str, 'info') self.print_conversation(str, 'info')
if state in ('connecting', 'connected', 'connection_received'):
self._audio_button.set_active(True)
elif state in ('not_available', 'stop'):
# Destroy existing session with the user when he signs off
if state == 'not_available':
gajim.connections[self.account].delete_jingle_session(
self.contact.get_full_jid(), self.audio_sid)
self._audio_button.set_active(False)
if state == 'not_available': if state == 'not_available':
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
self.audio_sid = None self.audio_sid = None
@ -1607,11 +1617,6 @@ class ChatControl(ChatControlBase):
elif state == 'error': elif state == 'error':
self.audio_state = self.JINGLE_STATE_ERROR self.audio_state = self.JINGLE_STATE_ERROR
if state in ('connecting', 'connected', 'connection_received'):
self._audio_button.set_active(True)
elif state in ('not_available', 'stop'):
#TODO: Destroy existing session(s) with this user?
self._audio_button.set_active(False)
self.update_audio() self.update_audio()
def set_video_state(self, state, sid=None, reason=None): def set_video_state(self, state, sid=None, reason=None):
@ -1621,6 +1626,16 @@ class ChatControl(ChatControlBase):
if reason: if reason:
str += ', ' + _('reason: %s') % reason str += ', ' + _('reason: %s') % reason
self.print_conversation(str, 'info') self.print_conversation(str, 'info')
if state in ('connecting', 'connected', 'connection_received'):
self._video_button.set_active(True)
elif state in ('not_available', 'stop'):
# Destroy existing session with the user when he signs off
if state == 'not_available':
gajim.connections[self.account].delete_jingle_session(
self.contact.get_full_jid(), self.video_sid)
self._video_button.set_active(False)
if state == 'not_available': if state == 'not_available':
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
self.video_sid = None self.video_sid = None
@ -1642,11 +1657,6 @@ class ChatControl(ChatControlBase):
elif state == 'error': elif state == 'error':
self.video_state = self.JINGLE_STATE_ERROR self.video_state = self.JINGLE_STATE_ERROR
if state in ('connecting', 'connected', 'connection_received'):
self._video_button.set_active(True)
elif state in ('not_available', 'stop'):
#TODO: Destroy existing session(s) with this user?
self._video_button.set_active(False)
self.update_video() self.update_video()
def on_avatar_eventbox_enter_notify_event(self, widget, event): def on_avatar_eventbox_enter_notify_event(self, widget, event):

View file

@ -39,13 +39,11 @@
# * DONE: figure out why it doesn't work with pidgin: # * DONE: figure out why it doesn't work with pidgin:
# That's a bug in pidgin: http://xmpp.org/extensions/xep-0176.html#protocol-checks # That's a bug in pidgin: http://xmpp.org/extensions/xep-0176.html#protocol-checks
# * destroy sessions when user is unavailable, see handle_event_notify?
# * timeout # * timeout
# * security (see XEP 0166)
# * split this file in several modules # * split this file in several modules
# For example, a file dedicated for XEP0166, one for XEP0176, # For example, a file dedicated for XEP0166, one for XEP0176,
# and one for each media of XEP0167 # and one for XEP0167
# * handle different kinds of sink and src elements # * handle different kinds of sink and src elements
@ -78,6 +76,9 @@ class TransportType(object):
class OutOfOrder(Exception): class OutOfOrder(Exception):
''' Exception that should be raised when an action is received when in the wrong state. ''' ''' Exception that should be raised when an action is received when in the wrong state. '''
class TieBreak(Exception):
''' Exception that should be raised in case of a tie, when we overrule the other action. '''
class JingleSession(object): class JingleSession(object):
''' This represents one jingle session. ''' ''' This represents one jingle session. '''
def __init__(self, con, weinitiate, jid, sid=None): def __init__(self, con, weinitiate, jid, sid=None):
@ -306,6 +307,8 @@ class JingleSession(object):
callable(stanza=stanza, jingle=jingle, error=error, action=action) callable(stanza=stanza, jingle=jingle, error=error, action=action)
except xmpp.NodeProcessed: except xmpp.NodeProcessed:
pass pass
except TieBreak:
self.__send_error(stanza, 'conflict', 'tiebreak')
except OutOfOrder: except OutOfOrder:
self.__send_error(stanza, 'unexpected-request', 'out-of-order')#FIXME self.__send_error(stanza, 'unexpected-request', 'out-of-order')#FIXME
@ -328,7 +331,7 @@ class JingleSession(object):
self.__dispatch_error(xmpp_error, jingle_error, text) self.__dispatch_error(xmpp_error, jingle_error, text)
#FIXME: Not sure when we would want to do that... #FIXME: Not sure when we would want to do that...
if xmpp_error == 'item-not-found': if xmpp_error == 'item-not-found':
self.connection.delete_jingle(self) self.connection.delete_jingle_session(self.peerjid, self.sid)
def __transportReplaceCB(self, stanza, jingle, error, action): def __transportReplaceCB(self, stanza, jingle, error, action):
for content in jingle.iterTags('content'): for content in jingle.iterTags('content'):
@ -415,7 +418,8 @@ class JingleSession(object):
''' We got a jingle session request from other entity, ''' We got a jingle session request from other entity,
therefore we are the receiver... Unpack the data, therefore we are the receiver... Unpack the data,
inform the user. ''' inform the user. '''
if self.state != JingleStates.ended: #FIXME
if self.state != JingleStates.ended:
raise OutOfOrder raise OutOfOrder
self.initiator = jingle['initiator'] self.initiator = jingle['initiator']
@ -463,7 +467,7 @@ class JingleSession(object):
cn.stanzaCB(stanza, content, error, action) cn.stanzaCB(stanza, content, error, action)
def __sessionTerminateCB(self, stanza, jingle, error, action): def __sessionTerminateCB(self, stanza, jingle, error, action):
self.connection.delete_jingle(self) self.connection.delete_jingle_session(self.peerjid, self.sid)
reason, text = self.__reason_from_stanza(jingle) reason, text = self.__reason_from_stanza(jingle)
if reason not in ('success', 'cancel', 'decline'): if reason not in ('success', 'cancel', 'decline'):
self.__dispatch_error(reason, reason, text) self.__dispatch_error(reason, reason, text)
@ -607,7 +611,7 @@ class JingleSession(object):
text = '%s (%s)' % (reason, text) text = '%s (%s)' % (reason, text)
else: else:
text = reason text = reason
self.connection.delete_jingle(self) self.connection.delete_jingle_session(self.peerjid, self.sid)
self.connection.dispatch('JINGLE_DISCONNECTED', self.connection.dispatch('JINGLE_DISCONNECTED',
(self.peerjid, self.sid, None, text)) (self.peerjid, self.sid, None, text))
@ -1078,9 +1082,15 @@ class ConnectionJingle(object):
''' '''
self.__sessions[(jingle.peerjid, jingle.sid)] = jingle self.__sessions[(jingle.peerjid, jingle.sid)] = jingle
def delete_jingle(self, jingle): def delete_jingle_session(self, peerjid, sid):
''' Remove a jingle session from a jingle stanza dispatcher ''' ''' Remove a jingle session from a jingle stanza dispatcher '''
del self.__sessions[(jingle.peerjid, jingle.sid)] key = (peerjid, sid)
if key in self.__sessions:
#FIXME: Move this elsewhere?
for content in self.__sessions[key].contents.values():
content.destroy()
self.__sessions[key].callbacks = []
del self.__sessions[key]
def _JingleCB(self, con, stanza): def _JingleCB(self, con, stanza):
''' The jingle stanza dispatcher. ''' The jingle stanza dispatcher.