parent
f68ffc3816
commit
f7874d29c7
|
@ -1206,6 +1206,9 @@ class ChatControl(ChatControlBase):
|
||||||
ChatControlBase.update_ui(self)
|
ChatControlBase.update_ui(self)
|
||||||
|
|
||||||
def get_otr_status(self):
|
def get_otr_status(self):
|
||||||
|
if not self.session:
|
||||||
|
return 0
|
||||||
|
|
||||||
ctx = gajim.otr_module.otrl_context_find(
|
ctx = gajim.otr_module.otrl_context_find(
|
||||||
self.session.conn.otr_userstates,
|
self.session.conn.otr_userstates,
|
||||||
self.contact.get_full_jid().encode(),
|
self.contact.get_full_jid().encode(),
|
||||||
|
@ -1613,7 +1616,7 @@ class ChatControl(ChatControlBase):
|
||||||
|
|
||||||
def print_esession_details(self):
|
def print_esession_details(self):
|
||||||
'''print esession settings to textview'''
|
'''print esession settings to textview'''
|
||||||
e2e_is_active = self.session and self.session.enable_encryption
|
e2e_is_active = bool(self.session) and self.session.enable_encryption
|
||||||
if e2e_is_active:
|
if e2e_is_active:
|
||||||
msg = _('E2E encryption enabled')
|
msg = _('E2E encryption enabled')
|
||||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||||
|
@ -2022,6 +2025,7 @@ class ChatControl(ChatControlBase):
|
||||||
self.contact.our_chatstate = None
|
self.contact.our_chatstate = None
|
||||||
|
|
||||||
# disconnect self from session
|
# disconnect self from session
|
||||||
|
if self.session:
|
||||||
self.session.control = None
|
self.session.control = None
|
||||||
|
|
||||||
# Disconnect timer callbacks
|
# Disconnect timer callbacks
|
||||||
|
|
|
@ -980,6 +980,8 @@ class Connection(ConnectionHandlers):
|
||||||
elif show == 'offline':
|
elif show == 'offline':
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
if self.connection:
|
if self.connection:
|
||||||
|
self.terminate_sessions()
|
||||||
|
|
||||||
self.on_purpose = True
|
self.on_purpose = True
|
||||||
p = common.xmpp.Presence(typ = 'unavailable')
|
p = common.xmpp.Presence(typ = 'unavailable')
|
||||||
p = self.add_sha(p, False)
|
p = self.add_sha(p, False)
|
||||||
|
|
|
@ -1282,13 +1282,13 @@ class ConnectionHandlersBase:
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
||||||
def delete_session(self, jid, thread_id):
|
def delete_session(self, jid, thread_id):
|
||||||
try:
|
if not jid in self.sessions:
|
||||||
|
jid = gajim.get_jid_without_resource(jid)
|
||||||
|
|
||||||
del self.sessions[jid][thread_id]
|
del self.sessions[jid][thread_id]
|
||||||
|
|
||||||
if not self.sessions[jid]:
|
if not self.sessions[jid]:
|
||||||
del self.sessions[jid]
|
del self.sessions[jid]
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def find_null_session(self, jid):
|
def find_null_session(self, jid):
|
||||||
'''finds all of the sessions between us and a remote jid in which we
|
'''finds all of the sessions between us and a remote jid in which we
|
||||||
|
@ -1644,17 +1644,17 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
mtype = 'normal'
|
mtype = 'normal'
|
||||||
|
|
||||||
msgtxt = msg.getBody()
|
msgtxt = msg.getBody()
|
||||||
subject = msg.getSubject() # if not there, it's None
|
|
||||||
|
|
||||||
jid = helpers.get_jid_from_iq(msg)
|
jid = helpers.get_jid_from_iq(msg)
|
||||||
|
|
||||||
encrypted = False
|
encrypted = False
|
||||||
|
xep_200_encrypted = msg.getTag('c', namespace=common.xmpp.NS_STANZA_CRYPTO)
|
||||||
|
|
||||||
# I don't trust libotr, that's why I only pass the
|
# I don't trust libotr, that's why I only pass the
|
||||||
# message to it if it either contains the magic
|
# message to it if it either contains the magic
|
||||||
# ?OTR string or a plaintext tagged message.
|
# ?OTR string or a plaintext tagged message.
|
||||||
if gajim.otr_module and \
|
if gajim.otr_module and not xep_200_encrypted \
|
||||||
isinstance(msgtxt, unicode) and \
|
and isinstance(msgtxt, unicode) and \
|
||||||
('\x20\x09\x20\x20\x09\x09\x09\x09\x20\x09\x20\x09\x20\x09\x20\x20' \
|
('\x20\x09\x20\x20\x09\x09\x09\x09\x20\x09\x20\x09\x20\x09\x20\x20' \
|
||||||
in msgtxt or '?OTR' in msgtxt):
|
in msgtxt or '?OTR' in msgtxt):
|
||||||
# If it doesn't include ?OTR, it wasn't an
|
# If it doesn't include ?OTR, it wasn't an
|
||||||
|
@ -1764,11 +1764,12 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
tim = helpers.datetime_tuple(tim)
|
tim = helpers.datetime_tuple(tim)
|
||||||
tim = localtime(timegm(tim))
|
tim = localtime(timegm(tim))
|
||||||
|
|
||||||
if msg.getTag('c', namespace=common.xmpp.NS_STANZA_CRYPTO):
|
if xep_200_encrypted:
|
||||||
encrypted = True
|
encrypted = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
msg = session.decrypt_stanza(msg)
|
msg = session.decrypt_stanza(msg)
|
||||||
|
msgtxt = msg.getBody()
|
||||||
except:
|
except:
|
||||||
self.dispatch('FAILED_DECRYPT', (frm, tim, session))
|
self.dispatch('FAILED_DECRYPT', (frm, tim, session))
|
||||||
|
|
||||||
|
@ -1791,26 +1792,28 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
msgtxt = decmsg.replace('\x00', '')
|
msgtxt = decmsg.replace('\x00', '')
|
||||||
encrypted = True
|
encrypted = True
|
||||||
if mtype == 'error':
|
if mtype == 'error':
|
||||||
self.dispatch_error_message(msg, msgtxt, session, frm, tim, subject)
|
self.dispatch_error_message(msg, msgtxt, session, frm, tim)
|
||||||
elif mtype == 'groupchat':
|
elif mtype == 'groupchat':
|
||||||
self.dispatch_gc_message(msg, subject, frm, msgtxt, jid, tim)
|
self.dispatch_gc_message(msg, frm, msgtxt, jid, tim)
|
||||||
elif invite is not None:
|
elif invite is not None:
|
||||||
self.dispatch_invite_message(invite, frm)
|
self.dispatch_invite_message(invite, frm)
|
||||||
else:
|
else:
|
||||||
if isinstance(session, ChatControlSession):
|
if isinstance(session, ChatControlSession):
|
||||||
session.received(frm, msgtxt, tim, encrypted, subject, msg)
|
session.received(frm, msgtxt, tim, encrypted, msg)
|
||||||
else:
|
else:
|
||||||
session.received(msg)
|
session.received(msg)
|
||||||
# END messageCB
|
# END messageCB
|
||||||
|
|
||||||
# process and dispatch an error message
|
# process and dispatch an error message
|
||||||
def dispatch_error_message(self, msg, msgtxt, session, frm, tim, subject):
|
def dispatch_error_message(self, msg, msgtxt, session, frm, tim):
|
||||||
error_msg = msg.getErrorMsg()
|
error_msg = msg.getErrorMsg()
|
||||||
|
|
||||||
if not error_msg:
|
if not error_msg:
|
||||||
error_msg = msgtxt
|
error_msg = msgtxt
|
||||||
msgtxt = None
|
msgtxt = None
|
||||||
|
|
||||||
|
subject = msg.getSubject()
|
||||||
|
|
||||||
if session.is_loggable():
|
if session.is_loggable():
|
||||||
try:
|
try:
|
||||||
gajim.logger.write('error', frm, error_msg, tim=tim,
|
gajim.logger.write('error', frm, error_msg, tim=tim,
|
||||||
|
@ -1821,9 +1824,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
tim, session))
|
tim, session))
|
||||||
|
|
||||||
# process and dispatch a groupchat message
|
# process and dispatch a groupchat message
|
||||||
def dispatch_gc_message(self, msg, subject, frm, msgtxt, jid, tim):
|
def dispatch_gc_message(self, msg, frm, msgtxt, jid, tim):
|
||||||
has_timestamp = bool(msg.timestamp)
|
has_timestamp = bool(msg.timestamp)
|
||||||
|
|
||||||
|
subject = msg.getSubject()
|
||||||
|
|
||||||
if subject is not None:
|
if subject is not None:
|
||||||
self.dispatch('GC_SUBJECT', (frm, subject, msgtxt, has_timestamp))
|
self.dispatch('GC_SUBJECT', (frm, subject, msgtxt, has_timestamp))
|
||||||
return
|
return
|
||||||
|
|
|
@ -243,6 +243,9 @@ class EncryptedStanzaSession(StanzaSession):
|
||||||
|
|
||||||
return stanza
|
return stanza
|
||||||
|
|
||||||
|
def is_xep_200_encrypted(self, msg):
|
||||||
|
msg.getTag('c', namespace=common.xmpp.NS_STANZA_CRYPTO)
|
||||||
|
|
||||||
def hmac(self, key, content):
|
def hmac(self, key, content):
|
||||||
return HMAC.new(key, content, self.hash_alg).digest()
|
return HMAC.new(key, content, self.hash_alg).digest()
|
||||||
|
|
||||||
|
|
22
src/gajim.py
22
src/gajim.py
|
@ -2038,30 +2038,12 @@ class Interface:
|
||||||
|
|
||||||
if form.getField('terminate') and\
|
if form.getField('terminate') and\
|
||||||
form.getField('terminate').getValue() in ('1', 'true'):
|
form.getField('terminate').getValue() in ('1', 'true'):
|
||||||
was_encrypted = session.enable_encryption
|
|
||||||
ctrl = session.control
|
|
||||||
jid = str(jid)
|
jid = str(jid)
|
||||||
|
|
||||||
session.acknowledge_termination()
|
session.acknowledge_termination()
|
||||||
gajim.connections[account].delete_session(jid, session.thread_id)
|
|
||||||
|
|
||||||
if ctrl:
|
conn = gajim.connections[account]
|
||||||
# replace the old session in this control with a new one
|
conn.delete_session(jid, session.thread_id)
|
||||||
new_sess = gajim.connections[account].make_new_session(jid)
|
|
||||||
win = ctrl.parent_win
|
|
||||||
|
|
||||||
ctrl.set_session(new_sess)
|
|
||||||
gajim.connections[account].delete_session(jid,
|
|
||||||
session.thread_id)
|
|
||||||
|
|
||||||
if not jid in win._controls[account]:
|
|
||||||
jid = gajim.get_jid_without_resource(jid)
|
|
||||||
|
|
||||||
del win._controls[account][jid][session.thread_id]
|
|
||||||
win._controls[account][jid][new_sess.thread_id] = ctrl
|
|
||||||
|
|
||||||
if was_encrypted:
|
|
||||||
ctrl.print_esession_details()
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -128,13 +128,15 @@ class MessageControl:
|
||||||
|
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
|
new_key = None
|
||||||
if session:
|
if session:
|
||||||
session.control = self
|
session.control = self
|
||||||
|
new_key = session.thread_id
|
||||||
|
|
||||||
if oldsession:
|
if oldsession:
|
||||||
self.parent_win.change_thread_key(
|
self.parent_win.change_thread_key(
|
||||||
self.contact.jid, self.account,
|
self.contact.jid, self.account,
|
||||||
oldsession.thread_id, session.thread_id)
|
oldsession.thread_id, new_key)
|
||||||
|
|
||||||
if oldsession.enable_encryption:
|
if oldsession.enable_encryption:
|
||||||
self.print_esession_details()
|
self.print_esession_details()
|
||||||
|
@ -147,7 +149,14 @@ class MessageControl:
|
||||||
jid = self.contact.jid
|
jid = self.contact.jid
|
||||||
original_message = message
|
original_message = message
|
||||||
|
|
||||||
if gajim.otr_module and jid not in gajim.otr_dont_append_tag:
|
if not self.session:
|
||||||
|
sess = gajim.connections[self.account].make_new_session(jid)
|
||||||
|
self.set_session(sess)
|
||||||
|
self.parent_win.move_from_sessionless(self)
|
||||||
|
|
||||||
|
xep_200 = bool(self.session) and self.session.enable_encryption
|
||||||
|
|
||||||
|
if gajim.otr_module and not xep_200 and (jid not in gajim.otr_dont_append_tag):
|
||||||
if type == 'chat' and isinstance(message, unicode):
|
if type == 'chat' and isinstance(message, unicode):
|
||||||
d = {'kwargs': {'keyID': keyID, 'type': type,
|
d = {'kwargs': {'keyID': keyID, 'type': type,
|
||||||
'chatstate': chatstate,
|
'chatstate': chatstate,
|
||||||
|
|
|
@ -54,8 +54,15 @@ class MessageWindow(object):
|
||||||
) = range(5)
|
) = range(5)
|
||||||
|
|
||||||
def __init__(self, acct, type, parent_window=None, parent_paned=None):
|
def __init__(self, acct, type, parent_window=None, parent_paned=None):
|
||||||
# A dictionary of dictionaries where _contacts[account][jid] == A MessageControl
|
# A dictionary of dictionaries of dictionaries
|
||||||
|
# where _contacts[account][jid][thread_id] == A MessageControl
|
||||||
self._controls = {}
|
self._controls = {}
|
||||||
|
|
||||||
|
# a dictionary of dictionaries where
|
||||||
|
# sessionless_ctrls[account][jid] = a list of MessageControls that don't have
|
||||||
|
# sessions attached
|
||||||
|
self.sessionless_ctrls = {}
|
||||||
|
|
||||||
# If None, the window is not tied to any specific account
|
# If None, the window is not tied to any specific account
|
||||||
self.account = acct
|
self.account = acct
|
||||||
# If None, the window is not tied to any specific type
|
# If None, the window is not tied to any specific type
|
||||||
|
@ -146,6 +153,11 @@ class MessageWindow(object):
|
||||||
if self._controls.has_key(old_name):
|
if self._controls.has_key(old_name):
|
||||||
self._controls[new_name] = self._controls[old_name]
|
self._controls[new_name] = self._controls[old_name]
|
||||||
del self._controls[old_name]
|
del self._controls[old_name]
|
||||||
|
|
||||||
|
if self.sessionless_ctrls.has_key(old_name):
|
||||||
|
self.sessionless_ctrls[new_name] = self.sessionless_ctrls[old_name]
|
||||||
|
del self.sessionless_ctrls[old_name]
|
||||||
|
|
||||||
for ctrl in self.controls():
|
for ctrl in self.controls():
|
||||||
if ctrl.account == old_name:
|
if ctrl.account == old_name:
|
||||||
ctrl.account = new_name
|
ctrl.account = new_name
|
||||||
|
@ -157,6 +169,11 @@ class MessageWindow(object):
|
||||||
for jid_dict in self._controls.values():
|
for jid_dict in self._controls.values():
|
||||||
for dict in jid_dict.values():
|
for dict in jid_dict.values():
|
||||||
n += len(dict)
|
n += len(dict)
|
||||||
|
|
||||||
|
for jid_dict in self.sessionless_ctrls.values():
|
||||||
|
for ctrls in jid_dict.values():
|
||||||
|
n += len(ctrls)
|
||||||
|
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def resize(self, width, height):
|
def resize(self, width, height):
|
||||||
|
@ -197,6 +214,7 @@ class MessageWindow(object):
|
||||||
for ctrl in self.controls():
|
for ctrl in self.controls():
|
||||||
ctrl.shutdown()
|
ctrl.shutdown()
|
||||||
self._controls.clear()
|
self._controls.clear()
|
||||||
|
self.sessionless_ctrls.clear()
|
||||||
# Clean up handlers connected to the parent window, this is important since
|
# Clean up handlers connected to the parent window, this is important since
|
||||||
# self.window may be the RosterWindow
|
# self.window may be the RosterWindow
|
||||||
for i in self.handlers.keys():
|
for i in self.handlers.keys():
|
||||||
|
@ -206,14 +224,24 @@ class MessageWindow(object):
|
||||||
del self.handlers
|
del self.handlers
|
||||||
|
|
||||||
def new_tab(self, control):
|
def new_tab(self, control):
|
||||||
|
fjid = control.get_full_jid()
|
||||||
|
|
||||||
|
if control.session:
|
||||||
if not self._controls.has_key(control.account):
|
if not self._controls.has_key(control.account):
|
||||||
self._controls[control.account] = {}
|
self._controls[control.account] = {}
|
||||||
fjid = control.get_full_jid()
|
|
||||||
|
|
||||||
if not self._controls[control.account].has_key(fjid):
|
if not self._controls[control.account].has_key(fjid):
|
||||||
self._controls[control.account][fjid] = {}
|
self._controls[control.account][fjid] = {}
|
||||||
|
|
||||||
self._controls[control.account][fjid][control.session.thread_id] = control
|
self._controls[control.account][fjid][control.session.thread_id] = control
|
||||||
|
else:
|
||||||
|
if not self.sessionless_ctrls.has_key(control.account):
|
||||||
|
self.sessionless_ctrls[control.account] = {}
|
||||||
|
|
||||||
|
if not self.sessionless_ctrls[control.account].has_key(fjid):
|
||||||
|
self.sessionless_ctrls[control.account][fjid] = []
|
||||||
|
|
||||||
|
self.sessionless_ctrls[control.account][fjid].append(control)
|
||||||
|
|
||||||
if self.get_num_controls() == 2:
|
if self.get_num_controls() == 2:
|
||||||
# is first conversation_textview scrolled down ?
|
# is first conversation_textview scrolled down ?
|
||||||
|
@ -443,7 +471,6 @@ class MessageWindow(object):
|
||||||
|
|
||||||
fjid = ctrl.get_full_jid()
|
fjid = ctrl.get_full_jid()
|
||||||
jid = gajim.get_jid_without_resource(fjid)
|
jid = gajim.get_jid_without_resource(fjid)
|
||||||
thread_id = ctrl.session.thread_id
|
|
||||||
|
|
||||||
fctrls = self.get_controls(fjid, ctrl.account)
|
fctrls = self.get_controls(fjid, ctrl.account)
|
||||||
bctrls = self.get_controls(jid, ctrl.account)
|
bctrls = self.get_controls(jid, ctrl.account)
|
||||||
|
@ -458,13 +485,20 @@ class MessageWindow(object):
|
||||||
|
|
||||||
self.notebook.remove_page(self.notebook.page_num(ctrl.widget))
|
self.notebook.remove_page(self.notebook.page_num(ctrl.widget))
|
||||||
|
|
||||||
del self._controls[ctrl.account][fjid][thread_id]
|
if ctrl.session:
|
||||||
|
dict = self._controls
|
||||||
|
idx = ctrl.session.thread_id
|
||||||
|
else:
|
||||||
|
dict = self.sessionless_ctrls
|
||||||
|
idx = dict[ctrl.account][fjid].index(ctrl)
|
||||||
|
|
||||||
if len(self._controls[ctrl.account][fjid]) == 0:
|
del dict[ctrl.account][fjid][idx]
|
||||||
del self._controls[ctrl.account][fjid]
|
|
||||||
|
|
||||||
if len(self._controls[ctrl.account]) == 0:
|
if len(dict[ctrl.account][fjid]) == 0:
|
||||||
del self._controls[ctrl.account]
|
del dict[ctrl.account][fjid]
|
||||||
|
|
||||||
|
if len(dict[ctrl.account]) == 0:
|
||||||
|
del dict[ctrl.account]
|
||||||
|
|
||||||
self.check_tabs()
|
self.check_tabs()
|
||||||
self.show_title()
|
self.show_title()
|
||||||
|
@ -591,7 +625,16 @@ class MessageWindow(object):
|
||||||
|
|
||||||
def get_controls(self, jid, acct):
|
def get_controls(self, jid, acct):
|
||||||
try:
|
try:
|
||||||
return self._controls[acct][jid].values()
|
sessioned = self._controls[acct][jid].values()
|
||||||
|
except KeyError:
|
||||||
|
sessioned = []
|
||||||
|
|
||||||
|
sessionless = self.sessionless_controls(acct, jid)
|
||||||
|
return sessioned + sessionless
|
||||||
|
|
||||||
|
def sessionless_controls(self, acct, jid):
|
||||||
|
try:
|
||||||
|
return self.sessionless_ctrls[acct][jid]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -604,6 +647,15 @@ class MessageWindow(object):
|
||||||
return
|
return
|
||||||
self._controls[acct][new_jid] = ctrls
|
self._controls[acct][new_jid] = ctrls
|
||||||
del self._controls[acct][old_jid]
|
del self._controls[acct][old_jid]
|
||||||
|
|
||||||
|
try:
|
||||||
|
ctrls = self.sessionless_ctrls[acct][old_jid]
|
||||||
|
except KeyError:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sessionless_ctrls[acct][new_jid] = ctrls
|
||||||
|
del self.sessionless_ctrls[acct][new_jid]
|
||||||
|
|
||||||
if old_jid in gajim.last_message_time[acct]:
|
if old_jid in gajim.last_message_time[acct]:
|
||||||
gajim.last_message_time[acct][new_jid] = \
|
gajim.last_message_time[acct][new_jid] = \
|
||||||
gajim.last_message_time[acct][old_jid]
|
gajim.last_message_time[acct][old_jid]
|
||||||
|
@ -611,20 +663,54 @@ class MessageWindow(object):
|
||||||
|
|
||||||
def change_thread_key(self, jid, acct, old_thread_id, new_thread_id):
|
def change_thread_key(self, jid, acct, old_thread_id, new_thread_id):
|
||||||
'''Change the thread_id key of a control'''
|
'''Change the thread_id key of a control'''
|
||||||
try:
|
|
||||||
# Check if control exists
|
|
||||||
ctrl = self._controls[acct][jid][old_thread_id]
|
|
||||||
except KeyError:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._controls[acct][jid][new_thread_id] = ctrl
|
if jid in self._controls[acct]:
|
||||||
|
ctrl = self._controls[acct][jid][old_thread_id]
|
||||||
|
else:
|
||||||
|
jid = gajim.get_jid_without_resource(jid)
|
||||||
|
ctrl = self._controls[acct][jid][old_thread_id]
|
||||||
|
|
||||||
del self._controls[acct][jid][old_thread_id]
|
del self._controls[acct][jid][old_thread_id]
|
||||||
|
|
||||||
|
if new_thread_id:
|
||||||
|
self._controls[acct][jid][new_thread_id] = ctrl
|
||||||
|
else:
|
||||||
|
if acct not in self.sessionless_ctrls:
|
||||||
|
self.sessionless_ctrls[acct] = {}
|
||||||
|
|
||||||
|
if jid not in self.sessionless_ctrls[acct]:
|
||||||
|
self.sessionless_ctrls[acct][jid] = []
|
||||||
|
|
||||||
|
self.sessionless_ctrls[acct][jid].append(ctrl)
|
||||||
|
|
||||||
|
def move_from_sessionless(self, ctrl):
|
||||||
|
'''a control just got a session, move it to the proper holding cell'''
|
||||||
|
acct = ctrl.account
|
||||||
|
jid = ctrl.get_full_jid()
|
||||||
|
|
||||||
|
idx = self.sessionless_ctrls[acct][jid].index(ctrl)
|
||||||
|
|
||||||
|
del self.sessionless_ctrls[acct][jid][idx]
|
||||||
|
|
||||||
|
if not self._controls.has_key(acct):
|
||||||
|
self._controls[acct] = {}
|
||||||
|
|
||||||
|
if not self.sessionless_ctrls[acct].has_key(jid):
|
||||||
|
self._controls[acct][jid] = {}
|
||||||
|
|
||||||
|
thread_id = ctrl.session.thread_id
|
||||||
|
|
||||||
|
self._controls[acct][jid][thread_id] = ctrl
|
||||||
|
|
||||||
def controls(self):
|
def controls(self):
|
||||||
for jid_dict in self._controls.values():
|
for jid_dict in self._controls.values():
|
||||||
for ctrl_dict in jid_dict.values():
|
for ctrl_dict in jid_dict.values():
|
||||||
for ctrl in ctrl_dict.values():
|
for ctrl in ctrl_dict.values():
|
||||||
yield ctrl
|
yield ctrl
|
||||||
|
for jid_dict in self.sessionless_ctrls.values():
|
||||||
|
for ctrl_dict in jid_dict.values():
|
||||||
|
for ctrl in ctrl_dict:
|
||||||
|
yield ctrl
|
||||||
|
|
||||||
def move_to_next_unread_tab(self, forward):
|
def move_to_next_unread_tab(self, forward):
|
||||||
ind = self.notebook.get_current_page()
|
ind = self.notebook.get_current_page()
|
||||||
|
@ -834,11 +920,10 @@ class MessageWindowMgr(gobject.GObject):
|
||||||
|
|
||||||
def get_window(self, jid, acct):
|
def get_window(self, jid, acct):
|
||||||
for win in self.windows():
|
for win in self.windows():
|
||||||
try:
|
if (acct in win._controls and jid in win._controls[acct]) or \
|
||||||
if win._controls[acct][jid]:
|
(acct in win.sessionless_ctrls and jid in win.sessionless_ctrls[acct]):
|
||||||
return win
|
return win
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_gc_control(self, jid, acct):
|
def get_gc_control(self, jid, acct):
|
||||||
|
|
|
@ -2100,8 +2100,6 @@ class RosterWindow:
|
||||||
|
|
||||||
self.quit_on_next_offline = 0
|
self.quit_on_next_offline = 0
|
||||||
for acct in accounts:
|
for acct in accounts:
|
||||||
gajim.connections[acct].terminate_sessions()
|
|
||||||
|
|
||||||
if gajim.connections[acct].connected:
|
if gajim.connections[acct].connected:
|
||||||
self.quit_on_next_offline += 1
|
self.quit_on_next_offline += 1
|
||||||
self.send_status(acct, 'offline', message)
|
self.send_status(acct, 'offline', message)
|
||||||
|
@ -3214,7 +3212,7 @@ class RosterWindow:
|
||||||
import tictactoe
|
import tictactoe
|
||||||
|
|
||||||
sess = gajim.connections[account].make_new_session(jid,
|
sess = gajim.connections[account].make_new_session(jid,
|
||||||
klass=tictactoe.TicTacToeSession)
|
cls=tictactoe.TicTacToeSession)
|
||||||
sess.begin()
|
sess.begin()
|
||||||
|
|
||||||
def on_execute_command(self, widget, contact, account, resource=None):
|
def on_execute_command(self, widget, contact, account, resource=None):
|
||||||
|
|
|
@ -20,11 +20,19 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
self.control = None
|
self.control = None
|
||||||
|
|
||||||
def acknowledge_termination(self):
|
def acknowledge_termination(self):
|
||||||
# the other party terminated the session. we'll keep the control around, though.
|
|
||||||
stanza_session.EncryptedStanzaSession.acknowledge_termination(self)
|
stanza_session.EncryptedStanzaSession.acknowledge_termination(self)
|
||||||
|
|
||||||
if self.control:
|
if self.control:
|
||||||
self.control.session = None
|
if self.enable_encryption:
|
||||||
|
self.control.print_esession_details()
|
||||||
|
|
||||||
|
self.control.set_session(None)
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
stanza_session.EncryptedStanzaSession.terminate(self)
|
||||||
|
|
||||||
|
if self.control:
|
||||||
|
self.control.set_session(None)
|
||||||
|
|
||||||
# extracts chatstate from a <message/> stanza
|
# extracts chatstate from a <message/> stanza
|
||||||
def get_chatstate(self, msg, msgtxt):
|
def get_chatstate(self, msg, msgtxt):
|
||||||
|
@ -53,8 +61,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
return (composing_xep, chatstate)
|
return (composing_xep, chatstate)
|
||||||
|
|
||||||
# dispatch a received <message> stanza
|
# dispatch a received <message> stanza
|
||||||
def received(self, full_jid_with_resource, msgtxt, tim, encrypted, subject, msg):
|
def received(self, full_jid_with_resource, msgtxt, tim, encrypted, msg):
|
||||||
msg_type = msg.getType()
|
msg_type = msg.getType()
|
||||||
|
subject = msg.getSubject()
|
||||||
|
|
||||||
if not msg_type:
|
if not msg_type:
|
||||||
msg_type = 'normal'
|
msg_type = 'normal'
|
||||||
|
@ -246,6 +255,19 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
contact = gajim.interface.roster.add_to_not_in_the_roster(
|
contact = gajim.interface.roster.add_to_not_in_the_roster(
|
||||||
self.conn.name, jid, user_nick)
|
self.conn.name, jid, user_nick)
|
||||||
|
|
||||||
|
if not self.control:
|
||||||
|
# look for an existing chat control without a session
|
||||||
|
mw = gajim.interface.msg_win_mgr.get_window(jid, self.conn.name)
|
||||||
|
|
||||||
|
if mw:
|
||||||
|
ctrls = mw.sessionless_controls(self.conn.name, jid)
|
||||||
|
|
||||||
|
if len(ctrls):
|
||||||
|
ctrl = ctrls[0]
|
||||||
|
self.control = ctrl
|
||||||
|
ctrl.set_session(self)
|
||||||
|
ctrl.parent_win.move_from_sessionless(ctrl)
|
||||||
|
|
||||||
if not self.control:
|
if not self.control:
|
||||||
# if no control exists and message comes from highest prio, the new
|
# if no control exists and message comes from highest prio, the new
|
||||||
# control shouldn't have a resource
|
# control shouldn't have a resource
|
||||||
|
|
Loading…
Reference in New Issue