From c0074f95b160f4766168ed2cae955709bf38d124 Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Wed, 11 Jan 2012 16:39:55 -0800
Subject: update_caps() can now do presence broadcasting.

As part of adding this feature:

    - fixed bug in update_caps() not assigning verstrings
    - fixed xep_0004 typo
    - can now use None as a roster key which will map to boundjid.bare
    - fixed using JID objects in disco node handlers
    - fixed failing test related to get_roster

Several of these bugs I've fixed before, so I either didn't push them
earlier, or I clobbered something when merging. *shrug*
---
 sleekxmpp/plugins/xep_0004/stanza/field.py |  2 +-
 sleekxmpp/plugins/xep_0030/disco.py        |  4 ++++
 sleekxmpp/plugins/xep_0115/caps.py         | 24 ++++++++++++++++++++----
 sleekxmpp/roster/multi.py                  |  2 ++
 sleekxmpp/roster/single.py                 | 11 +++++++++++
 5 files changed, 38 insertions(+), 5 deletions(-)

(limited to 'sleekxmpp')

diff --git a/sleekxmpp/plugins/xep_0004/stanza/field.py b/sleekxmpp/plugins/xep_0004/stanza/field.py
index 6814e157..8156997c 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/field.py
+++ b/sleekxmpp/plugins/xep_0004/stanza/field.py
@@ -93,7 +93,7 @@ class FormField(ElementBase):
                 if valXML.text is None:
                     valXML.text = ''
                 values.append(valXML.text)
-            if self._type == 'text-multi' and condense:
+            if self._type == 'text-multi' and convert:
                 values = "\n".join(values)
             return values
         else:
diff --git a/sleekxmpp/plugins/xep_0030/disco.py b/sleekxmpp/plugins/xep_0030/disco.py
index 10f9ef4e..58f4f20c 100644
--- a/sleekxmpp/plugins/xep_0030/disco.py
+++ b/sleekxmpp/plugins/xep_0030/disco.py
@@ -357,6 +357,7 @@ class xep_0030(base_plugin):
             else:
                 if str(jid) == str(self.xmpp.boundjid):
                     local = True
+            jid = jid.full
 
         if local or jid in (None, ''):
             log.debug("Looking up local disco#info data " + \
@@ -626,6 +627,9 @@ class xep_0030(base_plugin):
             node  -- The node requested.
             data  -- Optional, custom data to pass to the handler.
         """
+        if isinstance(jid, JID):
+            jid = jid.full
+
         if jid in (None, ''):
             if self.xmpp.is_component:
                 jid = self.xmpp.boundjid.full
diff --git a/sleekxmpp/plugins/xep_0115/caps.py b/sleekxmpp/plugins/xep_0115/caps.py
index d3e62abb..289bb8d1 100644
--- a/sleekxmpp/plugins/xep_0115/caps.py
+++ b/sleekxmpp/plugins/xep_0115/caps.py
@@ -65,10 +65,11 @@ class xep_0115(base_plugin):
         self.xmpp.add_event_handler('entity_caps', self._process_caps,
                                     threaded=True)
 
-        self.xmpp.register_feature('caps',
-                self._handle_caps_feature,
-                restart=False,
-                order=10010)
+        if not self.xmpp.is_component:
+            self.xmpp.register_feature('caps',
+                    self._handle_caps_feature,
+                    restart=False,
+                    order=10010)
 
     def post_init(self):
         base_plugin.post_init(self)
@@ -256,6 +257,21 @@ class xep_0115(base_plugin):
                     info=info)
             self.cache_caps(ver, info)
             self.assign_verstring(jid, ver)
+
+            if self.broadcast:
+                # Check if we've sent directed presence. If we haven't, we
+                # can just send a normal presence stanza. If we have, then
+                # we will send presence to each contact individually so
+                # that we don't clobber existing statuses.
+                directed = False
+                for contact in self.xmpp.roster[jid]:
+                    if self.xmpp.roster[jid][contact].last_status is not None:
+                        directed = True
+                if not directed:
+                    self.xmpp.roster[jid].send_last_presence()
+                else:
+                    for contact in self.xmpp.roster[jid]:
+                        self.xmpp.roster[jid][contact].send_last_presence()
         except XMPPError:
             return
 
diff --git a/sleekxmpp/roster/multi.py b/sleekxmpp/roster/multi.py
index 36c7e2ad..28876814 100644
--- a/sleekxmpp/roster/multi.py
+++ b/sleekxmpp/roster/multi.py
@@ -68,6 +68,8 @@ class Roster(object):
         """
         if isinstance(key, JID):
             key = key.bare
+        if key is None:
+            key = self.xmpp.boundjid.bare
         if key not in self._rosters:
             self.add(key)
             self._rosters[key].auto_authorize = self.auto_authorize
diff --git a/sleekxmpp/roster/single.py b/sleekxmpp/roster/single.py
index 903333a3..c2f8e763 100644
--- a/sleekxmpp/roster/single.py
+++ b/sleekxmpp/roster/single.py
@@ -286,5 +286,16 @@ class RosterNode(object):
                 self.xmpp.event('sent_presence')
                 self.xmpp.sentpresence = True
 
+    def send_last_presence(self):
+        if self.last_status is None:
+            self.send_presence()
+        else:
+            pres = self.last_status
+            if self.xmpp.is_component:
+                pres['from'] = self.jid
+            else:
+                del pres['from']
+            pres.send()
+
     def __repr__(self):
         return repr(self._jids)
-- 
cgit v1.2.3