Mercurial > libervia-pubsub
comparison sat_pubsub/iidavoll.py @ 232:923281d4c5bc
renamed idavoll directory to sat_pubsub
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 17 May 2012 12:48:14 +0200 |
parents | idavoll/iidavoll.py@274a45d2a5ab |
children | 564ae55219e1 |
comparison
equal
deleted
inserted
replaced
231:d99047cd90f9 | 232:923281d4c5bc |
---|---|
1 # Copyright (c) 2003-2008 Ralph Meijer | |
2 # See LICENSE for details. | |
3 | |
4 """ | |
5 Interfaces for idavoll. | |
6 """ | |
7 | |
8 from zope.interface import Attribute, Interface | |
9 | |
10 class IBackendService(Interface): | |
11 """ Interface to a backend service of a pubsub service. """ | |
12 | |
13 | |
14 def __init__(storage): | |
15 """ | |
16 @param storage: Object providing L{IStorage}. | |
17 """ | |
18 | |
19 | |
20 def supportsPublisherAffiliation(): | |
21 """ Reports if the backend supports the publisher affiliation. | |
22 | |
23 @rtype: C{bool} | |
24 """ | |
25 | |
26 | |
27 def supportsOutcastAffiliation(): | |
28 """ Reports if the backend supports the publisher affiliation. | |
29 | |
30 @rtype: C{bool} | |
31 """ | |
32 | |
33 | |
34 def supportsPersistentItems(): | |
35 """ Reports if the backend supports persistent items. | |
36 | |
37 @rtype: C{bool} | |
38 """ | |
39 | |
40 | |
41 def getNodeType(nodeIdentifier): | |
42 """ Return type of a node. | |
43 | |
44 @return: a deferred that returns either 'leaf' or 'collection' | |
45 """ | |
46 | |
47 | |
48 def getNodes(): | |
49 """ Returns list of all nodes. | |
50 | |
51 @return: a deferred that returns a C{list} of node ids. | |
52 """ | |
53 | |
54 | |
55 def getNodeMetaData(nodeIdentifier): | |
56 """ Return meta data for a node. | |
57 | |
58 @return: a deferred that returns a C{list} of C{dict}s with the | |
59 metadata. | |
60 """ | |
61 | |
62 | |
63 def createNode(nodeIdentifier, requestor): | |
64 """ Create a node. | |
65 | |
66 @return: a deferred that fires when the node has been created. | |
67 """ | |
68 | |
69 | |
70 def registerPreDelete(preDeleteFn): | |
71 """ Register a callback that is called just before a node deletion. | |
72 | |
73 The function C{preDeletedFn} is added to a list of functions to be | |
74 called just before deletion of a node. The callback C{preDeleteFn} is | |
75 called with the C{nodeIdentifier} that is about to be deleted and | |
76 should return a deferred that returns a list of deferreds that are to | |
77 be fired after deletion. The backend collects the lists from all these | |
78 callbacks before actually deleting the node in question. After | |
79 deletion all collected deferreds are fired to do post-processing. | |
80 | |
81 The idea is that you want to be able to collect data from the node | |
82 before deleting it, for example to get a list of subscribers that have | |
83 to be notified after the node has been deleted. To do this, | |
84 C{preDeleteFn} fetches the subscriber list and passes this list to a | |
85 callback attached to a deferred that it sets up. This deferred is | |
86 returned in the list of deferreds. | |
87 """ | |
88 | |
89 | |
90 def deleteNode(nodeIdentifier, requestor): | |
91 """ Delete a node. | |
92 | |
93 @return: a deferred that fires when the node has been deleted. | |
94 """ | |
95 | |
96 | |
97 def purgeNode(nodeIdentifier, requestor): | |
98 """ Removes all items in node from persistent storage """ | |
99 | |
100 | |
101 def subscribe(nodeIdentifier, subscriber, requestor): | |
102 """ Request the subscription of an entity to a pubsub node. | |
103 | |
104 Depending on the node's configuration and possible business rules, the | |
105 C{subscriber} is added to the list of subscriptions of the node with id | |
106 C{nodeIdentifier}. The C{subscriber} might be different from the | |
107 C{requestor}, and if the C{requestor} is not allowed to subscribe this | |
108 entity an exception should be raised. | |
109 | |
110 @return: a deferred that returns the subscription state | |
111 """ | |
112 | |
113 | |
114 def unsubscribe(nodeIdentifier, subscriber, requestor): | |
115 """ Cancel the subscription of an entity to a pubsub node. | |
116 | |
117 The subscription of C{subscriber} is removed from the list of | |
118 subscriptions of the node with id C{nodeIdentifier}. If the | |
119 C{requestor} is not allowed to unsubscribe C{subscriber}, an an | |
120 exception should be raised. | |
121 | |
122 @return: a deferred that fires when unsubscription is complete. | |
123 """ | |
124 | |
125 | |
126 def getSubscribers(nodeIdentifier): | |
127 """ Get node subscriber list. | |
128 | |
129 @return: a deferred that fires with the list of subscribers. | |
130 """ | |
131 | |
132 | |
133 def getSubscriptions(entity): | |
134 """ Report the list of current subscriptions with this pubsub service. | |
135 | |
136 Report the list of the current subscriptions with all nodes within this | |
137 pubsub service, for the C{entity}. | |
138 | |
139 @return: a deferred that returns the list of all current subscriptions | |
140 as tuples C{(nodeIdentifier, subscriber, subscription)}. | |
141 """ | |
142 | |
143 | |
144 def getAffiliations(entity): | |
145 """ Report the list of current affiliations with this pubsub service. | |
146 | |
147 Report the list of the current affiliations with all nodes within this | |
148 pubsub service, for the C{entity}. | |
149 | |
150 @return: a deferred that returns the list of all current affiliations | |
151 as tuples C{(nodeIdentifier, affiliation)}. | |
152 """ | |
153 | |
154 | |
155 def publish(nodeIdentifier, items, requestor): | |
156 """ Publish items to a pubsub node. | |
157 | |
158 @return: a deferred that fires when the items have been published. | |
159 @rtype: L{Deferred<twisted.internet.defer.Deferred>} | |
160 """ | |
161 | |
162 | |
163 def registerNotifier(observerfn, *args, **kwargs): | |
164 """ Register callback which is called for notification. """ | |
165 | |
166 | |
167 def getNotifications(nodeIdentifier, items): | |
168 """ | |
169 Get notification list. | |
170 | |
171 This method is called to discover which entities should receive | |
172 notifications for the given items that have just been published to the | |
173 given node. | |
174 | |
175 The notification list contains tuples (subscriber, subscriptions, | |
176 items) to result in one notification per tuple: the given subscriptions | |
177 yielded the given items to be notified to this subscriber. This | |
178 structure is needed allow for letting the subscriber know which | |
179 subscriptions yielded which notifications, while catering for | |
180 collection nodes and content-based subscriptions. | |
181 | |
182 To minimize the amount of notifications per entity, implementers | |
183 should take care that if all items in C{items} were yielded | |
184 by the same set of subscriptions, exactly one tuple is for this | |
185 subscriber is returned, so that the subscriber would get exactly one | |
186 notification. Alternatively, one tuple per subscription combination. | |
187 | |
188 @param nodeIdentifier: The identifier of the node the items were | |
189 published to. | |
190 @type nodeIdentifier: C{unicode}. | |
191 @param items: The list of published items as | |
192 L{Element<twisted.words.xish.domish.Element>}s. | |
193 @type items: C{list} | |
194 @return: The notification list as tuples of | |
195 (L{JID<twisted.words.protocols.jabber.jid.JID>}, | |
196 C{list} of L{Subscription<wokkel.pubsub.Subscription>}, | |
197 C{list} of L{Element<twisted.words.xish.domish.Element>}. | |
198 @rtype: C{list} | |
199 """ | |
200 | |
201 | |
202 def getItems(nodeIdentifier, requestor, maxItems=None, itemIdentifiers=[]): | |
203 """ Retrieve items from persistent storage | |
204 | |
205 If C{maxItems} is given, return the C{maxItems} last published | |
206 items, else if C{itemIdentifiers} is not empty, return the items | |
207 requested. If neither is given, return all items. | |
208 | |
209 @return: a deferred that returns the requested items | |
210 """ | |
211 | |
212 | |
213 def retractItem(nodeIdentifier, itemIdentifier, requestor): | |
214 """ Removes item in node from persistent storage """ | |
215 | |
216 | |
217 | |
218 class IStorage(Interface): | |
219 """ | |
220 Storage interface. | |
221 """ | |
222 | |
223 | |
224 def getNode(nodeIdentifier): | |
225 """ | |
226 Get Node. | |
227 | |
228 @param nodeIdentifier: NodeID of the desired node. | |
229 @type nodeIdentifier: C{str} | |
230 @return: deferred that returns a L{INode} providing object. | |
231 """ | |
232 | |
233 | |
234 def getNodeIds(): | |
235 """ | |
236 Return all NodeIDs. | |
237 | |
238 @return: deferred that returns a list of NodeIDs (C{unicode}). | |
239 """ | |
240 | |
241 | |
242 def createNode(nodeIdentifier, owner, config): | |
243 """ | |
244 Create new node. | |
245 | |
246 The implementation should make sure, the passed owner JID is stripped | |
247 of the resource (e.g. using C{owner.userhostJID()}). The passed config | |
248 is expected to have values for the fields returned by | |
249 L{getDefaultConfiguration}, as well as a value for | |
250 C{'pubsub#node_type'}. | |
251 | |
252 @param nodeIdentifier: NodeID of the new node. | |
253 @type nodeIdentifier: C{unicode} | |
254 @param owner: JID of the new nodes's owner. | |
255 @type owner: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
256 @param config: Node configuration. | |
257 @type config: C{dict} | |
258 @return: deferred that fires on creation. | |
259 """ | |
260 | |
261 | |
262 def deleteNode(nodeIdentifier): | |
263 """ | |
264 Delete a node. | |
265 | |
266 @param nodeIdentifier: NodeID of the new node. | |
267 @type nodeIdentifier: C{unicode} | |
268 @return: deferred that fires on deletion. | |
269 """ | |
270 | |
271 | |
272 def getAffiliations(entity): | |
273 """ | |
274 Get all affiliations for entity. | |
275 | |
276 The implementation should make sure, the passed owner JID is stripped | |
277 of the resource (e.g. using C{owner.userhostJID()}). | |
278 | |
279 @param entity: JID of the entity. | |
280 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
281 @return: deferred that returns a C{list} of tuples of the form | |
282 C{(nodeIdentifier, affiliation)}, where C{nodeIdentifier} is | |
283 of the type L{unicode} and C{affiliation} is one of | |
284 C{'owner'}, C{'publisher'} and C{'outcast'}. | |
285 """ | |
286 | |
287 | |
288 def getSubscriptions(entity): | |
289 """ | |
290 Get all subscriptions for an entity. | |
291 | |
292 The implementation should make sure, the passed owner JID is stripped | |
293 of the resource (e.g. using C{owner.userhostJID()}). | |
294 | |
295 @param entity: JID of the entity. | |
296 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
297 @return: deferred that returns a C{list} of tuples of the form | |
298 C{(nodeIdentifier, subscriber, state)}, where | |
299 C{nodeIdentifier} is of the type C{unicode}, C{subscriber} of | |
300 the type J{JID<twisted.words.protocols.jabber.jid.JID>}, and | |
301 C{state} is C{'subscribed'}, C{'pending'} or | |
302 C{'unconfigured'}. | |
303 """ | |
304 | |
305 | |
306 def getDefaultConfiguration(nodeType): | |
307 """ | |
308 Get the default configuration for the given node type. | |
309 | |
310 @param nodeType: Either C{'leaf'} or C{'collection'}. | |
311 @type nodeType: C{str} | |
312 @return: The default configuration. | |
313 @rtype: C{dict}. | |
314 @raises: L{idavoll.error.NoCollections} if collections are not | |
315 supported. | |
316 """ | |
317 | |
318 | |
319 | |
320 class INode(Interface): | |
321 """ | |
322 Interface to the class of objects that represent nodes. | |
323 """ | |
324 | |
325 nodeType = Attribute("""The type of this node. One of {'leaf'}, | |
326 {'collection'}.""") | |
327 nodeIdentifier = Attribute("""The node identifer of this node""") | |
328 | |
329 | |
330 def getType(): | |
331 """ | |
332 Get node's type. | |
333 | |
334 @return: C{'leaf'} or C{'collection'}. | |
335 """ | |
336 | |
337 | |
338 def getConfiguration(): | |
339 """ | |
340 Get node's configuration. | |
341 | |
342 The configuration must at least have two options: | |
343 C{pubsub#persist_items}, and C{pubsub#deliver_payloads}. | |
344 | |
345 @return: C{dict} of configuration options. | |
346 """ | |
347 | |
348 | |
349 def getMetaData(): | |
350 """ | |
351 Get node's meta data. | |
352 | |
353 The meta data must be a superset of the configuration options, and | |
354 also at least should have a C{pubsub#node_type} entry. | |
355 | |
356 @return: C{dict} of meta data. | |
357 """ | |
358 | |
359 | |
360 def setConfiguration(options): | |
361 """ | |
362 Set node's configuration. | |
363 | |
364 The elements of {options} will set the new values for those | |
365 configuration items. This means that only changing items have to | |
366 be given. | |
367 | |
368 @param options: a dictionary of configuration options. | |
369 @returns: a deferred that fires upon success. | |
370 """ | |
371 | |
372 | |
373 def getAffiliation(entity): | |
374 """ | |
375 Get affiliation of entity with this node. | |
376 | |
377 @param entity: JID of entity. | |
378 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
379 @return: deferred that returns C{'owner'}, C{'publisher'}, C{'outcast'} | |
380 or C{None}. | |
381 """ | |
382 | |
383 | |
384 def getSubscription(subscriber): | |
385 """ | |
386 Get subscription to this node of subscriber. | |
387 | |
388 @param subscriber: JID of the new subscriptions' entity. | |
389 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
390 @return: deferred that returns the subscription state (C{'subscribed'}, | |
391 C{'pending'} or C{None}). | |
392 """ | |
393 | |
394 | |
395 def getSubscriptions(state=None): | |
396 """ | |
397 Get list of subscriptions to this node. | |
398 | |
399 The optional C{state} argument filters the subscriptions to their | |
400 state. | |
401 | |
402 @param state: Subscription state filter. One of C{'subscribed'}, | |
403 C{'pending'}, C{'unconfigured'}. | |
404 @type state: C{str} | |
405 @return: a deferred that returns a C{list} of | |
406 L{wokkel.pubsub.Subscription}s. | |
407 """ | |
408 | |
409 | |
410 def addSubscription(subscriber, state, config): | |
411 """ | |
412 Add new subscription to this node with given state. | |
413 | |
414 @param subscriber: JID of the new subscriptions' entity. | |
415 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
416 @param state: C{'subscribed'} or C{'pending'} | |
417 @type state: C{str} | |
418 @param config: Subscription configuration. | |
419 @param config: C{dict} | |
420 @return: deferred that fires on subscription. | |
421 """ | |
422 | |
423 | |
424 def removeSubscription(subscriber): | |
425 """ | |
426 Remove subscription to this node. | |
427 | |
428 @param subscriber: JID of the subscriptions' entity. | |
429 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
430 @return: deferred that fires on removal. | |
431 """ | |
432 | |
433 | |
434 def isSubscribed(entity): | |
435 """ | |
436 Returns whether entity has any subscription to this node. | |
437 | |
438 Only returns C{True} when the subscription state (if present) is | |
439 C{'subscribed'} for any subscription that matches the bare JID. | |
440 | |
441 @param subscriber: bare JID of the subscriptions' entity. | |
442 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
443 @return: deferred that returns a C{bool}. | |
444 """ | |
445 | |
446 | |
447 def getAffiliations(): | |
448 """ | |
449 Get affiliations of entities with this node. | |
450 | |
451 @return: deferred that returns a C{list} of tuples (jid, affiliation), | |
452 where jid is a L(JID<twisted.words.protocols.jabber.jid.JID>) | |
453 and affiliation is one of C{'owner'}, | |
454 C{'publisher'}, C{'outcast'}. | |
455 """ | |
456 | |
457 | |
458 | |
459 class ILeafNode(Interface): | |
460 """ | |
461 Interface to the class of objects that represent leaf nodes. | |
462 """ | |
463 | |
464 def storeItems(items, publisher): | |
465 """ | |
466 Store items in persistent storage for later retrieval. | |
467 | |
468 @param items: The list of items to be stored. Each item is the | |
469 L{domish} representation of the XML fragment as defined | |
470 for C{<item/>} in the | |
471 C{http://jabber.org/protocol/pubsub} namespace. | |
472 @type items: C{list} of {domish.Element} | |
473 @param publisher: JID of the publishing entity. | |
474 @type publisher: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
475 @return: deferred that fires upon success. | |
476 """ | |
477 | |
478 | |
479 def removeItems(itemIdentifiers): | |
480 """ | |
481 Remove items by id. | |
482 | |
483 @param itemIdentifiers: C{list} of item ids. | |
484 @return: deferred that fires with a C{list} of ids of the items that | |
485 were deleted | |
486 """ | |
487 | |
488 | |
489 def getItems(maxItems=None): | |
490 """ | |
491 Get items. | |
492 | |
493 If C{maxItems} is not given, all items in the node are returned, | |
494 just like C{getItemsById}. Otherwise, C{maxItems} limits | |
495 the returned items to a maximum of that number of most recently | |
496 published items. | |
497 | |
498 @param maxItems: if given, a natural number (>0) that limits the | |
499 returned number of items. | |
500 @return: deferred that fires with a C{list} of found items. | |
501 """ | |
502 | |
503 | |
504 def getItemsById(itemIdentifiers): | |
505 """ | |
506 Get items by item id. | |
507 | |
508 Each item in the returned list is a unicode string that | |
509 represent the XML of the item as it was published, including the | |
510 item wrapper with item id. | |
511 | |
512 @param itemIdentifiers: C{list} of item ids. | |
513 @return: deferred that fires with a C{list} of found items. | |
514 """ | |
515 | |
516 | |
517 def purge(): | |
518 """ | |
519 Purge node of all items in persistent storage. | |
520 | |
521 @return: deferred that fires when the node has been purged. | |
522 """ | |
523 | |
524 | |
525 | |
526 class IGatewayStorage(Interface): | |
527 | |
528 def addCallback(service, nodeIdentifier, callback): | |
529 """ | |
530 Register a callback URI. | |
531 | |
532 The registered HTTP callback URI will have an Atom Entry documented | |
533 POSTed to it upon receiving a notification for the given pubsub node. | |
534 | |
535 @param service: The XMPP entity that holds the node. | |
536 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
537 @param nodeIdentifier: The identifier of the publish-subscribe node. | |
538 @type nodeIdentifier: C{unicode}. | |
539 @param callback: The callback URI to be registered. | |
540 @type callback: C{str}. | |
541 @rtype: L{Deferred<twisted.internet.defer.Deferred>} | |
542 """ | |
543 | |
544 def removeCallback(service, nodeIdentifier, callback): | |
545 """ | |
546 Remove a registered callback URI. | |
547 | |
548 The returned deferred will fire with a boolean that signals wether or | |
549 not this was the last callback unregistered for this node. | |
550 | |
551 @param service: The XMPP entity that holds the node. | |
552 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
553 @param nodeIdentifier: The identifier of the publish-subscribe node. | |
554 @type nodeIdentifier: C{unicode}. | |
555 @param callback: The callback URI to be unregistered. | |
556 @type callback: C{str}. | |
557 @rtype: L{Deferred<twisted.internet.defer.Deferred>} | |
558 """ | |
559 | |
560 def getCallbacks(service, nodeIdentifier): | |
561 """ | |
562 Get the callbacks registered for this node. | |
563 | |
564 Returns a deferred that fires with the set of HTTP callback URIs | |
565 registered for this node. | |
566 | |
567 @param service: The XMPP entity that holds the node. | |
568 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
569 @param nodeIdentifier: The identifier of the publish-subscribe node. | |
570 @type nodeIdentifier: C{unicode}. | |
571 @rtype: L{Deferred<twisted.internet.defer.Deferred>} | |
572 """ | |
573 | |
574 | |
575 def hasCallbacks(service, nodeIdentifier): | |
576 """ | |
577 Return wether there are callbacks registered for a node. | |
578 | |
579 @param service: The XMPP entity that holds the node. | |
580 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>} | |
581 @param nodeIdentifier: The identifier of the publish-subscribe node. | |
582 @type nodeIdentifier: C{unicode}. | |
583 @returns: Deferred that fires with a boolean. | |
584 @rtype: L{Deferred<twisted.internet.defer.Deferred>} | |
585 """ |