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*
This commit is contained in:
Lance Stout 2012-01-11 16:39:55 -08:00
parent a79ce1c35e
commit c0074f95b1
7 changed files with 41 additions and 6 deletions

View file

@ -68,6 +68,7 @@ packages = [ 'sleekxmpp',
'sleekxmpp/plugins/xep_0085', 'sleekxmpp/plugins/xep_0085',
'sleekxmpp/plugins/xep_0086', 'sleekxmpp/plugins/xep_0086',
'sleekxmpp/plugins/xep_0092', 'sleekxmpp/plugins/xep_0092',
'sleekxmpp/plugins/xep_0115',
'sleekxmpp/plugins/xep_0128', 'sleekxmpp/plugins/xep_0128',
'sleekxmpp/plugins/xep_0199', 'sleekxmpp/plugins/xep_0199',
'sleekxmpp/plugins/xep_0202', 'sleekxmpp/plugins/xep_0202',

View file

@ -93,7 +93,7 @@ class FormField(ElementBase):
if valXML.text is None: if valXML.text is None:
valXML.text = '' valXML.text = ''
values.append(valXML.text) values.append(valXML.text)
if self._type == 'text-multi' and condense: if self._type == 'text-multi' and convert:
values = "\n".join(values) values = "\n".join(values)
return values return values
else: else:

View file

@ -357,6 +357,7 @@ class xep_0030(base_plugin):
else: else:
if str(jid) == str(self.xmpp.boundjid): if str(jid) == str(self.xmpp.boundjid):
local = True local = True
jid = jid.full
if local or jid in (None, ''): if local or jid in (None, ''):
log.debug("Looking up local disco#info data " + \ log.debug("Looking up local disco#info data " + \
@ -626,6 +627,9 @@ class xep_0030(base_plugin):
node -- The node requested. node -- The node requested.
data -- Optional, custom data to pass to the handler. data -- Optional, custom data to pass to the handler.
""" """
if isinstance(jid, JID):
jid = jid.full
if jid in (None, ''): if jid in (None, ''):
if self.xmpp.is_component: if self.xmpp.is_component:
jid = self.xmpp.boundjid.full jid = self.xmpp.boundjid.full

View file

@ -65,10 +65,11 @@ class xep_0115(base_plugin):
self.xmpp.add_event_handler('entity_caps', self._process_caps, self.xmpp.add_event_handler('entity_caps', self._process_caps,
threaded=True) threaded=True)
self.xmpp.register_feature('caps', if not self.xmpp.is_component:
self._handle_caps_feature, self.xmpp.register_feature('caps',
restart=False, self._handle_caps_feature,
order=10010) restart=False,
order=10010)
def post_init(self): def post_init(self):
base_plugin.post_init(self) base_plugin.post_init(self)
@ -256,6 +257,21 @@ class xep_0115(base_plugin):
info=info) info=info)
self.cache_caps(ver, info) self.cache_caps(ver, info)
self.assign_verstring(jid, ver) 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: except XMPPError:
return return

View file

@ -68,6 +68,8 @@ class Roster(object):
""" """
if isinstance(key, JID): if isinstance(key, JID):
key = key.bare key = key.bare
if key is None:
key = self.xmpp.boundjid.bare
if key not in self._rosters: if key not in self._rosters:
self.add(key) self.add(key)
self._rosters[key].auto_authorize = self.auto_authorize self._rosters[key].auto_authorize = self.auto_authorize

View file

@ -286,5 +286,16 @@ class RosterNode(object):
self.xmpp.event('sent_presence') self.xmpp.event('sent_presence')
self.xmpp.sentpresence = True 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): def __repr__(self):
return repr(self._jids) return repr(self._jids)

View file

@ -125,7 +125,8 @@ class TestStreamRoster(SleekTest):
# Since get_roster blocks, we need to run it in a thread. # Since get_roster blocks, we need to run it in a thread.
t = threading.Thread(name='get_roster', t = threading.Thread(name='get_roster',
target=self.xmpp.get_roster, target=self.xmpp.get_roster,
kwargs={str('callback'): roster_callback}) kwargs={str('block'): False,
str('callback'): roster_callback})
t.start() t.start()
self.send(""" self.send("""