Mercurial > libervia-pubsub
comparison idavoll/pubsub.py @ 38:c9ddca3cce20
Change exception classes to include stanza error.
Change name of exception base class to Error.
Change backend error map to have a tuple as value: stanza-error, pubsub-error.
Remove empty componentConnected() definition in Service.
Move registering of notification from __init__ to componentConnected in
ComponentServiceFromNotificationService.
Add observers for subscribe, options and configure.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Sun, 31 Oct 2004 16:03:50 +0000 |
parents | fa866793075d |
children | 31eb00734cc5 |
comparison
equal
deleted
inserted
replaced
37:9aa20efac203 | 38:c9ddca3cce20 |
---|---|
17 PUBSUB_GET = IQ_GET + PUBSUB_ELEMENT | 17 PUBSUB_GET = IQ_GET + PUBSUB_ELEMENT |
18 PUBSUB_SET = IQ_SET + PUBSUB_ELEMENT | 18 PUBSUB_SET = IQ_SET + PUBSUB_ELEMENT |
19 PUBSUB_CREATE = PUBSUB_SET + '/create' | 19 PUBSUB_CREATE = PUBSUB_SET + '/create' |
20 PUBSUB_PUBLISH = PUBSUB_SET + '/publish' | 20 PUBSUB_PUBLISH = PUBSUB_SET + '/publish' |
21 PUBSUB_SUBSCRIBE = PUBSUB_SET + '/subscribe' | 21 PUBSUB_SUBSCRIBE = PUBSUB_SET + '/subscribe' |
22 PUBSUB_UNSUBSCRIBE = PUBSUB_SET + '/unsubscribe' | |
22 PUBSUB_OPTIONS_GET = PUBSUB_GET + '/options' | 23 PUBSUB_OPTIONS_GET = PUBSUB_GET + '/options' |
23 PUBSUB_OPTIONS_SET = PUBSUB_SET + '/options' | 24 PUBSUB_OPTIONS_SET = PUBSUB_SET + '/options' |
24 PUBSUB_CONFIGURE_GET = PUBSUB_GET + '/configure' | 25 PUBSUB_CONFIGURE_GET = PUBSUB_GET + '/configure' |
25 PUBSUB_CONFIGURE_SET = PUBSUB_SET + '/configure' | 26 PUBSUB_CONFIGURE_SET = PUBSUB_SET + '/configure' |
26 | 27 |
27 class PubSubError(Exception): | 28 class Error(Exception): |
28 pubsub_error = None | 29 pubsub_error = None |
30 stanza_error = None | |
29 msg = '' | 31 msg = '' |
30 | 32 |
31 class NotImplemented(PubSubError): | 33 class NotImplemented(Error): |
32 pass | 34 stanza_error = 'feature-not-implemented' |
33 | 35 |
34 class OptionsUnavailable(PubSubError): | 36 class OptionsUnavailable(Error): |
37 stanza_error = 'feature-not-implemented' | |
35 pubsub_error = 'subscription-options-unavailable' | 38 pubsub_error = 'subscription-options-unavailable' |
36 | 39 |
37 class SubscriptionOptionsUnavailable(PubSubError): | 40 class SubscriptionOptionsUnavailable(Error): |
41 stanza_error = 'not-acceptable' | |
38 pubsub_error = 'subscription-options-unavailable' | 42 pubsub_error = 'subscription-options-unavailable' |
39 | 43 |
40 class NodeNotConfigurable(PubSubError): | 44 class NodeNotConfigurable(Error): |
45 stanza_error = 'feature-not-implemented' | |
41 pubsub_error = 'node-not-configurable' | 46 pubsub_error = 'node-not-configurable' |
42 | 47 |
43 class CreateNodeNotConfigurable(PubSubError): | 48 class CreateNodeNotConfigurable(Error): |
49 stanza_error = 'not-acceptable' | |
44 pubsub_error = 'node-not-configurable' | 50 pubsub_error = 'node-not-configurable' |
45 | 51 |
46 error_map = { | 52 error_map = { |
47 backend.NotAuthorized: 'not-authorized', | 53 backend.NotAuthorized: ('not-authorized', None), |
48 backend.NodeNotFound: 'item-not-found', | 54 backend.NodeNotFound: ('item-not-found', None), |
49 backend.NoPayloadAllowed: 'bad-request', | 55 backend.NoPayloadAllowed: ('bad-request', None), |
50 backend.PayloadExpected: 'bad-request', | 56 backend.PayloadExpected: ('bad-request', None), |
51 backend.NoInstantNodes: 'not-acceptable', | 57 backend.NoInstantNodes: ('not-acceptable', None), |
52 backend.NodeExists: 'conflict', | 58 backend.NodeExists: ('conflict', None), |
53 backend.NotImplemented: 'feature-not-implemented', | 59 backend.NotImplemented: ('feature-not-implemented', None), |
54 NotImplemented: 'feature-not-implemented', | 60 backend.NotSubscribed: ('not-authorized', 'requestor-not-subscribed'), |
55 OptionsUnavailable: 'feature-not-implemented', | |
56 SubscriptionOptionsUnavailable: 'not-acceptable', | |
57 NodeNotConfigurable: 'feature-not-implemented', | |
58 CreateNodeNotConfigurable: 'not-acceptable', | |
59 } | 61 } |
60 | 62 |
61 class Service(component.Service): | 63 class Service(component.Service): |
62 | 64 |
63 __implements__ = component.IService | 65 __implements__ = component.IService |
64 | 66 |
65 def __init__(self, backend): | 67 def __init__(self, backend): |
66 self.backend = backend | 68 self.backend = backend |
67 | 69 |
68 def componentConnected(self, xmlstream): | |
69 pass | |
70 | |
71 def error(self, failure, iq): | 70 def error(self, failure, iq): |
72 try: | 71 try: |
73 r = failure.trap(*error_map.keys()) | 72 e = failure.trap(Error, *error_map.keys()) |
74 xmpp_error.error_from_iq(iq, error_map[r], failure.value.msg) | 73 |
75 if isinstance(failure.value, PubSubError) and \ | 74 if e == Error: |
76 failure.value.pubsub_error is not None: | 75 stanza_error = failure.value.stanza_error |
77 iq.error.addElement((NS_PUBSUB_ERRORS, | 76 pubsub_error = failure.value.pubsub_error |
78 failure.value.pubsub_error), | 77 msg = '' |
79 NS_PUBSUB_ERRORS) | 78 else: |
79 stanza_error, pubsub_error = error_map[e] | |
80 msg = failure.value.msg | |
81 | |
82 xmpp_error.error_from_iq(iq, stanza_error, msg) | |
83 if pubsub_error: | |
84 iq.error.addElement((NS_PUBSUB_ERRORS, pubsub_error)) | |
80 return iq | 85 return iq |
81 except: | 86 except: |
82 xmpp_error.error_from_iq(iq, 'internal-server-error') | 87 xmpp_error.error_from_iq(iq, 'internal-server-error') |
83 self.send(iq) | 88 self.send(iq) |
84 raise | 89 raise |
128 | 133 |
129 components.registerAdapter(ComponentServiceFromService, backend.IBackendService, component.IService) | 134 components.registerAdapter(ComponentServiceFromService, backend.IBackendService, component.IService) |
130 | 135 |
131 class ComponentServiceFromNotificationService(Service): | 136 class ComponentServiceFromNotificationService(Service): |
132 | 137 |
133 def __init__(self, backend): | 138 def componentConnected(self, xmlstream): |
134 Service.__init__(self, backend) | |
135 self.backend.register_notifier(self.notify) | 139 self.backend.register_notifier(self.notify) |
136 | 140 |
137 def notify(self, object): | 141 def notify(self, object): |
138 node_id = object["node_id"] | 142 node_id = object["node_id"] |
139 items = object["items"] | 143 items = object["items"] |
140 d = self.backend.get_notification_list(node_id, items) | 144 d = self.backend.get_notification_list(node_id, items) |
141 d.addCallback(self._notify, node_id) | 145 d.addCallback(self._notify, node_id) |
142 | 146 |
143 def _notify(self, list, node_id): | 147 def _notify(self, list, node_id): |
148 print list | |
144 for recipient, items in list.items(): | 149 for recipient, items in list.items(): |
145 self._notify_recipient(recipient, node_id, items) | 150 self._notify_recipient(recipient, node_id, items) |
146 | 151 |
147 def _notify_recipient(self, recipient, node_id, itemlist): | 152 def _notify_recipient(self, recipient, node_id, itemlist): |
148 message = domish.Element((NS_COMPONENT, "message")) | 153 message = domish.Element((NS_COMPONENT, "message")) |
149 message["from"] = self.parent.jabberId | 154 message["from"] = self.parent.jabberId |
150 message["to"] = recipient | 155 message["to"] = recipient |
151 event = message.addElement((NS_PUBSUB_EVENT, "event"), NS_PUBSUB_EVENT) | 156 event = message.addElement((NS_PUBSUB_EVENT, "event")) |
152 items = event.addElement("items") | 157 items = event.addElement("items") |
153 items["node"] = node_id | 158 items["node"] = node_id |
154 items.children.extend(itemlist) | 159 items.children.extend(itemlist) |
155 self.send(message) | 160 self.send(message) |
156 | 161 |
181 | 186 |
182 class ComponentServiceFromSubscriptionService(Service): | 187 class ComponentServiceFromSubscriptionService(Service): |
183 | 188 |
184 def componentConnected(self, xmlstream): | 189 def componentConnected(self, xmlstream): |
185 xmlstream.addObserver(PUBSUB_SUBSCRIBE, self.onSubscribe) | 190 xmlstream.addObserver(PUBSUB_SUBSCRIBE, self.onSubscribe) |
191 xmlstream.addObserver(PUBSUB_UNSUBSCRIBE, self.onUnsubscribe) | |
192 xmlstream.addObserver(PUBSUB_OPTIONS_GET, self.onOptionsGet) | |
193 xmlstream.addObserver(PUBSUB_OPTIONS_SET, self.onOptionsSet) | |
186 | 194 |
187 def onSubscribe(self, iq): | 195 def onSubscribe(self, iq): |
188 self.handler_wrapper(self._onSubscribe, iq) | 196 self.handler_wrapper(self._onSubscribe, iq) |
189 | 197 |
190 def _onSubscribe(self, iq): | 198 def _onSubscribe(self, iq): |
192 raise SubscribeOptionsUnavailable | 200 raise SubscribeOptionsUnavailable |
193 | 201 |
194 node_id = iq.pubsub.subscribe["node"] | 202 node_id = iq.pubsub.subscribe["node"] |
195 subscriber = jid.JID(iq.pubsub.subscribe["jid"]) | 203 subscriber = jid.JID(iq.pubsub.subscribe["jid"]) |
196 requestor = jid.JID(iq["from"]).userhostJID() | 204 requestor = jid.JID(iq["from"]).userhostJID() |
197 d = self.backend.do_subscribe(node_id, subscriber, requestor) | 205 d = self.backend.subscribe(node_id, subscriber, requestor) |
198 d.addCallback(self.return_subscription) | 206 d.addCallback(self.return_subscription) |
199 d.addCallback(self.succeed, iq) | 207 return d |
200 d.addErrback(self.error, iq) | |
201 d.addCallback(self.send) | |
202 | |
203 def _onConfigureGet(self, iq): | |
204 raise NodeNotConfigurable | |
205 | |
206 def _onConfigureSet(self, iq): | |
207 raise NodeNotConfigurable | |
208 | 208 |
209 def return_subscription(self, result): | 209 def return_subscription(self, result): |
210 reply = domish.Element("pubsub", NS_PUBSUB) | 210 reply = domish.Element((NS_PUBSUB, "pubsub"), NS_PUBSUB) |
211 entity = reply.addElement("entity") | 211 entity = reply.addElement("entity") |
212 entity["node"] = result["node"] | 212 entity["node"] = result["node"] |
213 entity["jid"] = result["jid"].full() | 213 entity["jid"] = result["jid"].full() |
214 entity["affiliation"] = result["affiliation"] | 214 entity["affiliation"] = result["affiliation"] |
215 entity["subscription"] = result["subscription"] | 215 entity["subscription"] = result["subscription"] |
216 return reply | 216 return [reply] |
217 | |
218 def onUnsubscribe(self, iq): | |
219 self.handler_wrapper(self._onUnsubscribe, iq) | |
220 | |
221 def _onUnsubscribe(self, iq): | |
222 node_id = iq.pubsub.unsubscribe["node"] | |
223 subscriber = jid.JID(iq.pubsub.unsubscribe["jid"]) | |
224 requestor = jid.JID(iq["from"]).userhostJID() | |
225 return self.backend.unsubscribe(node_id, subscriber, requestor) | |
226 | |
227 def onOptionsGet(self, iq): | |
228 self.handler_wrapper(self._onOptionsGet, iq) | |
229 | |
230 def _onOptionsGet(self, iq): | |
231 raise OptionsUnavailable | |
232 | |
233 def onOptionsSet(self, iq): | |
234 self.handler_wrapper(self._onOptionsSet, iq) | |
235 | |
236 def _onOptionsSet(self, iq): | |
237 raise OptionsUnavailable | |
217 | 238 |
218 components.registerAdapter(ComponentServiceFromSubscriptionService, backend.ISubscriptionService, component.IService) | 239 components.registerAdapter(ComponentServiceFromSubscriptionService, backend.ISubscriptionService, component.IService) |
219 | 240 |
220 class ComponentServiceFromNodeCreationService(Service): | 241 class ComponentServiceFromNodeCreationService(Service): |
221 | 242 |
222 def componentConnected(self, xmlstream): | 243 def componentConnected(self, xmlstream): |
223 xmlstream.addObserver(PUBSUB_CREATE, self.onCreate) | 244 xmlstream.addObserver(PUBSUB_CREATE, self.onCreate) |
245 xmlstream.addObserver(PUBSUB_CONFIGURE_GET, self.onConfigureGet) | |
246 xmlstream.addObserver(PUBSUB_CONFIGURE_SET, self.onConfigureSet) | |
224 | 247 |
225 def onCreate(self, iq): | 248 def onCreate(self, iq): |
226 self.handler_wrapper(self._onCreate, iq) | 249 self.handler_wrapper(self._onCreate, iq) |
227 | 250 |
228 def _onCreate(self, iq): | 251 def _onCreate(self, iq): |
233 owner = jid.JID(iq["from"]).userhostJID() | 256 owner = jid.JID(iq["from"]).userhostJID() |
234 | 257 |
235 d = self.backend.create_node(node, owner) | 258 d = self.backend.create_node(node, owner) |
236 d.addCallback(self.return_create_response, iq) | 259 d.addCallback(self.return_create_response, iq) |
237 return d | 260 return d |
238 | |
239 def _onOptionsGet(self, iq): | |
240 raise OptionsUnavailable | |
241 | |
242 def _onOptionsSet(self, iq): | |
243 raise OptionsUnavailable | |
244 | 261 |
245 def return_create_response(self, result, iq): | 262 def return_create_response(self, result, iq): |
246 if iq.pubsub.create["node"] is None: | 263 if iq.pubsub.create["node"] is None: |
247 reply = domish.Element('pubsub', NS_PUBSUB) | 264 reply = domish.Element('pubsub', NS_PUBSUB) |
248 entity = reply.addElement('create') | 265 entity = reply.addElement('create') |
249 entity['node'] = result['node_id'] | 266 entity['node'] = result['node_id'] |
250 return reply | 267 return reply |
251 | 268 |
269 def onConfigureGet(self, iq): | |
270 self.handler_wrapper(self._onConfigureGet, iq) | |
271 | |
272 def _onConfigureGet(self, iq): | |
273 raise NodeNotConfigurable | |
274 | |
275 def onConfigureSet(self, iq): | |
276 self.handler_wrapper(self._onConfigureSet, iq) | |
277 | |
278 def _onConfigureSet(self, iq): | |
279 raise NodeNotConfigurable | |
280 | |
252 components.registerAdapter(ComponentServiceFromNodeCreationService, backend.INodeCreationService, component.IService) | 281 components.registerAdapter(ComponentServiceFromNodeCreationService, backend.INodeCreationService, component.IService) |