diff options
Diffstat (limited to 'src/core.py')
-rw-r--r-- | src/core.py | 187 |
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) |