Various roster fixes.
* don't traceback when selfcontact is disconnecting * make more use of "remove contact after last event removed" mechanism * correctly redraw bigbrothers after status change * handle situation where we receive a message, go offline without reading it and reconnect after another resource has moved the sending contact to another group. know bugs: newly added transports added to "not in roster group"
This commit is contained in:
parent
399233f293
commit
d5bbc403c9
25
src/gajim.py
25
src/gajim.py
|
@ -609,7 +609,11 @@ class Interface:
|
||||||
def handle_event_notify(self, account, array):
|
def handle_event_notify(self, account, array):
|
||||||
# 'NOTIFY' (account, (jid, status, status message, resource, priority,
|
# 'NOTIFY' (account, (jid, status, status message, resource, priority,
|
||||||
# keyID, timestamp, contact_nickname))
|
# keyID, timestamp, contact_nickname))
|
||||||
# if we're here it means contact changed show
|
#
|
||||||
|
# Contact changed show
|
||||||
|
|
||||||
|
# FIXME: Drop and rewrite...
|
||||||
|
|
||||||
statuss = ['offline', 'error', 'online', 'chat', 'away', 'xa', 'dnd',
|
statuss = ['offline', 'error', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
'invisible']
|
'invisible']
|
||||||
# Ignore invalid show
|
# Ignore invalid show
|
||||||
|
@ -664,17 +668,20 @@ class Interface:
|
||||||
if contact1:
|
if contact1:
|
||||||
if contact1.show in statuss:
|
if contact1.show in statuss:
|
||||||
old_show = statuss.index(contact1.show)
|
old_show = statuss.index(contact1.show)
|
||||||
|
# nick changed
|
||||||
if contact_nickname is not None and \
|
if contact_nickname is not None and \
|
||||||
contact1.contact_name != contact_nickname:
|
contact1.contact_name != contact_nickname:
|
||||||
contact1.contact_name = contact_nickname
|
contact1.contact_name = contact_nickname
|
||||||
self.roster.draw_contact(jid, account)
|
self.roster.draw_contact(jid, account)
|
||||||
|
|
||||||
if old_show == new_show and contact1.status == status_message and \
|
if old_show == new_show and contact1.status == status_message and \
|
||||||
contact1.priority == priority: # no change
|
contact1.priority == priority: # no change
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
contact1 = gajim.contacts.get_first_contact_from_jid(account, ji)
|
contact1 = gajim.contacts.get_first_contact_from_jid(account, ji)
|
||||||
if not contact1:
|
if not contact1:
|
||||||
# presence of another resource of our jid
|
# Presence of another resource of our jid
|
||||||
|
# Create SelfContact and add to roster
|
||||||
if resource == gajim.connections[account].server_resource:
|
if resource == gajim.connections[account].server_resource:
|
||||||
return
|
return
|
||||||
contact1 = gajim.contacts.create_contact(jid = ji,
|
contact1 = gajim.contacts.create_contact(jid = ji,
|
||||||
|
@ -687,14 +694,15 @@ 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:
|
||||||
old_show = 0
|
old_show = 0
|
||||||
contact1 = gajim.contacts.copy_contact(contact1)
|
contact1 = gajim.contacts.copy_contact(contact1)
|
||||||
lcontact.append(contact1)
|
lcontact.append(contact1)
|
||||||
contact1.resource = resource
|
contact1.resource = resource
|
||||||
# FIXME ugly workaround for self contact
|
|
||||||
self.roster.add_contact(contact1.jid, account)
|
self.roster.add_contact(contact1.jid, account)
|
||||||
|
|
||||||
if contact1.jid.find('@') > 0 and len(lcontact) == 1:
|
if contact1.jid.find('@') > 0 and len(lcontact) == 1:
|
||||||
# It's not an agent
|
# It's not an agent
|
||||||
|
@ -725,6 +733,7 @@ class Interface:
|
||||||
# We're connected since more that 30 seconds
|
# We're connected since more that 30 seconds
|
||||||
contact1.last_status_time = time.localtime()
|
contact1.last_status_time = time.localtime()
|
||||||
contact1.contact_nickname = contact_nickname
|
contact1.contact_nickname = contact_nickname
|
||||||
|
|
||||||
if gajim.jid_is_transport(jid):
|
if gajim.jid_is_transport(jid):
|
||||||
# It must be an agent
|
# It must be an agent
|
||||||
if ji in jid_list:
|
if ji in jid_list:
|
||||||
|
@ -852,10 +861,7 @@ class Interface:
|
||||||
if jid in gajim.contacts.get_jid_list(account):
|
if jid in gajim.contacts.get_jid_list(account):
|
||||||
c = gajim.contacts.get_first_contact_from_jid(account, jid)
|
c = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
c.resource = array[1]
|
c.resource = array[1]
|
||||||
self.roster.remove_contact(c.jid, account)
|
self.roster.remove_contact_from_groups(c.jid, account, [('Not in Roster'),])
|
||||||
if _('Not in Roster') in c.groups:
|
|
||||||
c.groups.remove(_('Not in Roster'))
|
|
||||||
self.roster.add_contact(c.jid, account)
|
|
||||||
else:
|
else:
|
||||||
keyID = ''
|
keyID = ''
|
||||||
attached_keys = gajim.config.get_per('accounts', account,
|
attached_keys = gajim.config.get_per('accounts', account,
|
||||||
|
@ -922,8 +928,7 @@ class Interface:
|
||||||
if c.jid in gajim.to_be_removed[account]:
|
if c.jid in gajim.to_be_removed[account]:
|
||||||
# This way we'll really remove it
|
# This way we'll really remove it
|
||||||
gajim.to_be_removed[account].remove(c.jid)
|
gajim.to_be_removed[account].remove(c.jid)
|
||||||
gajim.contacts.remove_jid(account, c.jid)
|
self.roster.remove_contact(c.jid, account, backend = True)
|
||||||
self.roster.remove_contact(c.jid, account)
|
|
||||||
|
|
||||||
def handle_event_register_agent_info(self, account, array):
|
def handle_event_register_agent_info(self, account, array):
|
||||||
# ('REGISTER_AGENT_INFO', account, (agent, infos, is_form))
|
# ('REGISTER_AGENT_INFO', account, (agent, infos, is_form))
|
||||||
|
|
|
@ -760,33 +760,6 @@ class RosterWindow:
|
||||||
self.remove_contact(jid, account, force = True, backend = True)
|
self.remove_contact(jid, account, force = True, backend = True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
#FIXME:
|
|
||||||
# We need to define a generic way to keep contacts in roster
|
|
||||||
# as long as they have pending events or as we
|
|
||||||
# still chat with them
|
|
||||||
def _readd_contact_to_roster_if_needed(self, contact, account):
|
|
||||||
need_readd = False
|
|
||||||
if len(gajim.events.get_events(account, contact.jid)):
|
|
||||||
need_readd = True
|
|
||||||
elif gajim.interface.msg_win_mgr.has_window(contact.jid, account):
|
|
||||||
if _('Not in Roster') in contact.groups:
|
|
||||||
# Close chat window
|
|
||||||
msg_win = gajim.interface.msg_win_mgr.get_window(contact.jid,
|
|
||||||
account)
|
|
||||||
for ctrl in gajim.interface.msg_win_mgr.get_chat_controls(
|
|
||||||
contact.jid, account):
|
|
||||||
msg_win.remove_tab(ctrl, msg_win.CLOSE_CLOSE_BUTTON)
|
|
||||||
else:
|
|
||||||
need_readd = True
|
|
||||||
if need_readd:
|
|
||||||
c = gajim.contacts.create_contact(jid = contact.jid,
|
|
||||||
name = '', groups = [_('Not in Roster')],
|
|
||||||
show = 'not in roster', status = '', ask = 'none',
|
|
||||||
keyID = contact.keyID)
|
|
||||||
gajim.contacts.add_contact(account, c)
|
|
||||||
self.add_contact(contact.jid, account)
|
|
||||||
|
|
||||||
|
|
||||||
def add_contact_to_groups(self, jid, account, groups):
|
def add_contact_to_groups(self, jid, account, groups):
|
||||||
'''Add contact to given groups and redraw them.
|
'''Add contact to given groups and redraw them.
|
||||||
|
|
||||||
|
@ -1165,13 +1138,15 @@ class RosterWindow:
|
||||||
Show contact if it has pending events
|
Show contact if it has pending events
|
||||||
'''
|
'''
|
||||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
|
if not contact:
|
||||||
|
# idle draw or just removed SelfContact
|
||||||
|
return
|
||||||
|
|
||||||
family = gajim.contacts.get_metacontacts_family(account, jid)
|
family = gajim.contacts.get_metacontacts_family(account, jid)
|
||||||
if family:
|
if family:
|
||||||
# There might be a new big brother
|
# There might be a new big brother
|
||||||
self._recalibrate_metacontact_family(family, account)
|
self._recalibrate_metacontact_family(family, account)
|
||||||
else:
|
self.draw_contact(jid, account)
|
||||||
self.draw_contact(jid, account)
|
|
||||||
self.draw_account(account)
|
self.draw_account(account)
|
||||||
|
|
||||||
for group in contact.groups:
|
for group in contact.groups:
|
||||||
|
@ -1496,7 +1471,7 @@ class RosterWindow:
|
||||||
gajim.groups[account] = {}
|
gajim.groups[account] = {}
|
||||||
for jid in array.keys():
|
for jid in array.keys():
|
||||||
# Remove the contact in roster. It might has changed
|
# Remove the contact in roster. It might has changed
|
||||||
self.remove_contact(jid, account)
|
self.remove_contact(jid, account, force = True)
|
||||||
# Remove old Contact instances
|
# Remove old Contact instances
|
||||||
gajim.contacts.remove_jid(account, jid, remove_meta=False)
|
gajim.contacts.remove_jid(account, jid, remove_meta=False)
|
||||||
jids = jid.split('/')
|
jids = jid.split('/')
|
||||||
|
@ -1827,6 +1802,7 @@ class RosterWindow:
|
||||||
# We come back from invisible, join bookmarks
|
# We come back from invisible, join bookmarks
|
||||||
gajim.interface.auto_join_bookmarks(account)
|
gajim.interface.auto_join_bookmarks(account)
|
||||||
|
|
||||||
|
|
||||||
def chg_contact_status(self, contact, show, status, account):
|
def chg_contact_status(self, contact, show, status, account):
|
||||||
'''When a contact changes his or her status'''
|
'''When a contact changes his or her status'''
|
||||||
contact_instances = gajim.contacts.get_contacts(account, contact.jid)
|
contact_instances = gajim.contacts.get_contacts(account, contact.jid)
|
||||||
|
@ -1835,9 +1811,12 @@ class RosterWindow:
|
||||||
# name is to show in conversation window
|
# name is to show in conversation window
|
||||||
name = contact.get_shown_name()
|
name = contact.get_shown_name()
|
||||||
|
|
||||||
|
# The contact has several resources
|
||||||
if len(contact_instances) > 1:
|
if len(contact_instances) > 1:
|
||||||
if contact.resource != '':
|
if contact.resource != '':
|
||||||
name += '/' + contact.resource
|
name += '/' + contact.resource
|
||||||
|
|
||||||
|
# Remove resource when going offline
|
||||||
if show in ('offline', 'error') and \
|
if show in ('offline', 'error') and \
|
||||||
len(gajim.events.get_events(account, contact.get_full_jid())) == 0:
|
len(gajim.events.get_events(account, contact.get_full_jid())) == 0:
|
||||||
jid_with_resource = contact.jid + '/' + contact.resource
|
jid_with_resource = contact.jid + '/' + contact.resource
|
||||||
|
@ -1848,13 +1827,13 @@ class RosterWindow:
|
||||||
for ctrl in win.get_controls(jid_with_resource, account):
|
for ctrl in win.get_controls(jid_with_resource, account):
|
||||||
ctrl.update_ui()
|
ctrl.update_ui()
|
||||||
win.redraw_tab(ctrl)
|
win.redraw_tab(ctrl)
|
||||||
|
|
||||||
gajim.contacts.remove_contact(account, contact)
|
gajim.contacts.remove_contact(account, contact)
|
||||||
|
|
||||||
elif contact.jid == gajim.get_jid_from_account(account) and \
|
elif contact.jid == gajim.get_jid_from_account(account) and \
|
||||||
show == 'offline':
|
show in ('offline', 'error'):
|
||||||
# Our SelfContact went offline. Remove him from roster and contacts
|
# SelfContact went offline. Remove him when last pending message was read
|
||||||
self.remove_contact(contact.jid, account)
|
self.remove_contact(contact.jid, account, backend = True)
|
||||||
gajim.contacts.remove_contact(account, contact)
|
|
||||||
# print status in chat window and update status/GPG image
|
# print status in chat window and update status/GPG image
|
||||||
if gajim.interface.msg_win_mgr.has_window(contact.jid, account):
|
if gajim.interface.msg_win_mgr.has_window(contact.jid, account):
|
||||||
win = gajim.interface.msg_win_mgr.get_window(contact.jid, account)
|
win = gajim.interface.msg_win_mgr.get_window(contact.jid, account)
|
||||||
|
@ -1909,8 +1888,7 @@ class RosterWindow:
|
||||||
# Remove SelfContact from roster and remove it.
|
# Remove SelfContact from roster and remove it.
|
||||||
# It might be gone when we return
|
# It might be gone when we return
|
||||||
self_jid = gajim.get_jid_from_account(account)
|
self_jid = gajim.get_jid_from_account(account)
|
||||||
self.remove_contact(self_jid, account)
|
self.remove_contact(self_jid, account, backend = True)
|
||||||
gajim.contacts.remove_jid(account, self_jid)
|
|
||||||
self.actions_menu_needs_rebuild = True
|
self.actions_menu_needs_rebuild = True
|
||||||
self.update_status_combobox()
|
self.update_status_combobox()
|
||||||
# Force the rebuild now since the on_activates on the menu itself does
|
# Force the rebuild now since the on_activates on the menu itself does
|
||||||
|
@ -2310,7 +2288,6 @@ class RosterWindow:
|
||||||
def on_remove_agent(self, widget, list_):
|
def on_remove_agent(self, widget, list_):
|
||||||
'''When an agent is requested to be removed. list_ is a list of
|
'''When an agent is requested to be removed. list_ is a list of
|
||||||
(contact, account) tuple'''
|
(contact, account) tuple'''
|
||||||
# FIXME remove transport contacts
|
|
||||||
for (contact, account) in list_:
|
for (contact, account) in list_:
|
||||||
if gajim.config.get_per('accounts', account, 'hostname') == \
|
if gajim.config.get_per('accounts', account, 'hostname') == \
|
||||||
contact.jid:
|
contact.jid:
|
||||||
|
@ -2579,16 +2556,9 @@ class RosterWindow:
|
||||||
for contact in gajim.contacts.get_contacts_from_group(account, group):
|
for contact in gajim.contacts.get_contacts_from_group(account, group):
|
||||||
if not dlg.is_checked():
|
if not dlg.is_checked():
|
||||||
self.remove_contact_from_groups(contact.jid,account, [group])
|
self.remove_contact_from_groups(contact.jid,account, [group])
|
||||||
gajim.connections[account].update_contact(contact.jid,
|
|
||||||
contact.name, contact.groups)
|
|
||||||
self.add_contact(contact.jid, account)
|
|
||||||
else:
|
else:
|
||||||
gajim.connections[account].unsubscribe(contact.jid)
|
gajim.connections[account].unsubscribe(contact.jid)
|
||||||
for c in gajim.contacts.get_contacts(account, contact.jid):
|
self.remove_contact(contact.jid, account, backend = True)
|
||||||
self.remove_contact(c.jid, account)
|
|
||||||
gajim.contacts.remove_jid(account, c.jid)
|
|
||||||
self._readd_contact_to_roster_if_needed(contact, account)
|
|
||||||
self.draw_account(account)
|
|
||||||
|
|
||||||
def on_assign_pgp_key(self, widget, contact, account):
|
def on_assign_pgp_key(self, widget, contact, account):
|
||||||
attached_keys = gajim.config.get_per('accounts', account,
|
attached_keys = gajim.config.get_per('accounts', account,
|
||||||
|
@ -2964,21 +2934,13 @@ class RosterWindow:
|
||||||
remove_auth = False
|
remove_auth = False
|
||||||
for (contact, account) in list_:
|
for (contact, account) in list_:
|
||||||
gajim.connections[account].unsubscribe(contact.jid, remove_auth)
|
gajim.connections[account].unsubscribe(contact.jid, remove_auth)
|
||||||
for c in gajim.contacts.get_contacts(account, contact.jid):
|
self.remove_contact(contact.jid, account, backend = True)
|
||||||
self.remove_contact(c.jid, account)
|
|
||||||
gajim.contacts.remove_jid(account, contact.jid)
|
|
||||||
self.draw_account(account)
|
|
||||||
if not remove_auth and contact.sub == 'both':
|
if not remove_auth and contact.sub == 'both':
|
||||||
contact.name = ''
|
contact.name = ''
|
||||||
contact.groups = []
|
contact.groups = []
|
||||||
contact.sub = 'from'
|
contact.sub = 'from'
|
||||||
gajim.contacts.add_contact(account, contact)
|
gajim.contacts.add_contact(account, contact)
|
||||||
self.add_contact(contact.jid, account)
|
self.add_contact(contact.jid, account)
|
||||||
else:
|
|
||||||
if _('Not in Roster') in contact.groups:
|
|
||||||
gajim.events.remove_events(account, contact.jid)
|
|
||||||
self._readd_contact_to_roster_if_needed(contact, account)
|
|
||||||
|
|
||||||
def on_ok2(list_):
|
def on_ok2(list_):
|
||||||
on_ok(False, list_)
|
on_ok(False, list_)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue