comparison sat_tmp/wokkel/pubsub.py @ 69:0721b6254c9e

python 3 port: - applied 2to3 - replaced zope's implements by @implementer decorator - replaced references to python2 by python3
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 18:58:11 +0200
parents 0bb020e9fd47
children ab556b1c2ca4
comparison
equal deleted inserted replaced
68:042a926cf3b2 69:0721b6254c9e
54 54
55 This protocol is specified in 55 This protocol is specified in
56 U{XEP-0060<http://xmpp.org/extensions/xep-0060.html>}. 56 U{XEP-0060<http://xmpp.org/extensions/xep-0060.html>}.
57 """ 57 """
58 58
59 from zope.interface import implements 59 from zope.interface import implementer
60 60
61 from twisted.internet import defer 61 from twisted.internet import defer
62 from twisted.python import log 62 from twisted.python import log
63 from twisted.words.protocols.jabber import jid, error 63 from twisted.words.protocols.jabber import jid, error
64 from twisted.words.xish import domish 64 from twisted.words.xish import domish
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" 84 NS_ORDER_BY = "urn:xmpp:order-by:0"
85 85
86 # XPath to match pubsub requests 86 # XPath to match pubsub requests
87 PUBSUB_REQUEST = '/iq[@type="get" or @type="set"]/' + \ 87 PUBSUB_REQUEST = '/iq[@type="get" or @type="set"]/' + \
88 'pubsub[@xmlns="' + NS_PUBSUB + '" or ' + \ 88 'pubsub[@xmlns="' + NS_PUBSUB + '" or ' + \
89 '@xmlns="' + NS_PUBSUB_OWNER + '"]' 89 '@xmlns="' + NS_PUBSUB_OWNER + '"]'
196 @rtype: L{domish.Element} 196 @rtype: L{domish.Element}
197 """ 197 """
198 element = domish.Element((defaultUri, 'subscription')) 198 element = domish.Element((defaultUri, 'subscription'))
199 if self.nodeIdentifier: 199 if self.nodeIdentifier:
200 element['node'] = self.nodeIdentifier 200 element['node'] = self.nodeIdentifier
201 element['jid'] = unicode(self.subscriber) 201 element['jid'] = str(self.subscriber)
202 element['subscription'] = self.state 202 element['subscription'] = self.state
203 if self.subscriptionIdentifier: 203 if self.subscriptionIdentifier:
204 element['subid'] = self.subscriptionIdentifier 204 element['subid'] = self.subscriptionIdentifier
205 return element 205 return element
206 206
227 227
228 domish.Element.__init__(self, (None, 'item')) 228 domish.Element.__init__(self, (None, 'item'))
229 if id is not None: 229 if id is not None:
230 self['id'] = id 230 self['id'] = id
231 if payload is not None: 231 if payload is not None:
232 if isinstance(payload, basestring): 232 if isinstance(payload, str):
233 self.addRawXml(payload) 233 self.addRawXml(payload)
234 else: 234 else:
235 self.addChild(payload) 235 self.addChild(payload)
236 236
237 237
324 ('get', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsGet', 324 ('get', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsGet',
325 ('set', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsSet', 325 ('set', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsSet',
326 } 326 }
327 327
328 # Map request verb to request iq type and subelement name 328 # Map request verb to request iq type and subelement name
329 _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.iteritems())) 329 _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.items()))
330 330
331 # Map request verb to parameter handler names 331 # Map request verb to parameter handler names
332 _parameters = { 332 _parameters = {
333 'publish': ['node', 'items'], 333 'publish': ['node', 'items'],
334 'subscribe': ['nodeOrEmpty', 'jid', 'optionsWithSubscribe'], 334 'subscribe': ['nodeOrEmpty', 'jid', 'optionsWithSubscribe'],
461 form = data_form.findForm(verbElement, NS_PUBSUB_NODE_CONFIG) 461 form = data_form.findForm(verbElement, NS_PUBSUB_NODE_CONFIG)
462 if form is not None: 462 if form is not None:
463 if form.formType in ('submit', 'cancel'): 463 if form.formType in ('submit', 'cancel'):
464 self.options = form 464 self.options = form
465 else: 465 else:
466 raise BadRequest(text=u"Unexpected form type '%s'" % form.formType) 466 raise BadRequest(text="Unexpected form type '%s'" % form.formType)
467 else: 467 else:
468 raise BadRequest(text="Missing configuration form") 468 raise BadRequest(text="Missing configuration form")
469 469
470 470
471 def _parse_configureOrNone(self, verbElement): 471 def _parse_configureOrNone(self, verbElement):
475 for element in verbElement.parent.elements(): 475 for element in verbElement.parent.elements():
476 if element.uri in (NS_PUBSUB, NS_PUBSUB_OWNER) and element.name == 'configure': 476 if element.uri in (NS_PUBSUB, NS_PUBSUB_OWNER) and element.name == 'configure':
477 form = data_form.findForm(element, NS_PUBSUB_NODE_CONFIG) 477 form = data_form.findForm(element, NS_PUBSUB_NODE_CONFIG)
478 if form is not None: 478 if form is not None:
479 if form.formType != 'submit': 479 if form.formType != 'submit':
480 raise BadRequest(text=u"Unexpected form type '%s'" % 480 raise BadRequest(text="Unexpected form type '%s'" %
481 form.formType) 481 form.formType)
482 else: 482 else:
483 form = data_form.Form('submit', 483 form = data_form.Form('submit',
484 formNamespace=NS_PUBSUB_NODE_CONFIG) 484 formNamespace=NS_PUBSUB_NODE_CONFIG)
485 self.options = form 485 self.options = form
537 def _render_maxItems(self, verbElement): 537 def _render_maxItems(self, verbElement):
538 """ 538 """
539 Render maximum items into an items request. 539 Render maximum items into an items request.
540 """ 540 """
541 if self.maxItems: 541 if self.maxItems:
542 verbElement['max_items'] = unicode(self.maxItems) 542 verbElement['max_items'] = str(self.maxItems)
543 543
544 544
545 def _parse_subidOrNone(self, verbElement): 545 def _parse_subidOrNone(self, verbElement):
546 """ 546 """
547 Parse subscription identifier out of a request. 547 Parse subscription identifier out of a request.
564 form = data_form.findForm(verbElement, NS_PUBSUB_SUBSCRIBE_OPTIONS) 564 form = data_form.findForm(verbElement, NS_PUBSUB_SUBSCRIBE_OPTIONS)
565 if form is not None: 565 if form is not None:
566 if form.formType in ('submit', 'cancel'): 566 if form.formType in ('submit', 'cancel'):
567 self.options = form 567 self.options = form
568 else: 568 else:
569 raise BadRequest(text=u"Unexpected form type '%s'" % form.formType) 569 raise BadRequest(text="Unexpected form type '%s'" % form.formType)
570 else: 570 else:
571 raise BadRequest(text="Missing options form") 571 raise BadRequest(text="Missing options form")
572 572
573 573
574 def _render_options(self, verbElement): 574 def _render_options(self, verbElement):
580 if element.name == 'options' and element.uri == NS_PUBSUB: 580 if element.name == 'options' and element.uri == NS_PUBSUB:
581 form = data_form.findForm(element, 581 form = data_form.findForm(element,
582 NS_PUBSUB_SUBSCRIBE_OPTIONS) 582 NS_PUBSUB_SUBSCRIBE_OPTIONS)
583 if form is not None: 583 if form is not None:
584 if form.formType != 'submit': 584 if form.formType != 'submit':
585 raise BadRequest(text=u"Unexpected form type '%s'" % 585 raise BadRequest(text="Unexpected form type '%s'" %
586 form.formType) 586 form.formType)
587 else: 587 else:
588 form = data_form.Form('submit', 588 form = data_form.Form('submit',
589 formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS) 589 formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS)
590 self.options = form 590 self.options = form
616 616
617 self.affiliations[entity] = affiliation 617 self.affiliations[entity] = affiliation
618 618
619 619
620 def _render_affiliations(self, verbElement): 620 def _render_affiliations(self, verbElement):
621 for entity, affiliation in self.affiliations.iteritems(): 621 for entity, affiliation in self.affiliations.items():
622 affiliationElement = verbElement.addElement((NS_PUBSUB_OWNER, 'affiliation')) 622 affiliationElement = verbElement.addElement((NS_PUBSUB_OWNER, 'affiliation'))
623 affiliationElement['jid'] = entity.full() 623 affiliationElement['jid'] = entity.full()
624 affiliationElement['affiliation'] = affiliation 624 affiliationElement['affiliation'] = affiliation
625 625
626 626
813 A publish-subscribe event that signifies the purging of a node. 813 A publish-subscribe event that signifies the purging of a node.
814 """ 814 """
815 815
816 816
817 817
818 @implementer(IPubSubClient)
818 class PubSubClient(XMPPHandler): 819 class PubSubClient(XMPPHandler):
819 """ 820 """
820 Publish subscribe client protocol. 821 Publish subscribe client protocol.
821 """ 822 """
822 implements(IPubSubClient)
823 823
824 _request_class = PubSubRequest 824 _request_class = PubSubRequest
825 825
826 def connectionInitialized(self): 826 def connectionInitialized(self):
827 self.xmlstream.addObserver('/message/event[@xmlns="%s"]' % 827 self.xmlstream.addObserver('/message/event[@xmlns="%s"]' %
1179 d = request.send(self.xmlstream) 1179 d = request.send(self.xmlstream)
1180 return d 1180 return d
1181 1181
1182 1182
1183 1183
1184 @implementer(IPubSubService, disco.IDisco)
1184 class PubSubService(XMPPHandler, IQHandlerMixin): 1185 class PubSubService(XMPPHandler, IQHandlerMixin):
1185 """ 1186 """
1186 Protocol implementation for a XMPP Publish Subscribe Service. 1187 Protocol implementation for a XMPP Publish Subscribe Service.
1187 1188
1188 The word Service here is used as taken from the Publish Subscribe 1189 The word Service here is used as taken from the Publish Subscribe
1207 @ivar pubSubFeatures: List of supported publish-subscribe features for 1208 @ivar pubSubFeatures: List of supported publish-subscribe features for
1208 service discovery, as C{str}. 1209 service discovery, as C{str}.
1209 @type pubSubFeatures: C{list} or C{None} 1210 @type pubSubFeatures: C{list} or C{None}
1210 """ 1211 """
1211 1212
1212 implements(IPubSubService, disco.IDisco)
1213 1213
1214 iqHandlers = { 1214 iqHandlers = {
1215 '/*': '_onPubSubRequest', 1215 '/*': '_onPubSubRequest',
1216 } 1216 }
1217 1217
1320 """ 1320 """
1321 items = [] 1321 items = []
1322 for node in nodes: 1322 for node in nodes:
1323 if not node: 1323 if not node:
1324 continue 1324 continue
1325 elif isinstance(node, basestring): 1325 elif isinstance(node, str):
1326 items.append(disco.DiscoItem(target, node)) 1326 items.append(disco.DiscoItem(target, node))
1327 else: 1327 else:
1328 _node, name = node 1328 _node, name = node
1329 items.append(disco.DiscoItem(target, _node, name)) 1329 items.append(disco.DiscoItem(target, _node, name))
1330 return items 1330 return items
1525 affiliations = response.addElement('affiliations') 1525 affiliations = response.addElement('affiliations')
1526 1526
1527 if request.nodeIdentifier: 1527 if request.nodeIdentifier:
1528 affiliations['node'] = request.nodeIdentifier 1528 affiliations['node'] = request.nodeIdentifier
1529 1529
1530 for entity, affiliation in result.iteritems(): 1530 for entity, affiliation in result.items():
1531 item = affiliations.addElement('affiliation') 1531 item = affiliations.addElement('affiliation')
1532 item['jid'] = entity.full() 1532 item['jid'] = entity.full()
1533 item['affiliation'] = affiliation 1533 item['affiliation'] = affiliation
1534 1534
1535 return response 1535 return response
1647 def delete(self, requestor, service, nodeIdentifier): 1647 def delete(self, requestor, service, nodeIdentifier):
1648 raise Unsupported('delete-nodes') 1648 raise Unsupported('delete-nodes')
1649 1649
1650 1650
1651 1651
1652 @implementer(IPubSubResource)
1652 class PubSubResource(object): 1653 class PubSubResource(object):
1653 1654
1654 implements(IPubSubResource)
1655 1655
1656 features = [] 1656 features = []
1657 discoIdentity = disco.DiscoIdentity('pubsub', 1657 discoIdentity = disco.DiscoIdentity('pubsub',
1658 'service', 1658 'service',
1659 'Publish-Subscribe Service') 1659 'Publish-Subscribe Service')