comparison sat_tmp/wokkel/pubsub.py @ 58:f4d569dc8e6b

wokkel/mam, wokkel/pubsub, wokkel/rsm: implemented "order-by" protoXEP (for Pubsub and MAM)
author Goffi <goffi@goffi.org>
date Sun, 06 Jan 2019 17:25:30 +0100
parents c8cb4e867897
children c8b468a96c5c
comparison
equal deleted inserted replaced
57:a1ae63fe666d 58:f4d569dc8e6b
79 NS_PUBSUB_OWNER = NS_PUBSUB + "#owner" 79 NS_PUBSUB_OWNER = NS_PUBSUB + "#owner"
80 NS_PUBSUB_NODE_CONFIG = NS_PUBSUB + "#node_config" 80 NS_PUBSUB_NODE_CONFIG = NS_PUBSUB + "#node_config"
81 NS_PUBSUB_META_DATA = NS_PUBSUB + "#meta-data" 81 NS_PUBSUB_META_DATA = NS_PUBSUB + "#meta-data"
82 NS_PUBSUB_SUBSCRIBE_OPTIONS = NS_PUBSUB + "#subscribe_options" 82 NS_PUBSUB_SUBSCRIBE_OPTIONS = NS_PUBSUB + "#subscribe_options"
83 83
84 NS_ORDER_BY = u"urn:xmpp:order-by:0"
85
84 # XPath to match pubsub requests 86 # XPath to match pubsub requests
85 PUBSUB_REQUEST = '/iq[@type="get" or @type="set"]/' + \ 87 PUBSUB_REQUEST = '/iq[@type="get" or @type="set"]/' + \
86 'pubsub[@xmlns="' + NS_PUBSUB + '" or ' + \ 88 'pubsub[@xmlns="' + NS_PUBSUB + '" or ' + \
87 '@xmlns="' + NS_PUBSUB_OWNER + '"]' 89 '@xmlns="' + NS_PUBSUB_OWNER + '"]'
88 90
296 subscriber = None 298 subscriber = None
297 subscriptionIdentifier = None 299 subscriptionIdentifier = None
298 subscriptions = None 300 subscriptions = None
299 affiliations = None 301 affiliations = None
300 notify = None 302 notify = None
303 orderBy = None
301 304
302 # Map request iq type and subelement name to request verb 305 # Map request iq type and subelement name to request verb
303 _requestVerbMap = { 306 _requestVerbMap = {
304 ('set', NS_PUBSUB, 'publish'): 'publish', 307 ('set', NS_PUBSUB, 'publish'): 'publish',
305 ('set', NS_PUBSUB, 'subscribe'): 'subscribe', 308 ('set', NS_PUBSUB, 'subscribe'): 'subscribe',
336 'affiliations': ['nodeOrNone'], 339 'affiliations': ['nodeOrNone'],
337 'create': ['nodeOrNone', 'configureOrNone'], 340 'create': ['nodeOrNone', 'configureOrNone'],
338 'default': ['default'], 341 'default': ['default'],
339 'configureGet': ['nodeOrEmpty'], 342 'configureGet': ['nodeOrEmpty'],
340 'configureSet': ['nodeOrEmpty', 'configureOrNone'], 343 'configureSet': ['nodeOrEmpty', 'configureOrNone'],
341 'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone'], 344 'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone', 'orderBy'],
342 'retract': ['node', 'notify', 'itemIdentifiers'], 345 'retract': ['node', 'notify', 'itemIdentifiers'],
343 'purge': ['node'], 346 'purge': ['node'],
344 'delete': ['node'], 347 'delete': ['node'],
345 'affiliationsGet': ['node'], 348 'affiliationsGet': ['node'],
346 'affiliationsSet': ['node', 'affiliations'], 349 'affiliationsSet': ['node', 'affiliations'],
670 def _render_notify(self, verbElement): 673 def _render_notify(self, verbElement):
671 if self.notify is not None: 674 if self.notify is not None:
672 verbElement['notify'] = "true" if self.notify else "false" 675 verbElement['notify'] = "true" if self.notify else "false"
673 676
674 677
678 def _parse_orderBy(self, verbElement):
679 pubsub_elt = verbElement.parent
680 self.orderBy = []
681 for element in pubsub_elt.elements(NS_ORDER_BY, 'order'):
682 self.orderBy.append(element['by'])
683
684
685 def _render_orderBy(self, verbElement):
686 if self.orderBy is None:
687 return
688 pubsub_elt = verbElement.parent
689 for by_attr in self.orderBy:
690 order_elt = pubsub_elt.addElement((NS_ORDER_BY,'order'))
691 order_elt['by'] = by_attr
692
693
675 def parseElement(self, element): 694 def parseElement(self, element):
676 """ 695 """
677 Parse the publish-subscribe verb and parameters out of a request. 696 Parse the publish-subscribe verb and parameters out of a request.
678 """ 697 """
679 generic.Stanza.parseElement(self, element) 698 generic.Stanza.parseElement(self, element)
705 724
706 for parameter in self._parameters[self.verb]: 725 for parameter in self._parameters[self.verb]:
707 getattr(self, '_parse_%s' % parameter)(verbElement) 726 getattr(self, '_parse_%s' % parameter)(verbElement)
708 727
709 728
710
711 def send(self, xs): 729 def send(self, xs):
712 """ 730 """
713 Send this request to its recipient. 731 Send this request to its recipient.
714 732
715 This renders all of the relevant parameters for this specific 733 This renders all of the relevant parameters for this specific
1019 request.items = items 1037 request.items = items
1020 request.sender = sender 1038 request.sender = sender
1021 return request.send(self.xmlstream) 1039 return request.send(self.xmlstream)
1022 1040
1023 1041
1024 def items(self, service, nodeIdentifier, maxItems=None, itemIdentifiers=None, 1042 def items(self, service, nodeIdentifier, maxItems=None,
1025 subscriptionIdentifier=None, sender=None): 1043 subscriptionIdentifier=None, sender=None, itemIdentifiers=None,
1044 orderBy=None):
1026 """ 1045 """
1027 Retrieve previously published items from a publish subscribe node. 1046 Retrieve previously published items from a publish subscribe node.
1028 1047
1029 @param service: The publish subscribe service that keeps the node. 1048 @param service: The publish subscribe service that keeps the node.
1030 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>} 1049 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1032 @param nodeIdentifier: The identifier of the node. 1051 @param nodeIdentifier: The identifier of the node.
1033 @type nodeIdentifier: C{unicode} 1052 @type nodeIdentifier: C{unicode}
1034 1053
1035 @param maxItems: Optional limit on the number of retrieved items. 1054 @param maxItems: Optional limit on the number of retrieved items.
1036 @type maxItems: C{int} 1055 @type maxItems: C{int}
1037
1038 @param itemIdentifiers: Identifiers of the items to be retrieved.
1039 @type itemIdentifiers: C{set}
1040 1056
1041 @param subscriptionIdentifier: Optional subscription identifier. In 1057 @param subscriptionIdentifier: Optional subscription identifier. In
1042 case the node has been subscribed to multiple times, this narrows 1058 case the node has been subscribed to multiple times, this narrows
1043 the results to the specific subscription. 1059 the results to the specific subscription.
1044 @type subscriptionIdentifier: C{unicode} 1060 @type subscriptionIdentifier: C{unicode}
1061
1062 @param itemIdentifiers: Identifiers of the items to be retrieved.
1063 @type itemIdentifiers: C{set}
1064
1065 @param orderBy: Keys to order by
1066 @type orderBy: L{list} of L{unicode}
1045 """ 1067 """
1046 request = self._request_class('items') 1068 request = self._request_class('items')
1047 request.recipient = service 1069 request.recipient = service
1048 request.nodeIdentifier = nodeIdentifier 1070 request.nodeIdentifier = nodeIdentifier
1049 if maxItems: 1071 if maxItems:
1050 request.maxItems = str(int(maxItems)) 1072 request.maxItems = str(int(maxItems))
1051 request.subscriptionIdentifier = subscriptionIdentifier 1073 request.subscriptionIdentifier = subscriptionIdentifier
1052 request.sender = sender 1074 request.sender = sender
1053 request.itemIdentifiers = itemIdentifiers 1075 request.itemIdentifiers = itemIdentifiers
1076 request.orderBy = orderBy
1054 1077
1055 def cb(iq): 1078 def cb(iq):
1056 items = [] 1079 items = []
1057 for element in iq.pubsub.items.elements(): 1080 for element in iq.pubsub.items.elements():
1058 if element.uri == NS_PUBSUB and element.name == 'item': 1081 if element.uri == NS_PUBSUB and element.name == 'item':