Changeset 118:a70736af32c3


Ignore:
Timestamp:
Oct 20, 2008, 8:37:06 PM (13 years ago)
Author:
Christopher Zorn <tofu@…>
Branch:
wokkel-muc-client-support-24
Convert:
svn:b33ecbfc-034c-dc11-8662-000475d9059e/branches/wokkel-muc-client-support-24@114
Message:

add timeouts and a test for a user leaving a room

Location:
wokkel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wokkel/muc.py

    r117 r118  
    1414from zope.interface import implements
    1515
    16 from twisted.internet import defer
     16from twisted.internet import defer, reactor
    1717from twisted.words.protocols.jabber import jid, error, xmlstream
    1818from twisted.words.xish import domish
     
    8787STATUS_CODE_CREATED = 201
    8888
     89DEFER_TIMEOUT = 30 # basic timeout is 30 seconds
    8990
    9091class MUCError(error.StanzaError):
     
    341342            x['role'] = role
    342343
     344class UnavailableUserPresence(xmppim.UnavailablePresence):
     345    """
     346    This behaves like an object providing L{domish.IElement}.
     347
     348    """
     349
     350    def __init__(self, to=None, type=None, frm=None, affiliation=None, role=None):
     351        xmppim.UnavailablePresence.__init__(self, to, type)
     352        if frm:
     353            self['from'] = frm
     354        # add muc elements
     355        x = self.addElement('x', NS_MUC_USER)
     356        if affiliation:
     357            x['affiliation'] = affiliation
     358        if role:
     359            x['role'] = role
     360
    343361
    344362class PasswordPresence(BasicPresence):
     
    388406    rooms = {}
    389407
     408    timeout = None
     409
     410    _deferreds = []
     411
    390412    def connectionInitialized(self):
    391413        self.xmlstream.addObserver(PRESENCE+"[not(@type) or @type='available']/x", self._onXPresence)
     
    412434        """
    413435        """
     436
    414437        if not prs.hasAttribute('from'):
    415438            return
     
    601624        return getattr(iq,'query', None)
    602625       
     626
     627    def sendDeferred(self,  obj, timeout):
     628        """ Send data or a domish element, adding a deferred with a timeout.
     629        """
     630        d = defer.Deferred()
     631        self._deferreds.append(d)
     632
     633
     634        def onTimeout():
     635            i = 0
     636            for xd in self._deferreds:
     637                if d == xd:
     638                    self._deferreds.pop(i)
     639                    d.errback(xmlstream.TimeoutError("Timeout waiting for response."))
     640                i += 1
     641
     642        call = reactor.callLater(timeout, onTimeout)
     643       
     644        def cancelTimeout(result):
     645            if call.active():
     646                call.cancel()
     647
     648            return result
     649
     650        d.addBoth(cancelTimeout)
     651
     652        self.xmlstream.send(obj)
     653        return d
     654
    603655    def disco(self, entity, type='info'):
    604656        """Send disco queries to a XMPP entity
     
    649701       
    650702        """
    651         d = defer.Deferred()
    652703        r = Room(room, server, nick, state='joining')
    653704        self._setRoom(r)
    654705 
    655706        p = BasicPresence(to=r.entity_id)
    656         # p['from'] = self.jid.full()
    657         self.xmlstream.send(p)
     707        d = self.sendDeferred(p, timeout=DEFER_TIMEOUT)
    658708
    659709        # add observer for joining the room
     
    685735        """
    686736
    687         d = defer.Deferred()
     737       
    688738        r = self._getRoom(room_jid)
    689739        if r is None:
     
    693743        # make sure we call the method to generate the new entity xmpp id
    694744        p = BasicPresence(to=r.entityId())
    695         self.xmlstream.send(p)
     745        d = self.sendDeferred(p, timeout=DEFER_TIMEOUT)
    696746
    697747        # add observer for joining the room
     
    706756        """
    707757        """
    708         d = defer.Deferred()
    709 
    710758        r = self._getRoom(room_jid)
    711759 
    712760        p = xmppim.UnavailablePresence(to=r.entity_id)
    713         # p['from'] = self.jid.full()
    714         self.xmlstream.send(p)
    715 
     761
     762        d = self.sendDeferred(p, timeout=DEFER_TIMEOUT)
    716763        # add observer for joining the room
    717764        self.xmlstream.addOnetimeObserver(PRESENCE+"[@from='%s' and @type='unavailable']" % (r.entity_id.full()),
  • wokkel/test/test_muc.py

    r117 r118  
    205205       
    206206
     207    def test_userPartsRoom(self):
     208        """An entity leaves the room, a presence of type unavailable is received by the client.
     209        """
     210
     211        p = muc.UnavailableUserPresence()
     212        p['to'] = self.user_jid.full()
     213        p['from'] = self.room_jid.full()
     214
     215        # create a room
     216        self._createRoom()
     217        # add user to room
     218        u = muc.User(self.room_jid.resource)
     219
     220        room = self.protocol._getRoom(self.room_jid)
     221        room.addUser(u)
     222
     223        def userPresence(room, user):
     224            self.failUnless(room.name==self.test_room, 'Wrong room name')
     225            self.failUnless(room.inRoster(user)==False, 'User in roster')
     226                           
     227        d, self.protocol.userLeftRoom = calledAsync(userPresence)
     228        self.stub.send(p)
     229        return d
     230       
     231
    207232    def test_ban(self):
    208233        """Ban an entity in a room.
Note: See TracChangeset for help on using the changeset viewer.