Changeset 30:68535ae85c8d for wokkel/pubsub.py
- Timestamp:
- Aug 4, 2008, 3:44:57 PM (14 years ago)
- Branch:
- default
- Convert:
- svn:b33ecbfc-034c-dc11-8662-000475d9059e/trunk@60
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/pubsub.py
r29 r30 70 70 PUBSUB_DELETE = PUBSUB_OWNER_SET + '/delete' + IN_NS_PUBSUB_OWNER 71 71 72 class BadRequest(error.StanzaError):73 """74 Bad request stanza error.75 """76 def __init__(self):77 error.StanzaError.__init__(self, 'bad-request')78 79 80 81 72 class SubscriptionPending(Exception): 82 73 """ … … 108 99 109 100 101 class BadRequest(PubSubError): 102 """ 103 Bad request stanza error. 104 """ 105 def __init__(self, pubsubCondition=None, text=None): 106 PubSubError.__init__(self, 'bad-request', pubsubCondition, text) 107 108 109 110 110 class Unsupported(PubSubError): 111 111 def __init__(self, feature, text=None): … … 117 117 118 118 119 class OptionsUnavailable(Unsupported): 120 def __init__(self): 121 Unsupported.__init__(self, 'subscription-options-unavailable') 119 class Subscription(object): 120 """ 121 A subscription to a node. 122 123 @ivar nodeIdentifier: The identifier of the node subscribed to. 124 The root node is denoted by C{None}. 125 @ivar subscriber: The subscribing entity. 126 @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'}, 127 C{'unconfigured'}. 128 @ivar options: Optional list of subscription options. 129 @type options: C{dict}. 130 """ 131 132 def __init__(self, nodeIdentifier, subscriber, state, options=None): 133 self.nodeIdentifier = nodeIdentifier 134 self.subscriber = subscriber 135 self.state = state 136 self.options = options or {} 122 137 123 138 … … 274 289 message.handled = True 275 290 291 276 292 def _onEvent_items(self, sender, recipient, action, headers): 277 293 nodeIdentifier = action["node"] … … 282 298 event = ItemsEvent(sender, recipient, nodeIdentifier, items, headers) 283 299 self.itemsReceived(event) 300 284 301 285 302 def _onEvent_delete(self, sender, recipient, action, headers): … … 288 305 self.deleteReceived(event) 289 306 307 290 308 def _onEvent_purge(self, sender, recipient, action, headers): 291 309 nodeIdentifier = action["node"] … … 293 311 self.purgeReceived(event) 294 312 313 295 314 def itemsReceived(self, event): 296 315 pass 297 316 317 298 318 def deleteReceived(self, event): 299 319 pass 300 320 321 301 322 def purgeReceived(self, event): 302 323 pass 324 303 325 304 326 def createNode(self, service, nodeIdentifier=None): … … 355 377 """ 356 378 request = _PubSubRequest(self.xmlstream, 'subscribe') 357 request.command['node'] = nodeIdentifier 379 if nodeIdentifier: 380 request.command['node'] = nodeIdentifier 358 381 request.command['jid'] = subscriber.full() 359 382 … … 386 409 """ 387 410 request = _PubSubRequest(self.xmlstream, 'unsubscribe') 388 request.command['node'] = nodeIdentifier 411 if nodeIdentifier: 412 request.command['node'] = nodeIdentifier 389 413 request.command['jid'] = subscriber.full() 390 414 return request.send(service) … … 423 447 """ 424 448 request = _PubSubRequest(self.xmlstream, 'items', method='get') 425 request.command['node'] = nodeIdentifier 449 if nodeIdentifier: 450 request.command['node'] = nodeIdentifier 426 451 if maxItems: 427 452 request.command["max_items"] = str(int(maxItems)) … … 573 598 574 599 575 def _onPublish(self, iq): 600 def _getParameter_node(self, commandElement): 601 try: 602 return commandElement["node"] 603 except KeyError: 604 raise BadRequest('nodeid-required') 605 606 607 def _getParameter_nodeOrEmpty(self, commandElement): 608 return commandElement.getAttribute("node", '') 609 610 611 def _getParameter_jid(self, commandElement): 612 try: 613 return jid.internJID(commandElement["jid"]) 614 except KeyError: 615 raise BadRequest('jid-required') 616 617 618 def _getParameter_max_items(self, commandElement): 619 value = commandElement.getAttribute('max_items') 620 621 if value: 622 try: 623 return int(value) 624 except ValueError: 625 raise BadRequest(text="Field max_items requires a positive " + 626 "integer value") 627 else: 628 return None 629 630 631 def _getParameters(self, iq, *names): 576 632 requestor = jid.internJID(iq["from"]).userhostJID() 577 633 service = jid.internJID(iq["to"]) 578 634 579 try: 580 nodeIdentifier = iq.pubsub.publish["node"] 581 except KeyError: 582 raise BadRequest 635 params = [requestor, service] 636 637 if names: 638 command = names[0] 639 commandElement = getattr(iq.pubsub, command) 640 if not commandElement: 641 raise Exception("Could not find command element %r" % command) 642 643 for name in names[1:]: 644 try: 645 getter = getattr(self, '_getParameter_' + name) 646 except KeyError: 647 raise Exception("No parameter getter for this name") 648 649 params.append(getter(commandElement)) 650 651 return params 652 653 654 def _onPublish(self, iq): 655 requestor, service, nodeIdentifier = self._getParameters( 656 iq, 'publish', 'node') 583 657 584 658 items = [] … … 591 665 592 666 def _onSubscribe(self, iq): 593 requestor = jid.internJID(iq["from"]).userhostJID() 594 service = jid.internJID(iq["to"]) 595 596 try: 597 nodeIdentifier = iq.pubsub.subscribe["node"] 598 subscriber = jid.internJID(iq.pubsub.subscribe["jid"]) 599 except KeyError: 600 raise BadRequest 601 602 def toResponse(subscription): 603 nodeIdentifier, state = subscription 667 requestor, service, nodeIdentifier, subscriber = self._getParameters( 668 iq, 'subscribe', 'nodeOrEmpty', 'jid') 669 670 def toResponse(result): 604 671 response = domish.Element((NS_PUBSUB, "pubsub")) 605 672 subscription = response.addElement("subscription") 606 subscription["node"] = nodeIdentifier 607 subscription["jid"] = subscriber.full() 608 subscription["subscription"] = state 673 if result.nodeIdentifier: 674 subscription["node"] = result.nodeIdentifier 675 subscription["jid"] = result.subscriber.full() 676 subscription["subscription"] = result.state 609 677 return response 610 678 … … 615 683 616 684 def _onUnsubscribe(self, iq): 617 requestor = jid.internJID(iq["from"]).userhostJID() 618 service = jid.internJID(iq["to"]) 619 620 try: 621 nodeIdentifier = iq.pubsub.unsubscribe["node"] 622 subscriber = jid.internJID(iq.pubsub.unsubscribe["jid"]) 623 except KeyError: 624 raise BadRequest 685 requestor, service, nodeIdentifier, subscriber = self._getParameters( 686 iq, 'unsubscribe', 'nodeOrEmpty', 'jid') 625 687 626 688 return self.unsubscribe(requestor, service, nodeIdentifier, subscriber) … … 628 690 629 691 def _onOptionsGet(self, iq): 630 raise Unsupported('subscription-options -unavailable')692 raise Unsupported('subscription-options') 631 693 632 694 633 695 def _onOptionsSet(self, iq): 634 raise Unsupported('subscription-options -unavailable')696 raise Unsupported('subscription-options') 635 697 636 698 637 699 def _onSubscriptions(self, iq): 638 requestor = jid.internJID(iq["from"]).userhostJID() 639 service = jid.internJID(iq["to"]) 700 requestor, service = self._getParameters(iq) 640 701 641 702 def toResponse(result): … … 655 716 656 717 def _onAffiliations(self, iq): 657 requestor = jid.internJID(iq["from"]).userhostJID() 658 service = jid.internJID(iq["to"]) 718 requestor, service = self._getParameters(iq) 659 719 660 720 def toResponse(result): … … 675 735 676 736 def _onCreate(self, iq): 677 requestor = jid.internJID(iq["from"]).userhostJID() 678 service = jid.internJID(iq["to"]) 737 requestor, service = self._getParameters(iq) 679 738 nodeIdentifier = iq.pubsub.create.getAttribute("node") 680 739 … … 743 802 744 803 def _onDefault(self, iq): 745 requestor = jid.internJID(iq["from"]).userhostJID() 746 service = jid.internJID(iq["to"]) 804 requestor, service = self._getParameters(iq) 747 805 748 806 def toResponse(options): … … 752 810 return response 753 811 754 d = self.getDefaultConfiguration(requestor, service) 812 form = self._findForm(iq.pubsub.config, NS_PUBSUB_NODE_CONFIG) 813 values = form and form.formType == 'result' and form.getValues() or {} 814 nodeType = values.get('pubsub#node_type', 'leaf') 815 816 if nodeType not in ('leaf', 'collections'): 817 return defer.fail(error.StanzaError('not-acceptable')) 818 819 d = self.getDefaultConfiguration(requestor, service, nodeType) 755 820 d.addCallback(toResponse) 756 821 return d … … 758 823 759 824 def _onConfigureGet(self, iq): 760 requestor = jid.internJID(iq["from"]).userhostJID() 761 service = jid.internJID(iq["to"]) 762 nodeIdentifier = iq.pubsub.configure.getAttribute("node") 825 requestor, service, nodeIdentifier = self._getParameters( 826 iq, 'configure', 'nodeOrEmpty') 763 827 764 828 def toResponse(options): … … 778 842 779 843 def _onConfigureSet(self, iq): 780 requestor = jid.internJID(iq["from"]).userhostJID() 781 service = jid.internJID(iq["to"]) 782 nodeIdentifier = iq.pubsub.configure["node"] 844 requestor, service, nodeIdentifier = self._getParameters( 845 iq, 'configure', 'nodeOrEmpty') 783 846 784 847 # Search configuration form with correct FORM_TYPE and process it … … 799 862 800 863 def _onItems(self, iq): 801 requestor = jid.internJID(iq["from"]).userhostJID() 802 service = jid.internJID(iq["to"]) 803 804 try: 805 nodeIdentifier = iq.pubsub.items["node"] 806 except KeyError: 807 raise BadRequest 808 809 maxItems = iq.pubsub.items.getAttribute('max_items') 810 811 if maxItems: 812 try: 813 maxItems = int(maxItems) 814 except ValueError: 815 raise BadRequest 864 requestor, service, nodeIdentifier, maxItems = self._getParameters( 865 iq, 'items', 'nodeOrEmpty', 'max_items') 816 866 817 867 itemIdentifiers = [] … … 821 871 itemIdentifiers.append(child["id"]) 822 872 except KeyError: 823 raise BadRequest 873 raise BadRequest() 824 874 825 875 def toResponse(result): 826 876 response = domish.Element((NS_PUBSUB, 'pubsub')) 827 877 items = response.addElement('items') 828 items["node"] = nodeIdentifier 878 if nodeIdentifier: 879 items["node"] = nodeIdentifier 829 880 830 881 for item in result: … … 840 891 841 892 def _onRetract(self, iq): 842 requestor = jid.internJID(iq["from"]).userhostJID() 843 service = jid.internJID(iq["to"]) 844 845 try: 846 nodeIdentifier = iq.pubsub.retract["node"] 847 except KeyError: 848 raise BadRequest 893 requestor, service, nodeIdentifier = self._getParameters( 894 iq, 'retract', 'node') 849 895 850 896 itemIdentifiers = [] 851 897 for child in iq.pubsub.retract.elements(): 852 if child.uri == NS_PUBSUB _OWNERand child.name == 'item':898 if child.uri == NS_PUBSUB and child.name == 'item': 853 899 try: 854 900 itemIdentifiers.append(child["id"]) 855 901 except KeyError: 856 raise BadRequest 902 raise BadRequest() 857 903 858 904 return self.retract(requestor, service, nodeIdentifier, … … 861 907 862 908 def _onPurge(self, iq): 863 requestor = jid.internJID(iq["from"]).userhostJID() 864 service = jid.internJID(iq["to"]) 865 866 try: 867 nodeIdentifier = iq.pubsub.purge["node"] 868 except KeyError: 869 raise BadRequest 870 909 requestor, service, nodeIdentifier = self._getParameters( 910 iq, 'purge', 'node') 871 911 return self.purge(requestor, service, nodeIdentifier) 872 912 873 913 874 914 def _onDelete(self, iq): 875 requestor = jid.internJID(iq["from"]).userhostJID() 876 service = jid.internJID(iq["to"]) 877 878 try: 879 nodeIdentifier = iq.pubsub.delete["node"] 880 except KeyError: 881 raise BadRequest 882 915 requestor, service, nodeIdentifier = self._getParameters( 916 iq, 'delete', 'node') 883 917 return self.delete(requestor, service, nodeIdentifier) 884 918 … … 901 935 # public methods 902 936 937 def _createNotification(self, eventType, service, nodeIdentifier, 938 subscriber, subscriptions=None): 939 headers = [] 940 941 if subscriptions: 942 for subscription in subscriptions: 943 if nodeIdentifier != subscription.nodeIdentifier: 944 headers.append(('Collection', subscription.nodeIdentifier)) 945 946 message = domish.Element((None, "message")) 947 message["from"] = service.full() 948 message["to"] = subscriber.full() 949 event = message.addElement((NS_PUBSUB_EVENT, "event")) 950 951 element = event.addElement(eventType) 952 element["node"] = nodeIdentifier 953 954 if headers: 955 message.addChild(shim.Headers(headers)) 956 957 return message 958 903 959 def notifyPublish(self, service, nodeIdentifier, notifications): 904 for recipient, items in notifications: 905 message = domish.Element((None, "message")) 906 message["from"] = service.full() 907 message["to"] = recipient.full() 908 event = message.addElement((NS_PUBSUB_EVENT, "event")) 909 element = event.addElement("items") 910 element["node"] = nodeIdentifier 911 element.children = items 960 for subscriber, subscriptions, items in notifications: 961 message = self._createNotification('items', service, 962 nodeIdentifier, subscriber, 963 subscriptions) 964 message.event.items.children = items 912 965 self.send(message) 913 966 914 967 915 def notifyDelete(self, service, nodeIdentifier, recipients): 916 for recipient in recipients: 917 message = domish.Element((None, "message")) 918 message["from"] = service.full() 919 message["to"] = recipient.full() 920 event = message.addElement((NS_PUBSUB_EVENT, "event")) 921 element = event.addElement("delete") 922 element["node"] = nodeIdentifier 968 def notifyDelete(self, service, nodeIdentifier, subscriptions): 969 for subscription in subscriptions: 970 message = self._createNotification('delete', service, 971 nodeIdentifier, 972 subscription.subscriber) 923 973 self.send(message) 924 974
Note: See TracChangeset
for help on using the changeset viewer.