Refactor Presence

- Remove option to hide self contacts for now. This makes the code less
complicated.
- Move as much code as possible into the presence module
- Use nbxmpp properties
This commit is contained in:
Philipp Hörist 2019-01-01 16:19:35 +01:00
parent 608607b721
commit a289ad5f60
9 changed files with 260 additions and 313 deletions

View File

@ -268,7 +268,6 @@ class Config:
'check_idle_every_foo_seconds': [opt_int, 2, _('Choose interval between 2 checks of idleness.')], 'check_idle_every_foo_seconds': [opt_int, 2, _('Choose interval between 2 checks of idleness.')],
'uri_schemes': [opt_str, 'aaa:// aaas:// acap:// cap:// cid: crid:// data: dav: dict:// dns: fax: file:/ ftp:// geo: go: gopher:// h323: http:// https:// iax: icap:// im: imap:// info: ipp:// iris: iris.beep: iris.xpc: iris.xpcs: iris.lwz: ldap:// mid: modem: msrp:// msrps:// mtqp:// mupdate:// news: nfs:// nntp:// opaquelocktoken: pop:// pres: prospero:// rtsp:// service: shttp:// sip: sips: sms: snmp:// soap.beep:// soap.beeps:// tag: tel: telnet:// tftp:// thismessage:/ tip:// tv: urn:// vemmi:// xmlrpc.beep:// xmlrpc.beeps:// z39.50r:// z39.50s:// about: apt: cvs:// daap:// ed2k:// feed: fish:// git:// iax2: irc:// ircs:// ldaps:// magnet: mms:// rsync:// ssh:// svn:// sftp:// smb:// webcal:// aesgcm://', _('Valid uri schemes. Only schemes in this list will be accepted as "real" uri. (mailto and xmpp are handled separately)'), True], 'uri_schemes': [opt_str, 'aaa:// aaas:// acap:// cap:// cid: crid:// data: dav: dict:// dns: fax: file:/ ftp:// geo: go: gopher:// h323: http:// https:// iax: icap:// im: imap:// info: ipp:// iris: iris.beep: iris.xpc: iris.xpcs: iris.lwz: ldap:// mid: modem: msrp:// msrps:// mtqp:// mupdate:// news: nfs:// nntp:// opaquelocktoken: pop:// pres: prospero:// rtsp:// service: shttp:// sip: sips: sms: snmp:// soap.beep:// soap.beeps:// tag: tel: telnet:// tftp:// thismessage:/ tip:// tv: urn:// vemmi:// xmlrpc.beep:// xmlrpc.beeps:// z39.50r:// z39.50s:// about: apt: cvs:// daap:// ed2k:// feed: fish:// git:// iax2: irc:// ircs:// ldaps:// magnet: mms:// rsync:// ssh:// svn:// sftp:// smb:// webcal:// aesgcm://', _('Valid uri schemes. Only schemes in this list will be accepted as "real" uri. (mailto and xmpp are handled separately)'), True],
'shell_like_completion': [opt_bool, False, _('If true, completion in groupchats will be like a shell auto-completion')], 'shell_like_completion': [opt_bool, False, _('If true, completion in groupchats will be like a shell auto-completion')],
'show_self_contact': [opt_str, 'when_other_resource', _('When is self contact row displayed. Can be "always", "when_other_resource" or "never"'), True],
'audio_input_device': [opt_str, 'autoaudiosrc ! volume name=gajim_vol'], 'audio_input_device': [opt_str, 'autoaudiosrc ! volume name=gajim_vol'],
'audio_output_device': [opt_str, 'autoaudiosink'], 'audio_output_device': [opt_str, 'autoaudiosink'],
'video_input_device': [opt_str, 'autovideosrc'], 'video_input_device': [opt_str, 'autovideosrc'],

View File

@ -67,136 +67,13 @@ class ConnectionHandlersBase:
# We decrypt GPG messages one after the other. Keep queue in mem # We decrypt GPG messages one after the other. Keep queue in mem
self.gpg_messages_to_decrypt = [] self.gpg_messages_to_decrypt = []
app.ged.register_event_handler('presence-received', ged.CORE,
self._nec_presence_received)
app.ged.register_event_handler('gc-message-received', ged.CORE, app.ged.register_event_handler('gc-message-received', ged.CORE,
self._nec_gc_message_received) self._nec_gc_message_received)
def cleanup(self): def cleanup(self):
app.ged.remove_event_handler('presence-received', ged.CORE,
self._nec_presence_received)
app.ged.remove_event_handler('gc-message-received', ged.CORE, app.ged.remove_event_handler('gc-message-received', ged.CORE,
self._nec_gc_message_received) self._nec_gc_message_received)
def _nec_presence_received(self, obj):
account = obj.conn.name
if account != self.name:
return
jid = obj.jid
resource = obj.resource or ''
statuss = ['offline', 'error', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible']
obj.old_show = 0
obj.new_show = statuss.index(obj.show)
obj.contact_list = []
highest = app.contacts.get_contact_with_highest_priority(account, jid)
obj.was_highest = (highest and highest.resource == resource)
# Update contact
obj.contact_list = app.contacts.get_contacts(account, jid)
obj.contact = None
resources = []
for c in obj.contact_list:
resources.append(c.resource)
if c.resource == resource:
obj.contact = c
break
if obj.contact:
if obj.contact.show in statuss:
obj.old_show = statuss.index(obj.contact.show)
# nick changed
if obj.contact_nickname is not None and \
obj.contact.contact_name != obj.contact_nickname:
obj.contact.contact_name = obj.contact_nickname
obj.need_redraw = True
elif obj.old_show != obj.new_show or obj.contact.status != \
obj.status:
obj.need_redraw = True
else:
obj.contact = app.contacts.get_first_contact_from_jid(account,
jid)
if not obj.contact:
# Presence of another resource of our jid
# Create self contact and add to roster
if resource == obj.conn.server_resource:
return
# Ignore offline presence of unknown self resource
if obj.new_show < 2:
return
obj.contact = app.contacts.create_self_contact(jid=jid,
account=account, show=obj.show, status=obj.status,
priority=obj.prio, keyID=obj.keyID,
resource=obj.resource)
app.contacts.add_contact(account, obj.contact)
obj.contact_list.append(obj.contact)
elif obj.contact.show in statuss:
obj.old_show = statuss.index(obj.contact.show)
if (resources != [''] and (len(obj.contact_list) != 1 or \
obj.contact_list[0].show not in ('not in roster', 'offline'))) and \
not app.jid_is_transport(jid):
# Another resource of an existing contact connected
obj.old_show = 0
obj.contact = app.contacts.copy_contact(obj.contact)
obj.contact_list.append(obj.contact)
obj.contact.resource = resource
obj.need_redraw = True
obj.need_add_in_roster = True
if not app.jid_is_transport(jid) and len(obj.contact_list) == 1:
# It's not an agent
if obj.old_show == 0 and obj.new_show > 1:
if not jid in app.newly_added[account]:
app.newly_added[account].append(jid)
if jid in app.to_be_removed[account]:
app.to_be_removed[account].remove(jid)
elif obj.old_show > 1 and obj.new_show == 0 and \
obj.conn.connected > 1:
if not jid in app.to_be_removed[account]:
app.to_be_removed[account].append(jid)
if jid in app.newly_added[account]:
app.newly_added[account].remove(jid)
obj.need_redraw = True
obj.contact.show = obj.show
obj.contact.status = obj.status
obj.contact.priority = obj.prio
attached_keys = app.config.get_per('accounts', account,
'attached_gpg_keys').split()
if jid in attached_keys:
obj.contact.keyID = attached_keys[attached_keys.index(jid) + 1]
else:
# Do not override assigned key
obj.contact.keyID = obj.keyID
obj.contact.contact_nickname = obj.contact_nickname
obj.contact.idle_time = obj.idle_time
if app.jid_is_transport(jid):
return
# It isn't an agent
# (when contact signs out or has errors)
if obj.show in ('offline', 'error'):
# TODO: This causes problems when another
# resource signs off!
self.stop_all_active_file_transfers(obj.contact)
if app.config.get('log_contact_status_changes') and \
app.config.should_log(self.name, obj.jid):
show = app.logger.convert_show_values_to_db_api_values(obj.show)
if show is not None:
app.logger.insert_into_logs(self.name,
nbxmpp.JID(obj.jid).getStripped(),
time.time(),
KindConstant.STATUS,
message=obj.status,
show=show)
def _check_for_mam_compliance(self, room_jid, stanza_id): def _check_for_mam_compliance(self, room_jid, stanza_id):
namespace = muc_caps_cache.get_mam_namespace(room_jid) namespace = muc_caps_cache.get_mam_namespace(room_jid)
if stanza_id is None and namespace == nbxmpp.NS_MAM_2: if stanza_id is None and namespace == nbxmpp.NS_MAM_2:

View File

@ -144,105 +144,8 @@ class StreamConflictReceivedEvent(nec.NetworkIncomingEvent):
self.conn = self.base_event.conn self.conn = self.base_event.conn
return True return True
class PresenceHelperEvent: class PresenceReceivedEvent(nec.NetworkIncomingEvent):
def _generate_show(self):
self.show = self.stanza.getShow()
if self.show not in ('chat', 'away', 'xa', 'dnd'):
self.show = '' # We ignore unknown show
if not self.ptype and not self.show:
self.show = 'online'
elif self.ptype == 'unavailable':
self.show = 'offline'
def _generate_ptype(self):
self.ptype = self.stanza.getType()
if self.ptype == 'available':
self.ptype = None
rfc_types = ('unavailable', 'error', 'subscribe', 'subscribed',
'unsubscribe', 'unsubscribed')
if self.ptype and not self.ptype in rfc_types:
self.ptype = None
class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent,
PresenceHelperEvent):
name = 'presence-received' name = 'presence-received'
base_network_events = ['raw-pres-received']
def _generate_keyID(self, sig_tag):
self.keyID = ''
if sig_tag and self.conn.USE_GPG and self.ptype != 'error':
# error presences contain our own signature
# verify
sig_msg = sig_tag.getData()
self.keyID = self.conn.gpg.verify(self.status, sig_msg)
self.keyID = helpers.prepare_and_validate_gpg_keyID(self.conn.name,
self.jid,
self.keyID)
def _generate_prio(self):
self.prio = self.stanza.getPriority()
try:
self.prio = int(self.prio)
except Exception:
self.prio = 0
def generate(self):
self.conn = self.base_event.conn
self.stanza = self.base_event.stanza
self.need_add_in_roster = False
self.need_redraw = False
self.popup = False # Do we want to open chat window ?
if not self.conn or self.conn.connected < 2:
log.debug('account is no more connected')
return
self._generate_ptype()
try:
self.get_jid_resource()
except Exception:
log.warning('Invalid JID: %s, ignoring it', self.stanza.getFrom())
return
jid_list = app.contacts.get_jid_list(self.conn.name)
self.timestamp = None
self.get_id()
self.avatar_sha = None
# XEP-0172 User Nickname
self.user_nick = self.stanza.getTagData('nick') or ''
self.contact_nickname = None
self.transport_auto_auth = False
# XEP-0203
self.timestamp = parse_delay(self.stanza)
if self.timestamp is None:
self.timestamp = time_time()
# XEP-0319
self.idle_time = parse_idle(self.stanza)
sig_tag = self.stanza.getTag('x', namespace=nbxmpp.NS_SIGNED)
self.status = self.stanza.getStatus() or ''
self._generate_show()
self._generate_prio()
self._generate_keyID(sig_tag)
self.errcode = self.stanza.getErrorCode()
self.errmsg = self.stanza.getErrorMsg()
if self.ptype == 'error':
return
if not self.ptype or self.ptype == 'unavailable':
our_jid = app.get_jid_from_account(self.conn.name)
if self.jid == our_jid and self.resource == self.conn.server_resource:
# We got our own presence
app.nec.push_incoming_event(OurShowEvent(None, conn=self.conn,
show=self.show))
elif self.jid in jid_list or self.jid == our_jid:
return True
class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent): class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent):
name = 'presence-received' name = 'presence-received'
@ -254,16 +157,13 @@ class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent):
self.keyID = None self.keyID = None
self.idle_time = None self.idle_time = None
self.timestamp = 0 self.timestamp = 0
self.contact_nickname = None
self.avatar_sha = None self.avatar_sha = None
self.need_add_in_roster = False self.need_add_in_roster = False
self.need_redraw = False
if self.show == 'offline': if self.show == 'offline':
self.ptype = 'unavailable' self.ptype = 'unavailable'
else: else:
self.ptype = None self.ptype = None
self.user_nick = '' self.user_nick = ''
self.transport_auto_auth = False
self.errcode = None self.errcode = None
self.errmsg = '' self.errmsg = ''
self.popup = False # Do we want to open chat window ? self.popup = False # Do we want to open chat window ?

View File

@ -368,6 +368,9 @@ class LegacyContactsAPI:
def get_contact(self, account, jid, resource=None): def get_contact(self, account, jid, resource=None):
return self._accounts[account].contacts.get_contact(jid, resource=resource) return self._accounts[account].contacts.get_contact(jid, resource=resource)
def get_contact_strict(self, account, jid, resource):
return self._accounts[account].contacts.get_contact_strict(jid, resource)
def get_avatar(self, account, *args, **kwargs): def get_avatar(self, account, *args, **kwargs):
return self._accounts[account].contacts.get_avatar(*args, **kwargs) return self._accounts[account].contacts.get_avatar(*args, **kwargs)
@ -553,7 +556,7 @@ class Contacts():
""" """
Return the list of contact instances for this jid Return the list of contact instances for this jid
""" """
return self._contacts.get(jid, []) return list(self._contacts.get(jid, []))
def get_contact(self, jid, resource=None): def get_contact(self, jid, resource=None):
### WARNING ### ### WARNING ###

View File

@ -15,13 +15,17 @@
# Presence handler # Presence handler
import logging import logging
import time
import nbxmpp import nbxmpp
from nbxmpp.structs import StanzaHandler
from nbxmpp.const import PresenceType
from gajim.common import app from gajim.common import app
from gajim.common.i18n import _ from gajim.common.i18n import _
from gajim.common.nec import NetworkEvent from gajim.common.nec import NetworkEvent
from gajim.common.modules.user_nickname import parse_nickname from gajim.common.const import KindConstant
from gajim.common.helpers import prepare_and_validate_gpg_keyID
log = logging.getLogger('gajim.c.m.presence') log = logging.getLogger('gajim.c.m.presence')
@ -32,11 +36,25 @@ class Presence:
self._account = con.name self._account = con.name
self.handlers = [ self.handlers = [
('presence', self._presence_received), StanzaHandler(name='presence',
('presence', self._subscribe_received, 'subscribe'), callback=self._presence_received,
('presence', self._subscribed_received, 'subscribed'), priority=50),
('presence', self._unsubscribe_received, 'unsubscribe'), StanzaHandler(name='presence',
('presence', self._unsubscribed_received, 'unsubscribed'), callback=self._subscribe_received,
typ='subscribe',
priority=49),
StanzaHandler(name='presence',
callback=self._subscribed_received,
typ='subscribed',
priority=49),
StanzaHandler(name='presence',
callback=self._unsubscribe_received,
typ='unsubscribe',
priority=49),
StanzaHandler(name='presence',
callback=self._unsubscribed_received,
typ='unsubscribed',
priority=49),
] ]
# keep the jids we auto added (transports contacts) to not send the # keep the jids we auto added (transports contacts) to not send the
@ -46,32 +64,198 @@ class Presence:
# list of jid to auto-authorize # list of jid to auto-authorize
self.jids_for_auto_auth = [] self.jids_for_auto_auth = []
def _presence_received(self, _con, stanza): def _presence_received(self, _con, stanza, properties):
if stanza.getType() in ('subscribe', 'subscribed', log.info('Received from %s', properties.jid)
'unsubscribe', 'unsubscribed'):
# Dont handle that here if properties.type == PresenceType.ERROR:
log.info('Error: %s %s', properties.jid, properties.error)
raise nbxmpp.NodeProcessed
if self._account == 'Local':
app.nec.push_incoming_event(
NetworkEvent('raw-pres-received',
conn=self._con,
stanza=stanza))
raise nbxmpp.NodeProcessed
if properties.is_self_presence:
app.nec.push_incoming_event(
NetworkEvent('our-show',
conn=self._con,
show=properties.show.value))
raise nbxmpp.NodeProcessed
contacts = app.contacts.get_jid_list(self._account)
if properties.jid.getBare() not in contacts and not properties.is_self_bare:
# Handle only presence from roster contacts
log.warning('Unkown presence received')
log.warning(stanza)
return return
log.info('Received from %s', stanza.getFrom()) key_id = ''
if nbxmpp.isErrorNode(stanza): if properties.signed is not None and self._con.USE_GPG:
log.info('Error:\n%s', stanza) key_id = self._con.gpg.verify(properties.status, properties.signed)
key_id = prepare_and_validate_gpg_keyID(
self._account, properties.jid.getBare(), key_id)
app.nec.push_incoming_event( show = properties.show.value
NetworkEvent('raw-pres-received', if properties.type.is_unavailable:
conn=self._con, show = 'offline'
stanza=stanza))
event_attrs = {
'conn': self._con,
'stanza': stanza,
'keyID': key_id,
'prio': properties.priority,
'need_add_in_roster': False,
'popup': False,
'ptype': properties.type.value,
'jid': properties.jid.getBare(),
'resource': properties.jid.getResource(),
'id_': properties.id,
'fjid': str(properties.jid),
'timestamp': properties.timestamp,
'avatar_sha': properties.avatar_sha,
'user_nick': properties.nickname,
'idle_time': properties.idle_timestamp,
'show': show,
'new_show': show,
'old_show': 0,
'status': properties.status,
'contact_list': [],
'contact': None,
'need_add_in_roster': False,
}
event_ = NetworkEvent('presence-received', **event_attrs)
# TODO: Refactor
self._update_contact(event_, properties)
app.nec.push_incoming_event(event_)
raise nbxmpp.NodeProcessed
def _update_contact(self, event, properties):
jid = properties.jid.getBare()
resource = properties.jid.getResource()
status_strings = ['offline', 'error', 'online', 'chat', 'away',
'xa', 'dnd', 'invisible']
event.new_show = status_strings.index(event.show)
# Update contact
contact_list = app.contacts.get_contacts(self._account, jid)
if not contact_list:
log.warning('No contact found')
return
event.contact_list = contact_list
contact = app.contacts.get_contact_strict(self._account,
properties.jid.getBare(),
properties.jid.getResource())
if contact is None:
contact = app.contacts.get_first_contact_from_jid(self._account, jid)
if contact is None:
log.warning('First contact not found')
return
if self._is_resource_known(contact_list) and not app.jid_is_transport(jid):
# Another resource of an existing contact connected
# Add new contact
event.old_show = 0
contact = app.contacts.copy_contact(contact)
contact.resource = resource
app.contacts.add_contact(self._account, contact)
else:
# Convert the inital roster contact to a contact with resource
contact.resource = resource
event.old_show = status_strings.index(contact.show)
event.need_add_in_roster = True
elif contact.show in status_strings:
event.old_show = status_strings.index(contact.show)
# Update contact with presence data
contact.show = event.show
contact.status = properties.status
contact.priority = properties.priority
attached_keys = app.config.get_per('accounts', self._account,
'attached_gpg_keys').split()
if jid in attached_keys:
contact.keyID = attached_keys[attached_keys.index(jid) + 1]
else:
# Do not override assigned key
contact.keyID = event.keyID
contact.idle_time = properties.idle_timestamp
event.contact = contact
if not app.jid_is_transport(jid) and len(contact_list) == 1:
# It's not an agent
if event.old_show == 0 and event.new_show > 1:
if not jid in app.newly_added[self._account]:
app.newly_added[self._account].append(jid)
if jid in app.to_be_removed[self._account]:
app.to_be_removed[self._account].remove(jid)
elif event.old_show > 1 and event.new_show == 0 and \
self._con.connected > 1:
if not jid in app.to_be_removed[self._account]:
app.to_be_removed[self._account].append(jid)
if jid in app.newly_added[self._account]:
app.newly_added[self._account].remove(jid)
if app.jid_is_transport(jid):
return
if properties.type.is_unavailable:
# TODO: This causes problems when another
# resource signs off!
self._con.stop_all_active_file_transfers(contact)
self._log_presence(properties)
@staticmethod
def _is_resource_known(contact_list):
if len(contact_list) > 1:
return True
if contact_list[0].resource == '':
return False
return contact_list[0].show not in ('not in roster', 'offline')
def _log_presence(self, properties):
if not app.config.get('log_contact_status_changes'):
return
if not app.config.should_log(self._account, properties.jid.getBare()):
return
# TODO: Refactor
if properties.type.is_unavailable:
show = 'offline'
else:
show = properties.show.value
app.logger.insert_into_logs(self._account,
properties.jid.getBare(),
time.time(),
KindConstant.STATUS,
message=properties.status,
show=show)
def _subscribe_received(self, _con, _stanza, properties):
jid = properties.jid.getBare()
fjid = str(properties.jid)
def _subscribe_received(self, _con, stanza):
from_ = stanza.getFrom()
jid = from_.getStripped()
fjid = str(from_)
status = stanza.getStatus()
is_transport = app.jid_is_transport(fjid) is_transport = app.jid_is_transport(fjid)
auto_auth = app.config.get_per('accounts', self._account, 'autoauth') auto_auth = app.config.get_per('accounts', self._account, 'autoauth')
user_nick = parse_nickname(stanza)
log.info('Received Subscribe: %s, transport: %s, auto_auth: %s, ' log.info('Received Subscribe: %s, transport: %s, '
'user_nick: %s', from_, is_transport, auto_auth, user_nick) 'auto_auth: %s, user_nick: %s',
properties.jid, is_transport, auto_auth, properties.nickname)
if is_transport and fjid in self._con.agent_registrations: if is_transport and fjid in self._con.agent_registrations:
self._con.agent_registrations[fjid]['sub_received'] = True self._con.agent_registrations[fjid]['sub_received'] = True
if not self._con.agent_registrations[fjid]['roster_push']: if not self._con.agent_registrations[fjid]['roster_push']:
@ -81,8 +265,8 @@ class Presence:
if auto_auth or is_transport or jid in self.jids_for_auto_auth: if auto_auth or is_transport or jid in self.jids_for_auto_auth:
self.send_presence(fjid, 'subscribed') self.send_presence(fjid, 'subscribed')
if not status: status = (properties.status or
status = _('I would like to add you to my roster.') _('I would like to add you to my roster.'))
app.nec.push_incoming_event(NetworkEvent( app.nec.push_incoming_event(NetworkEvent(
'subscribe-presence-received', 'subscribe-presence-received',
@ -90,16 +274,15 @@ class Presence:
jid=jid, jid=jid,
fjid=fjid, fjid=fjid,
status=status, status=status,
user_nick=user_nick, user_nick=properties.nickname,
is_transport=is_transport)) is_transport=is_transport))
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
def _subscribed_received(self, _con, stanza): def _subscribed_received(self, _con, _stanza, properties):
from_ = stanza.getFrom() jid = properties.jid.getBare()
jid = from_.getStripped() resource = properties.jid.getResource()
resource = from_.getResource() log.info('Received Subscribed: %s', properties.jid)
log.info('Received Subscribed: %s', from_)
if jid in self.automatically_added: if jid in self.automatically_added:
self.automatically_added.remove(jid) self.automatically_added.remove(jid)
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
@ -110,17 +293,15 @@ class Presence:
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
@staticmethod @staticmethod
def _unsubscribe_received(_con, stanza): def _unsubscribe_received(_con, _stanza, properties):
log.info('Received Unsubscribe: %s', stanza.getFrom()) log.info('Received Unsubscribe: %s', properties.jid)
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
def _unsubscribed_received(self, _con, stanza): def _unsubscribed_received(self, _con, _stanza, properties):
from_ = stanza.getFrom() log.info('Received Unsubscribed: %s', properties.jid)
jid = from_.getStripped()
log.info('Received Unsubscribed: %s', from_)
app.nec.push_incoming_event(NetworkEvent( app.nec.push_incoming_event(NetworkEvent(
'unsubscribed-presence-received', 'unsubscribed-presence-received',
conn=self._con, jid=jid)) conn=self._con, jid=properties.jid.getBare()))
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
def subscribed(self, jid): def subscribed(self, jid):

View File

@ -152,7 +152,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
def _on_remove_service(self, jid): def _on_remove_service(self, jid):
self.roster.delItem(jid) self.roster.delItem(jid)
# 'NOTIFY' (account, (jid, status, status message, resource, priority, # 'NOTIFY' (account, (jid, status, status message, resource, priority,
# keyID, timestamp, contact_nickname)) # keyID, timestamp))
app.nec.push_incoming_event(ZeroconfPresenceReceivedEvent( app.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
None, conn=self, fjid=jid, show='offline', status='')) None, conn=self, fjid=jid, show='offline', status=''))

View File

@ -331,7 +331,7 @@ class Interface:
def handle_event_presence(self, obj): def handle_event_presence(self, obj):
# 'NOTIFY' (account, (jid, status, status message, resource, # 'NOTIFY' (account, (jid, status, status message, resource,
# priority, # keyID, timestamp, contact_nickname)) # priority, # keyID, timestamp))
# #
# Contact changed show # Contact changed show
account = obj.conn.name account = obj.conn.name

View File

@ -366,8 +366,7 @@ class GajimRemote(Server):
else: else:
return return
self.raise_signal(event, (obj.conn.name, [obj.jid, obj.show, self.raise_signal(event, (obj.conn.name, [obj.jid, obj.show,
obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp, obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp]))
obj.contact_nickname]))
def on_subscribe_presence_received(self, obj): def on_subscribe_presence_received(self, obj):
self.raise_signal('Subscribe', (obj.conn.name, [obj.jid, obj.status, self.raise_signal('Subscribe', (obj.conn.name, [obj.jid, obj.status,

View File

@ -720,14 +720,7 @@ class RosterWindow:
return return
if jid == app.get_jid_from_account(account): if jid == app.get_jid_from_account(account):
show_self_contact = app.config.get('show_self_contact') return self._add_self_contact(account)
if show_self_contact == 'never':
return
if (contact.resource != app.connections[account].server_resource \
and show_self_contact == 'when_other_resource') or \
show_self_contact == 'always':
return self._add_self_contact(account)
return
is_observer = contact.is_observer() is_observer = contact.is_observer()
if is_observer: if is_observer:
@ -1871,13 +1864,13 @@ class RosterWindow:
'contacts': {}} 'contacts': {}}
if account not in app.groups: if account not in app.groups:
app.groups[account] = {} app.groups[account] = {}
if app.config.get('show_self_contact') == 'always':
self_jid = app.get_jid_from_account(account) self_jid = app.get_jid_from_account(account)
if app.connections[account].server_resource: if app.connections[account].server_resource:
self_jid += '/' + app.connections[account].server_resource self_jid += '/' + app.connections[account].server_resource
array[self_jid] = {'name': app.nicks[account], array[self_jid] = {'name': app.nicks[account],
'groups': ['self_contact'], 'subscription': 'both', 'groups': ['self_contact'], 'subscription': 'both',
'ask': 'none'} 'ask': 'none'}
# .keys() is needed # .keys() is needed
for jid in list(array.keys()): for jid in list(array.keys()):
@ -2212,10 +2205,7 @@ class RosterWindow:
elif contact.jid == app.get_jid_from_account(account) and \ elif contact.jid == app.get_jid_from_account(account) and \
show in ('offline', 'error'): show in ('offline', 'error'):
if app.config.get('show_self_contact') != 'never': self.remove_contact(contact.jid, account, backend=True)
# SelfContact went offline. Remove him when last pending
# message was read
self.remove_contact(contact.jid, account, backend=True)
uf_show = helpers.get_uf_show(show) uf_show = helpers.get_uf_show(show)
@ -2249,13 +2239,12 @@ class RosterWindow:
if account not in app.contacts.get_accounts(): if account not in app.contacts.get_accounts():
return return
child_iterA = self._get_account_iter(account, self.model) child_iterA = self._get_account_iter(account, self.model)
if app.config.get('show_self_contact') == 'always': self_resource = app.connections[account].server_resource
self_resource = app.connections[account].server_resource self_contact = app.contacts.get_contact(account,
self_contact = app.contacts.get_contact(account, app.get_jid_from_account(account), resource=self_resource)
app.get_jid_from_account(account), resource=self_resource) if self_contact:
if self_contact: status = app.connections[account].status
status = app.connections[account].status self.chg_contact_status(self_contact, show, status, account)
self.chg_contact_status(self_contact, show, status, account)
self.set_account_status_icon(account) self.set_account_status_icon(account)
if show == 'offline': if show == 'offline':
if self.quit_on_next_offline > -1: if self.quit_on_next_offline > -1:
@ -2570,8 +2559,7 @@ class RosterWindow:
GLib.timeout_add_seconds(5, self.remove_to_be_removed, GLib.timeout_add_seconds(5, self.remove_to_be_removed,
jid, account) jid, account)
if obj.need_redraw: self.draw_contact(jid, account)
self.draw_contact(jid, account)
if app.jid_is_transport(jid) and jid in jid_list: if app.jid_is_transport(jid) and jid in jid_list:
# It must be an agent # It must be an agent
@ -2579,7 +2567,7 @@ class RosterWindow:
self.draw_contact(jid, account) self.draw_contact(jid, account)
self.draw_group(_('Transports'), account) self.draw_group(_('Transports'), account)
if obj.contact and obj.need_redraw: if obj.contact:
self.chg_contact_status(obj.contact, obj.show, obj.status, account) self.chg_contact_status(obj.contact, obj.show, obj.status, account)
if obj.popup: if obj.popup:
@ -2598,20 +2586,20 @@ class RosterWindow:
self.fire_up_unread_messages_events(obj.conn.name) self.fire_up_unread_messages_events(obj.conn.name)
else: else:
# add self contact # add self contact
if app.config.get('show_self_contact') == 'always': account = obj.conn.name
account = obj.conn.name self_jid = app.get_jid_from_account(account)
self_jid = app.get_jid_from_account(account) if self_jid not in app.contacts.get_jid_list(account):
if self_jid not in app.contacts.get_jid_list(account): resource = ''
resource = '' if app.connections[account].server_resource:
if app.connections[account].server_resource: resource = app.connections[account].server_resource
resource = app.connections[account].server_resource sha = app.config.get_per('accounts', account, 'avatar_sha')
sha = app.config.get_per('accounts', account, 'avatar_sha') contact = app.contacts.create_contact(
contact = app.contacts.create_contact( jid=self_jid, account=account, name=app.nicks[account],
jid=self_jid, account=account, name=app.nicks[account], groups=['self_contact'], show='offline', sub='both',
groups=['self_contact'], show='offline', sub='both', ask='none', resource=resource, avatar_sha=sha)
ask='none', resource=resource, avatar_sha=sha) app.contacts.add_contact(account, contact)
app.contacts.add_contact(account, contact) self.add_contact(self_jid, account)
self.add_contact(self_jid, account)
if app.config.get('remember_opened_chat_controls'): if app.config.get('remember_opened_chat_controls'):
account = obj.conn.name account = obj.conn.name
controls = app.config.get_per( controls = app.config.get_per(