Ignore:
Timestamp:
May 9, 2012, 2:24:28 PM (8 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add support for roster versioning.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wokkel/xmppim.py

    r172 r173  
    749749    @ivar item: Roster item to be set or pushed.
    750750    @type item: L{RosterItem}.
     751
     752    @ivar version: Roster version identifier for roster pushes and
     753        retrieving the roster as a delta from a known cached version. This
     754        should only be set if the recipient is known to support roster
     755        versioning.
     756    @type version: C{unicode}
    751757    """
    752758    item = None
     759    version = None
    753760
    754761    def parseRequest(self, element):
     762        self.version = element.getAttribute('ver')
     763
    755764        for child in element.elements(NS_ROSTER, 'item'):
    756765            self.item = RosterItem.fromElement(child)
     
    761770        element = Request.toElement(self)
    762771        query = element.addElement((NS_ROSTER, 'query'))
     772        if self.version is not None:
     773            query['ver'] = self.version
    763774        if self.item:
    764775            query.addChild(self.item.toElement())
     
    775786    result in a C{'service-unavailable'} error being sent in return.
    776787    """
     788
     789
     790
     791class Roster(dict):
     792    """
     793    In-memory roster container.
     794
     795    This provides a roster as a mapping from L{JID} to L{RosterItem}. If
     796    roster versioning is used, the C{version} attribute holds the version
     797    identifier for this version of the roster.
     798
     799    @ivar version: Roster version identifier.
     800    @type version: C{unicode}.
     801    """
     802
     803    version = None
    777804
    778805
     
    797824    pushes from untrusted senders.
    798825
     826    If roster versioning is supported by the server, the roster and
     827    subsequent pushes are annotated with a version identifier. This can be
     828    used to cache the roster on the client side. Upon reconnect, the client
     829    can request the roster with the version identifier of the cached version.
     830    The server may then choose to only send roster pushes for the changes
     831    since that version, instead of a complete roster.
     832
    799833    @cvar allowAnySender: Flag to allow roster pushes from any sender.
    800834        C{False} by default.
     
    810844
    811845
    812     def getRoster(self):
     846    def getRoster(self, version=None):
    813847        """
    814848        Retrieve contact list.
     849
     850        The returned deferred fires with the result of the roster request as
     851        L{Roster}, a mapping from contact JID to L{RosterItem}.
     852
     853        If roster versioning is supported, the recipient responds with either
     854        a the complete roster or with an empty result. In case of complete
     855        roster, the L{Roster} is annotated with a C{version} attribute that
     856        holds the version identifier for this version of the roster. This
     857        identifier should be used for caching.
     858
     859        If the recipient responds with an empty result, the returned deferred
     860        fires with C{None}. This indicates that any roster modifications
     861        since C{version} will be sent as roster pushes.
     862
     863        Note that the empty result (C{None}) is different from an empty
     864        roster (L{Roster} with no items).
     865
     866        @param version: Optional version identifier of the last cashed
     867            version of the roster. This shall only be set if the recipient is
     868            known to support roster versioning. If there is no (valid) cached
     869            version of the roster, but roster versioning is desired,
     870            C{version} should be set to the empty string (C{u''}).
     871        @type version: C{unicode}
    815872
    816873        @return: Roster as a mapping from L{JID} to L{RosterItem}.
     
    819876
    820877        def processRoster(result):
    821             roster = {}
    822             for element in domish.generateElementsQNamed(result.query.children,
    823                                                          'item', NS_ROSTER):
    824                 item = RosterItem.fromElement(element)
    825                 roster[item.entity] = item
    826 
    827             return roster
     878            if result.query is not None:
     879                roster = Roster()
     880                roster.version = result.query.getAttribute('ver')
     881                for element in result.query.elements(NS_ROSTER, 'item'):
     882                    item = RosterItem.fromElement(element)
     883                    roster[item.entity] = item
     884                return roster
     885            else:
     886                return None
    828887
    829888        request = RosterRequest(stanzaType='get')
     889        request.version = version
    830890        d = self.request(request)
    831891        d.addCallback(processRoster)
Note: See TracChangeset for help on using the changeset viewer.