Prevent roster_update from firing twice after retrieving the roster.
This commit is contained in:
parent
9f855b9679
commit
7734aee7ad
2 changed files with 26 additions and 27 deletions
|
@ -20,7 +20,7 @@ from sleekxmpp.stanza import StreamFeatures
|
||||||
from sleekxmpp.basexmpp import BaseXMPP
|
from sleekxmpp.basexmpp import BaseXMPP
|
||||||
from sleekxmpp.exceptions import XMPPError
|
from sleekxmpp.exceptions import XMPPError
|
||||||
from sleekxmpp.xmlstream import XMLStream
|
from sleekxmpp.xmlstream import XMLStream
|
||||||
from sleekxmpp.xmlstream.matcher import MatchXPath
|
from sleekxmpp.xmlstream.matcher import StanzaPath, MatchXPath
|
||||||
from sleekxmpp.xmlstream.handler import Callback
|
from sleekxmpp.xmlstream.handler import Callback
|
||||||
|
|
||||||
# Flag indicating if DNS SRV records are available for use.
|
# Flag indicating if DNS SRV records are available for use.
|
||||||
|
@ -103,9 +103,7 @@ class ClientXMPP(BaseXMPP):
|
||||||
self._handle_stream_features))
|
self._handle_stream_features))
|
||||||
self.register_handler(
|
self.register_handler(
|
||||||
Callback('Roster Update',
|
Callback('Roster Update',
|
||||||
MatchXPath('{%s}iq/{%s}query' % (
|
StanzaPath('iq@type=set/roster'),
|
||||||
self.default_ns,
|
|
||||||
'jabber:iq:roster')),
|
|
||||||
self._handle_roster))
|
self._handle_roster))
|
||||||
|
|
||||||
# Setup default stream features
|
# Setup default stream features
|
||||||
|
@ -230,7 +228,8 @@ class ClientXMPP(BaseXMPP):
|
||||||
response = iq.send(block, timeout, callback)
|
response = iq.send(block, timeout, callback)
|
||||||
|
|
||||||
if block:
|
if block:
|
||||||
self._handle_roster(response, request=True)
|
self.event('roster_received', response)
|
||||||
|
self._handle_roster(response)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def _handle_connected(self, event=None):
|
def _handle_connected(self, event=None):
|
||||||
|
@ -254,32 +253,28 @@ class ClientXMPP(BaseXMPP):
|
||||||
# restarting the XML stream.
|
# restarting the XML stream.
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _handle_roster(self, iq, request=False):
|
def _handle_roster(self, iq):
|
||||||
"""Update the roster after receiving a roster stanza.
|
"""Update the roster after receiving a roster stanza.
|
||||||
|
|
||||||
:param iq: The roster stanza.
|
:param iq: The roster stanza.
|
||||||
:param request: Indicates if this stanza is a response
|
|
||||||
to a request for the roster, and not an
|
|
||||||
empty acknowledgement from the server.
|
|
||||||
"""
|
"""
|
||||||
if iq['from'].bare and iq['from'].bare != self.boundjid.bare:
|
if iq['type'] == 'set':
|
||||||
raise XMPPError(condition='service-unavailable')
|
if iq['from'].bare and iq['from'].bare != self.boundjid.bare:
|
||||||
if iq['type'] == 'set' or (iq['type'] == 'result' and request):
|
raise XMPPError(condition='service-unavailable')
|
||||||
roster = self.client_roster
|
|
||||||
if iq['roster']['ver']:
|
|
||||||
roster.version = iq['roster']['ver']
|
|
||||||
for jid in iq['roster']['items']:
|
|
||||||
item = iq['roster']['items'][jid]
|
|
||||||
roster[jid]['name'] = item['name']
|
|
||||||
roster[jid]['groups'] = item['groups']
|
|
||||||
roster[jid]['from'] = item['subscription'] in ['from', 'both']
|
|
||||||
roster[jid]['to'] = item['subscription'] in ['to', 'both']
|
|
||||||
roster[jid]['pending_out'] = (item['ask'] == 'subscribe')
|
|
||||||
|
|
||||||
roster[jid].save(remove=(item['subscription'] == 'remove'))
|
roster = self.client_roster
|
||||||
|
if iq['roster']['ver']:
|
||||||
self.event('roster_received', iq)
|
roster.version = iq['roster']['ver']
|
||||||
|
for jid in iq['roster']['items']:
|
||||||
|
item = iq['roster']['items'][jid]
|
||||||
|
roster[jid]['name'] = item['name']
|
||||||
|
roster[jid]['groups'] = item['groups']
|
||||||
|
roster[jid]['from'] = item['subscription'] in ['from', 'both']
|
||||||
|
roster[jid]['to'] = item['subscription'] in ['to', 'both']
|
||||||
|
roster[jid]['pending_out'] = (item['ask'] == 'subscribe')
|
||||||
|
|
||||||
|
roster[jid].save(remove=(item['subscription'] == 'remove'))
|
||||||
|
|
||||||
self.event("roster_update", iq)
|
self.event("roster_update", iq)
|
||||||
if iq['type'] == 'set':
|
if iq['type'] == 'set':
|
||||||
iq.reply()
|
iq.reply()
|
||||||
|
|
|
@ -24,7 +24,11 @@ class TestStreamRoster(SleekTest):
|
||||||
def roster_received(iq):
|
def roster_received(iq):
|
||||||
events.append('roster_received')
|
events.append('roster_received')
|
||||||
|
|
||||||
|
def roster_update(iq):
|
||||||
|
events.append('roster_update')
|
||||||
|
|
||||||
self.xmpp.add_event_handler('roster_received', roster_received)
|
self.xmpp.add_event_handler('roster_received', roster_received)
|
||||||
|
self.xmpp.add_event_handler('roster_update', roster_update)
|
||||||
|
|
||||||
# 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', target=self.xmpp.get_roster)
|
t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
|
||||||
|
@ -62,8 +66,8 @@ class TestStreamRoster(SleekTest):
|
||||||
# Give the event queue time to process.
|
# Give the event queue time to process.
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
|
|
||||||
self.failUnless('roster_received' in events,
|
self.failUnless(events == ['roster_received', 'roster_update'],
|
||||||
"Roster received event not triggered: %s" % events)
|
"Wrong roster events fired: %s" % events)
|
||||||
|
|
||||||
def testRosterSet(self):
|
def testRosterSet(self):
|
||||||
"""Test handling pushed roster updates."""
|
"""Test handling pushed roster updates."""
|
||||||
|
|
Loading…
Reference in a new issue