Mercurial > libervia-pubsub
annotate idavoll/pubsub.py @ 21:e01bbbfa8a46
Implemented node creation.
Corrected handling of subscribe/options combo.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Wed, 06 Oct 2004 21:07:11 +0000 |
parents | 7937d6fbbe2a |
children | 884268687229 |
rev | line source |
---|---|
1 | 1 from twisted.protocols.jabber import component,jid |
2 | 2 from twisted.xish import utility, domish |
1 | 3 from twisted.python import components |
4 import backend | |
5 import xmpp_error | |
6 | |
2 | 7 NS_COMPONENT = 'jabber:component:accept' |
8 NS_PUBSUB = 'http://jabber.org/protocol/pubsub' | |
9 NS_PUBSUB_EVENT = NS_PUBSUB + '#event' | |
16 | 10 NS_PUBSUB_ERRORS = NS_PUBSUB + '#errors' |
2 | 11 |
1 | 12 IQ_GET = '/iq[@type="get"]' |
13 IQ_SET = '/iq[@type="set"]' | |
2 | 14 PUBSUB_ELEMENT = '/pubsub[@xmlns="' + NS_PUBSUB + '"]' |
15 PUBSUB_GET = IQ_GET + PUBSUB_ELEMENT | |
16 PUBSUB_SET = IQ_SET + PUBSUB_ELEMENT | |
1 | 17 PUBSUB_CREATE = PUBSUB_SET + '/create' |
18 PUBSUB_PUBLISH = PUBSUB_SET + '/publish' | |
16 | 19 PUBSUB_SUBSCRIBE = PUBSUB_SET + '/subscribe' |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
20 PUBSUB_OPTIONS_GET = PUBSUB_GET + '/options' |
21 | 21 PUBSUB_OPTIONS_SET = PUBSUB_SET + '/options' |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
22 PUBSUB_CONFIGURE_GET = PUBSUB_GET + '/configure' |
21 | 23 PUBSUB_CONFIGURE_SET = PUBSUB_SET + '/configure' |
1 | 24 |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
25 error_map = { |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
26 backend.NotAuthorized: 'not-authorized', |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
27 backend.NodeNotFound: 'item-not-found', |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
28 backend.NoPayloadAllowed: 'bad-request', |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
29 backend.PayloadExpected: 'bad-request', |
21 | 30 backend.NoInstantNodes: 'not-acceptable', |
31 backend.NodeExists: 'conflict', | |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
32 } |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
33 |
1 | 34 class ComponentServiceFromBackend(component.Service, utility.EventDispatcher): |
35 | |
36 def __init__(self, backend): | |
37 utility.EventDispatcher.__init__(self) | |
38 self.backend = backend | |
2 | 39 self.backend.pubsub_service = self |
1 | 40 self.addObserver(PUBSUB_PUBLISH, self.onPublish) |
21 | 41 |
42 # make sure subscribe and create are handled before resp. options and | |
43 # configure | |
44 self.addObserver(PUBSUB_SUBSCRIBE, self.onSubscribe, 0) | |
45 self.addObserver(PUBSUB_OPTIONS_SET, self.onOptionsSet, 1) | |
46 self.addObserver(PUBSUB_CREATE, self.onSubscribe, 0) | |
47 self.addObserver(PUBSUB_CONFIGURE_SET, self.onConfigureSet, 1) | |
48 | |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
49 self.addObserver(PUBSUB_OPTIONS_GET, self.onOptionsGet) |
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
50 self.addObserver(PUBSUB_CONFIGURE_GET, self.onConfigureGet) |
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
51 self.addObserver(PUBSUB_GET, self.notImplemented, -1) |
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
52 self.addObserver(PUBSUB_SET, self.notImplemented, -1) |
1 | 53 |
54 def componentConnected(self, xmlstream): | |
55 xmlstream.addObserver(PUBSUB_SET, self.onPubSub) | |
56 xmlstream.addObserver(PUBSUB_GET, self.onPubSub) | |
57 | |
9 | 58 def getIdentities(self, node): |
59 results = [] | |
60 if not node: | |
61 results.append({ | |
62 'category': 'pubsub', | |
63 'type': 'generic', | |
64 'name': 'Generic Pubsub Service' | |
65 }) | |
66 return results | |
67 | |
12 | 68 def getFeatures(self, node): |
69 return [ | |
70 "http://jabber.org/protocol/pubsub#outcast-affil", | |
71 "http://jabber.org/protocol/pubsub#publisher-affil", | |
16 | 72 "http://jabber.org/protocol/pubsub#persistent-items", |
12 | 73 ] |
74 | |
1 | 75 def error(self, failure, iq): |
16 | 76 try: |
77 r = failure.trap(*error_map.keys()) | |
78 xmpp_error.error_from_iq(iq, error_map[r], failure.value.msg) | |
79 return iq | |
80 except: | |
81 xmpp_error.error_from_iq(iq, 'internal-server-error') | |
82 self.send(iq) | |
83 raise | |
1 | 84 |
85 def success(self, result, iq): | |
86 iq.swapAttributeValues("to", "from") | |
87 iq["type"] = 'result' | |
18 | 88 iq.children = result or [] |
1 | 89 return iq |
90 | |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
91 def notImplemented(self, iq): |
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
92 self.send(xmpp_error.error_from_iq(iq, 'feature-not-implemented')) |
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
93 |
1 | 94 def onPubSub(self, iq): |
95 self.dispatch(iq) | |
96 iq.handled = True | |
97 | |
98 def onPublish(self, iq): | |
99 node = iq.pubsub.publish["node"] | |
100 | |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
101 items = [] |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
102 for child in iq.pubsub.publish.children: |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
103 if child.__class__ == domish.Element and child.name == 'item': |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
104 items.append(child) |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
105 |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
106 print items |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
107 |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
108 d = self.backend.do_publish(node, jid.JID(iq["from"]).userhost(), items) |
1 | 109 d.addCallback(self.success, iq) |
110 d.addErrback(self.error, iq) | |
111 d.addCallback(self.send) | |
112 | |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
113 def onOptionsGet(self, iq): |
16 | 114 xmpp_error.error_from_iq(iq, 'feature-not-implemented') |
115 iq.error.addElement((NS_PUBSUB_ERRORS, 'subscription-options-unavailable'), NS_PUBSUB_ERRORS) | |
116 self.send(iq) | |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
117 |
21 | 118 def onOptionsSet(self, iq): |
119 if iq.pubsub.subscribe: | |
120 # this should be handled by the subscribe handler | |
121 return | |
122 | |
123 xmpp_error.error_from_iq(iq, 'feature-not-implemented') | |
124 iq.error.addElement((NS_PUBSUB_ERRORS, 'subscription-options-unavailable'), NS_PUBSUB_ERRORS) | |
125 self.send(iq) | |
126 | |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
127 def onConfigureGet(self, iq): |
16 | 128 xmpp_error.error_from_iq(iq, 'feature-not-implemented') |
129 iq.error.addElement((NS_PUBSUB_ERRORS, 'node-not-configurable'), NS_PUBSUB_ERRORS) | |
130 self.send(iq) | |
131 | |
21 | 132 def onConfigureSet(self, iq): |
133 if iq.pubsub.create: | |
134 # this should be handled by the create handler | |
135 return | |
136 | |
137 xmpp_error.error_from_iq(iq, 'feature-not-implemented') | |
138 iq.error.addElement((NS_PUBSUB_ERRORS, 'node-not-configurable'), NS_PUBSUB_ERRORS) | |
139 self.send(iq) | |
140 | |
16 | 141 def onSubscribe(self, iq): |
21 | 142 if iq.pubsub.options: |
143 xmpp_error.error_from_iq(iq, 'not-acceptable') | |
144 iq.error.addElement((NS_PUBSUB_ERRORS, 'subscription-options-unavailable'), NS_PUBSUB_ERRORS) | |
145 self.send(iq) | |
146 return | |
147 | |
16 | 148 node_id = iq.pubsub.subscribe["node"] |
149 subscriber = jid.JID(iq.pubsub.subscribe["jid"]) | |
150 requestor = jid.JID(iq["from"]).userhostJID() | |
151 d = self.backend.do_subscribe(node_id, subscriber, requestor) | |
18 | 152 d.addCallback(self.return_subscription) |
153 d.addCallback(self.succeed, iq) | |
16 | 154 d.addErrback(self.error, iq) |
155 d.addCallback(self.send) | |
156 | |
18 | 157 def return_subscription(self, result): |
158 reply = domish.Element("pubsub", NS_PUBSUB) | |
16 | 159 entity = reply.addElement("entity") |
160 entity["node"] = result["node"] | |
161 entity["jid"] = result["jid"].full() | |
162 entity["affiliation"] = result["affiliation"] | |
163 entity["subscription"] = result["subscription"] | |
18 | 164 return reply |
7
a8cfb31dc50c
Implemented fallback for feature-not-implemented.
Ralph Meijer <ralphm@ik.nu>
parents:
4
diff
changeset
|
165 |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
166 def do_notification(self, list, node): |
1 | 167 |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
168 for recipient, items in list.items(): |
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
169 self.notify(node, items, recipient) |
2 | 170 |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
171 def notify(self, node, itemlist, recipient): |
2 | 172 message = domish.Element((NS_COMPONENT, "message")) |
173 message["from"] = self.parent.jabberId | |
174 message["to"] = recipient | |
175 x = message.addElement((NS_PUBSUB_EVENT, "x"), NS_PUBSUB_EVENT) | |
176 items = x.addElement("items") | |
177 items["node"] = node | |
4
ea195dc1732d
Allow publication of more than 1 item.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
178 items.children.extend(itemlist) |
2 | 179 self.send(message) |
180 | |
21 | 181 def onCreate(self, iq): |
182 if iq.pubsub.options: | |
183 xmpp_error.error_from_iq(iq, 'not-acceptable') | |
184 iq.error.addElement((NS_PUBSUB_ERRORS, 'node-not-configurable'), NS_PUBSUB_ERRORS) | |
185 self.send(iq) | |
186 return | |
187 | |
1 | 188 node = iq.pubsub.create["node"] |
21 | 189 owner = jid.JID(iq["from"]).userhostJID() |
1 | 190 |
191 try: | |
21 | 192 d = self.backend.create_node(node, owner) |
193 d.addCallback(self.return_create_response, iq) | |
194 d.addCallback(self.succeed, iq) | |
195 d.addErrback(self.error, iq) | |
196 d.addCallback(self.send) | |
1 | 197 except: |
198 pass | |
199 | |
21 | 200 def return_create_response(self, result, iq): |
201 if iq.pubsub.create["node"] is None: | |
202 reply = domish.Element('pubsub', NS_PUBSUB) | |
203 entity = reply.addElement('create') | |
204 entity['node'] = result['node_id'] | |
205 return reply | |
1 | 206 |
207 components.registerAdapter(ComponentServiceFromBackend, backend.IBackendService, component.IService) | |
208 |