summaryrefslogtreecommitdiff
path: root/src/core.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/core.py')
-rw-r--r--src/core.py187
1 files changed, 85 insertions, 102 deletions
diff --git a/src/core.py b/src/core.py
index 627f7f5c..f7447863 100644
--- a/src/core.py
+++ b/src/core.py
@@ -92,6 +92,9 @@ class Core(object):
self.events = events.EventHandler()
self.xmpp = singleton.Singleton(connection.Connection)
self.xmpp.core = self
+ roster.set_node(self.xmpp.client_roster)
+ roster.set_mucs(self.xmpp.plugin['xep_0045'].rooms)
+ roster.set_self_jid(self.xmpp.boundjid.bare)
self.paused = False
self.remote_fifo = None
# a unique buffer used to store global informations
@@ -194,7 +197,10 @@ class Core(object):
self.xmpp.add_event_handler("got_offline" , self.on_got_offline)
self.xmpp.add_event_handler("roster_update", self.on_roster_update)
self.xmpp.add_event_handler("changed_status", self.on_presence)
- self.xmpp.add_event_handler("changed_subscription", self.on_changed_subscription)
+ self.xmpp.add_event_handler("roster_subscription_request", self.on_subscription_request)
+ self.xmpp.add_event_handler("roster_subscription_authorized", self.on_subscription_authorized)
+ self.xmpp.add_event_handler("roster_subscription_remove", self.on_subscription_remove)
+ self.xmpp.add_event_handler("roster_subscription_removed", self.on_subscription_removed)
self.xmpp.add_event_handler("message_xform", self.on_data_form)
self.xmpp.add_event_handler("chatstate_active", self.on_chatstate_active)
self.xmpp.add_event_handler("chatstate_composing", self.on_chatstate_composing)
@@ -462,7 +468,7 @@ class Core(object):
if txt.endswith(' '):
n += 1
if n == 2:
- return the_input.auto_completion([contact.bare_jid for contact in roster.get_contacts()], '')
+ return the_input.auto_completion([jid for jid in roster.jids()], '')
elif n == 3:
rooms = []
for tab in self.tabs:
@@ -597,53 +603,37 @@ class Core(object):
def on_got_offline(self, presence):
jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
logger.log_roster_change(jid.bare, 'got offline')
- if not contact:
- return
- resource = contact.get_resource_by_fulljid(jid.full)
- if not resource:
- return
# If a resource got offline, display the message in the conversation with this
# precise resource.
- self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x191}offline' % (resource.jid.full))
- contact.remove_resource(resource)
- # Display the message in the conversation with the bare JID only if that was
- # the only resource online (i.e. now the contact is completely disconnected)
- if not contact.get_highest_priority_resource(): # No resource left: that was the last one
- self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x191}offline' % (jid.bare))
- self.information('\x193}%s \x195}is \x191}offline' % (resource.jid.bare), "Roster")
+ if jid.resource:
+ self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x191}offline' % (jid.full))
+ self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x191}offline' % (jid.bare))
+ self.information('\x193}%s \x195}is \x191}offline' % (jid.bare), 'Roster')
if isinstance(self.current_tab(), tabs.RosterInfoTab):
self.refresh_window()
def on_got_online(self, presence):
jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
- if not contact:
- # Todo, handle presence comming from contacts not in roster
+ contact = roster[jid.bare]
+ if contact is None:
+ # Todo, handle presence coming from contacts not in roster
return
logger.log_roster_change(jid.bare, 'got online')
- resource = contact.get_resource_by_fulljid(jid.full)
- assert not resource
- resource = Resource(jid.full)
+ resource = Resource(jid.full, {
+ 'priority': presence.get_priority() or 0,
+ 'status': presence['status'],
+ 'show': presence['show'],
+ })
self.events.trigger('normal_presence', presence, resource)
- status = presence['type']
- status_message = presence['status']
- priority = presence.getPriority() or 0
- resource.status = status_message
- resource.presence = status
- resource.priority = priority
self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x194}online' % (jid.full))
- if not contact.get_highest_priority_resource():
- # No connected resource yet: the user's just connecting
- if time.time() - self.connection_time > 12:
- # We do not display messages if we recently logged in
- if status_message:
- self.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (resource.jid.bare, status_message), "Roster")
- else:
- self.information("\x193}%s \x195}is \x194}online\x195}" % resource.jid.bare, "Roster")
+ if time.time() - self.connection_time > 20:
+ # We do not display messages if we recently logged in
+ if presence['status']:
+ self.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (resource.jid.bare, presence['status']), "Roster")
+ else:
+ self.information("\x193}%s \x195}is \x194}online\x195}" % resource.jid.bare, "Roster")
self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x194}online' % (jid.bare))
- contact.add_resource(resource)
if isinstance(self.current_tab(), tabs.RosterInfoTab):
self.refresh_window()
@@ -693,7 +683,7 @@ class Core(object):
self.information(_("Your JID is %s") % self.xmpp.boundjid.full)
if not self.xmpp.anon:
# request the roster
- self.xmpp.getRoster()
+ self.xmpp.get_roster()
# send initial presence
if config.get('send_initial_presence', 'true').lower() == 'true':
pres = self.xmpp.make_presence()
@@ -860,8 +850,8 @@ class Core(object):
conversation = self.get_tab_of_conversation_with_jid(jid, create=True)
self.events.trigger('conversation_msg', message, conversation)
body = xhtml.get_body_from_message_stanza(message)
- if roster.get_contact_by_jid(jid.bare):
- remote_nick = roster.get_contact_by_jid(jid.bare).name or jid.user
+ if jid.bare in roster:
+ remote_nick = roster[jid.bare].name or jid.user
else:
remote_nick = jid.user
delay_tag = message.find('{urn:xmpp:delay}delay')
@@ -889,20 +879,10 @@ class Core(object):
def on_presence(self, presence):
jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
- if not contact:
- resource = None
- else:
- resource = contact.get_resource_by_fulljid(jid.full)
- self.events.trigger('normal_presence', presence, resource)
- if not resource:
+ contact = roster[jid.bare]
+ self.events.trigger('normal_presence', presence, contact[jid.full])
+ if contact is None:
return
- status = presence['type']
- status_message = presence['status']
- priority = presence.getPriority() or 0
- resource.presence = status
- resource.priority = priority
- resource.status = status_message
tab = self.get_tab_of_conversation_with_jid(jid, create=False)
if isinstance(self.current_tab(), tabs.RosterInfoTab):
self.refresh_window()
@@ -912,60 +892,64 @@ class Core(object):
def on_roster_update(self, iq):
"""
- A subscription changed, or we received a roster item
- after a roster request, etc
- """
- for item in iq.findall('{jabber:iq:roster}query/{jabber:iq:roster}item'):
- jid = item.attrib['jid']
- contact = roster.get_contact_by_jid(jid)
- if not contact:
- contact = Contact(jid)
- roster.add_contact(contact, jid)
- if 'ask' in item.attrib:
- contact.ask = item.attrib['ask']
- else:
- contact.ask = None
- if 'name' in item.attrib:
- contact.name = item.attrib['name']
+ The roster was received.
+ """
+ for item in iq['roster']:
+ jid = item['jid']
+ if item['subscription'] == 'remove':
+ del roster[jid]
else:
- contact.name = None
- if item.attrib['subscription']:
- contact.subscription = item.attrib['subscription']
- groups = item.findall('{jabber:iq:roster}group')
- roster.edit_groups_of_contact(contact, [group.text for group in groups])
- if item.attrib['subscription'] == 'remove':
- roster.remove_contact(contact.bare_jid)
+ roster.update_contact_groups(jid)
if isinstance(self.current_tab(), tabs.RosterInfoTab):
self.refresh_window()
- def on_changed_subscription(self, presence):
- """
- Triggered whenever a presence stanza with a type of subscribe, subscribed, unsubscribe, or unsubscribed is received.
- """
+ def on_subscription_request(self, presence):
+ """subscribe received"""
jid = presence['from'].bare
- contact = roster.get_contact_by_jid(jid)
- if presence['type'] == 'subscribe':
- if not contact:
- contact = Contact(jid)
- roster.add_contact(contact, jid)
- log.debug("CONTACT: %s", contact)
- if contact.subscription in ('from', 'both'):
- log.debug('FROM OR BOTH')
- return
- elif contact.subscription in ('to'):
- log.debug('TO')
- self.xmpp.sendPresence(pto=jid, ptype='subscribed')
- self.xmpp.sendPresence(pto=jid, ptype='')
- return
- roster.edit_groups_of_contact(contact, [])
- contact.ask = 'asked'
+ contact = roster[jid]
+ if contact.subscription in ('from', 'both'):
+ return
+ elif contact.subscription == 'to':
+ self.xmpp.sendPresence(pto=jid, ptype='subscribed')
+ self.xmpp.sendPresence(pto=jid)
+ else:
+ roster.update_contact_groups(contact)
+ contact.pending_in = True
+ self.information('%s wants to subscribe to your presence' % jid, 'Roster')
self.get_tab_by_number(0).state = 'highlight'
- self.information('%s wants to subscribe to your presence'%jid, 'Roster')
- elif presence['type'] == 'unsubscribed':
- self.information('%s unsubscribed you from his presence'%jid, 'Roster')
- elif presence['type'] == 'unsubscribe':
- self.information('%s unsubscribed from your presence'%jid, 'Roster')
+ if isinstance(self.current_tab(), tabs.RosterInfoTab):
+ self.refresh_window()
+
+ def on_subscription_authorized(self, presence):
+ """subscribed received"""
+ jid = presence['from'].bare
+ contact = roster[jid]
+ if contact.pending_out:
+ contact.pending_out = False
+ if isinstance(self.current_tab(), tabs.RosterInfoTab):
+ self.refresh_window()
+
+ def on_subscription_remove(self, presence):
+ """unsubscribe received"""
+ jid = presence['from'].bare
+ contact = roster[jid]
+ if contact.subscription in ('to', 'both'):
+ self.information('%s does not want to receive your status anymore.' % jid, 'Roster')
+ self.get_tab_by_number(0).state = 'highlight'
+ if isinstance(self.current_tab(), tabs.RosterInfoTab):
+ self.refresh_window()
+ def on_subscription_removed(self, presence):
+ """unsubscribed received"""
+ jid = presence['from'].bare
+ contact = roster[jid]
+ if contact.subscription in ('both', 'from'):
+ self.information('%s does not want you to receive his status anymore.'%jid, 'Roster')
+ self.get_tab_by_number(0).state = 'highlight'
+ elif contact.pending_out:
+ self.information('%s rejected your contact proposal.' % jid, 'Roster')
+ self.get_tab_by_number(0).state = 'highlight'
+ contact.pending_out = False
if isinstance(self.current_tab(), tabs.RosterInfoTab):
self.refresh_window()
@@ -1501,7 +1485,7 @@ class Core(object):
if text.endswith(' '):
n += 1
if n == 2:
- return the_input.auto_completion([contact.bare_jid for contact in roster.get_contacts()], '')
+ return the_input.auto_completion([jid for jid in roster.jids()], '')
elif n == 3:
return the_input.auto_completion([status for status in possible_show], '')
@@ -1761,7 +1745,7 @@ class Core(object):
n = len(the_input.get_text().split())
if n > 2 or (n == 2 and the_input.get_text().endswith(' ')):
return
- return the_input.auto_completion([contact.bare_jid for contact in roster.get_contacts()], '', quotify=False)
+ return the_input.auto_completion([jid for jid in roster.jids()], '', quotify=False)
def completion_list(self, the_input):
muc_serv_list = []
@@ -2218,7 +2202,6 @@ class Core(object):
for tab in self.tabs:
if isinstance(tab, tabs.MucTab) and tab.joined:
tab.command_part(msg)
- roster.empty()
self.save_config()
# Ugly fix thanks to gmail servers
self.xmpp.disconnect(reconnect)