source: wokkel/iwokkel.py @ 59:e984452207e0

Last change on this file since 59:e984452207e0 was 59:e984452207e0, checked in by Ralph Meijer <ralphm@…>, 12 years ago

Provide PubSubResource?, modeled after Twisted Web resources.

Author: ralphm.
Fixes #47.

This should make it rather easy to make publish-subscribe enabled services.

File size: 26.5 KB
Line 
1# Copyright (c) 2003-2008 Ralph Meijer
2# See LICENSE for details.
3
4"""
5Wokkel interfaces.
6"""
7
8from zope.interface import Attribute, Interface
9
10class IXMPPHandler(Interface):
11    """
12    Interface for XMPP protocol handlers.
13
14    Objects that provide this interface can be added to a stream manager to
15    handle of (part of) an XMPP extension protocol.
16    """
17
18    parent = Attribute("""XML stream manager for this handler""")
19    xmlstream = Attribute("""The managed XML stream""")
20
21    def setHandlerParent(parent):
22        """
23        Set the parent of the handler.
24
25        @type parent: L{IXMPPHandlerCollection}
26        """
27
28
29    def disownHandlerParent(parent):
30        """
31        Remove the parent of the handler.
32
33        @type parent: L{IXMPPHandlerCollection}
34        """
35
36
37    def makeConnection(xs):
38        """
39        A connection over the underlying transport of the XML stream has been
40        established.
41
42        At this point, no traffic has been exchanged over the XML stream
43        given in C{xs}.
44
45        This should setup L{xmlstream} and call L{connectionMade}.
46
47        @type xs: L{XmlStream<twisted.words.protocols.jabber.XmlStream>}
48        """
49
50
51    def connectionMade():
52        """
53        Called after a connection has been established.
54
55        This method can be used to change properties of the XML Stream, its
56        authenticator or the stream manager prior to stream initialization
57        (including authentication).
58        """
59
60
61    def connectionInitialized():
62        """
63        The XML stream has been initialized.
64
65        At this point, authentication was successful, and XML stanzas can be
66        exchanged over the XML stream L{xmlstream}. This method can be
67        used to setup observers for incoming stanzas.
68        """
69
70
71    def connectionLost(reason):
72        """
73        The XML stream has been closed.
74
75        Subsequent use of L{parent.send} will result in data being queued
76        until a new connection has been established.
77
78        @type reason: L{twisted.python.failure.Failure}
79        """
80
81
82
83class IXMPPHandlerCollection(Interface):
84    """
85    Collection of handlers.
86
87    Contain several handlers and manage their connection.
88    """
89
90    def __iter__():
91        """
92        Get an iterator over all child handlers.
93        """
94
95
96    def addHandler(handler):
97        """
98        Add a child handler.
99
100        @type handler: L{IXMPPHandler}
101        """
102
103
104    def removeHandler(handler):
105        """
106        Remove a child handler.
107
108        @type handler: L{IXMPPHandler}
109        """
110
111
112
113class IDisco(Interface):
114    """
115    Interface for XMPP service discovery.
116    """
117
118    def getDiscoInfo(requestor, target, nodeIdentifier=''):
119        """
120        Get identity and features from this entity, node.
121
122        @param requestor: The entity the request originated from.
123        @type requestor: L{jid.JID}
124        @param target: The target entity to which the request is made.
125        @type target: L{jid.JID}
126        @param nodeIdentifier: The optional identifier of the node at this
127                               entity to retrieve the identify and features of.
128                               The default is C{''}, meaning the root node.
129        @type nodeIdentifier: C{unicode}
130        """
131
132    def getDiscoItems(requestor, target, nodeIdentifier=''):
133        """
134        Get contained items for this entity, node.
135
136        @param requestor: The entity the request originated from.
137        @type requestor: L{jid.JID}
138        @param target: The target entity to which the request is made.
139        @type target: L{jid.JID}
140        @param nodeIdentifier: The optional identifier of the node at this
141                               entity to retrieve the identify and features of.
142                               The default is C{''}, meaning the root node.
143        @type nodeIdentifier: C{unicode}
144        """
145
146
147class IPubSubClient(Interface):
148
149    def itemsReceived(event):
150        """
151        Called when an items notification has been received for a node.
152
153        An item can be an element named C{item} or C{retract}. Respectively,
154        they signal an item being published or retracted, optionally
155        accompanied with an item identifier in the C{id} attribute.
156
157        @param event: The items event.
158        @type event: L{ItemsEvent<wokkel.pubsub.ItemsEvent>}
159        """
160
161
162    def deleteReceived(event):
163        """
164        Called when a deletion notification has been received for a node.
165
166        @param event: The items event.
167        @type event: L{ItemsEvent<wokkel.pubsub.DeleteEvent>}
168        """
169
170
171    def purgeReceived(event):
172        """
173        Called when a purge notification has been received for a node.
174
175        Upon receiving this notification all items associated should be
176        considered retracted.
177
178        @param event: The items event.
179        @type event: L{ItemsEvent<wokkel.pubsub.PurgeEvent>}
180        """
181
182    def createNode(service, nodeIdentifier=None):
183        """
184        Create a new publish subscribe node.
185
186        @param service: The publish-subscribe service entity.
187        @type service: L{jid.JID}
188        @param nodeIdentifier: Optional suggestion for the new node's
189                               identifier. If omitted, the creation of an
190                               instant node will be attempted.
191        @type nodeIdentifier: L{unicode}
192        @return: a deferred that fires with the identifier of the newly created
193                 node. Note that this can differ from the suggested identifier
194                 if the publish subscribe service chooses to modify or ignore
195                 the suggested identifier.
196        @rtype: L{defer.Deferred}
197        """
198
199    def deleteNode(service, nodeIdentifier):
200        """
201        Delete a node.
202
203        @param service: The publish-subscribe service entity.
204        @type service: L{jid.JID}
205        @param nodeIdentifier: Identifier of the node to be deleted.
206        @type nodeIdentifier: L{unicode}
207        @rtype: L{defer.Deferred}
208        """
209
210    def subscribe(service, nodeIdentifier, subscriber):
211        """
212        Subscribe to a node with a given JID.
213
214        @param service: The publish-subscribe service entity.
215        @type service: L{jid.JID}
216        @param nodeIdentifier: Identifier of the node to subscribe to.
217        @type nodeIdentifier: L{unicode}
218        @param subscriber: JID to subscribe to the node.
219        @type subscriber: L{jid.JID}
220        @rtype: L{defer.Deferred}
221        """
222
223    def unsubscribe(service, nodeIdentifier, subscriber):
224        """
225        Unsubscribe from a node with a given JID.
226
227        @param service: The publish-subscribe service entity.
228        @type service: L{jid.JID}
229        @param nodeIdentifier: Identifier of the node to unsubscribe from.
230        @type nodeIdentifier: L{unicode}
231        @param subscriber: JID to unsubscribe from the node.
232        @type subscriber: L{jid.JID}
233        @rtype: L{defer.Deferred}
234        """
235
236    def publish(service, nodeIdentifier, items=[]):
237        """
238        Publish to a node.
239
240        Node that the C{items} parameter is optional, because so-called
241        transient, notification-only nodes do not use items and publish
242        actions only signify a change in some resource.
243
244        @param service: The publish-subscribe service entity.
245        @type service: L{jid.JID}
246        @param nodeIdentifier: Identifier of the node to publish to.
247        @type nodeIdentifier: L{unicode}
248        @param items: List of item elements.
249        @type items: L{list} of L{Item}
250        @rtype: L{defer.Deferred}
251        """
252
253
254class IPubSubService(Interface):
255    """
256    Interface for an XMPP Publish Subscribe Service.
257
258    All methods that are called as the result of an XMPP request are to
259    return a deferred that fires when the requested action has been performed.
260    Alternatively, exceptions maybe raised directly or by calling C{errback}
261    on the returned deferred.
262    """
263
264    def notifyPublish(service, nodeIdentifier, notifications):
265        """
266        Send out notifications for a publish event.
267
268        @param service: The entity the notifications will originate from.
269        @type service: L{jid.JID}
270        @param nodeIdentifier: The identifier of the node that was published
271                               to.
272        @type nodeIdentifier: C{unicode}
273        @param notifications: The notifications as tuples of subscriber, the
274                              list of subscriptions and the list of items to be
275                              notified.
276        @type notifications: C{list} of (L{jid.JID}, C{list} of
277                             L{Subscription<wokkel.pubsub.Subscription>},
278                             C{list} of L{domish.Element})
279        """
280
281
282    def notifyDelete(service, nodeIdentifier, subscribers,
283                     redirectURI=None):
284        """
285        Send out node deletion notifications.
286
287        @param service: The entity the notifications will originate from.
288        @type service: L{jid.JID}
289        @param nodeIdentifier: The identifier of the node that was deleted.
290        @type nodeIdentifier: C{unicode}
291        @param subscribers: The subscribers for which a notification should
292                            be sent out.
293        @type subscribers: C{list} of L{jid.JID}
294        @param redirectURI: Optional XMPP URI of another node that subscribers
295                            are redirected to.
296        @type redirectURI: C{str}
297        """
298
299    def publish(requestor, service, nodeIdentifier, items):
300        """
301        Called when a publish request has been received.
302
303        @param requestor: The entity the request originated from.
304        @type requestor: L{jid.JID}
305        @param service: The entity the request was addressed to.
306        @type service: L{jid.JID}
307        @param nodeIdentifier: The identifier of the node to publish to.
308        @type nodeIdentifier: C{unicode}
309        @param items: The items to be published as L{domish} elements.
310        @type items: C{list} of C{domish.Element}
311        @return: deferred that fires on success.
312        @rtype: L{defer.Deferred}
313        """
314
315    def subscribe(requestor, service, nodeIdentifier, subscriber):
316        """
317        Called when a subscribe request has been received.
318
319        @param requestor: The entity the request originated from.
320        @type requestor: L{jid.JID}
321        @param service: The entity the request was addressed to.
322        @type service: L{jid.JID}
323        @param nodeIdentifier: The identifier of the node to subscribe to.
324        @type nodeIdentifier: C{unicode}
325        @param subscriber: The entity to be subscribed.
326        @type subscriber: L{jid.JID}
327        @return: A deferred that fires with a
328                 L{Subscription<wokkel.pubsub.Subscription>}.
329        @rtype: L{defer.Deferred}
330        """
331
332    def unsubscribe(requestor, service, nodeIdentifier, subscriber):
333        """
334        Called when a subscribe request has been received.
335
336        @param requestor: The entity the request originated from.
337        @type requestor: L{jid.JID}
338        @param service: The entity the request was addressed to.
339        @type service: L{jid.JID}
340        @param nodeIdentifier: The identifier of the node to unsubscribe from.
341        @type nodeIdentifier: C{unicode}
342        @param subscriber: The entity to be unsubscribed.
343        @type subscriber: L{jid.JID}
344        @return: A deferred that fires with C{None} when unsubscription has
345                 succeeded.
346        @rtype: L{defer.Deferred}
347        """
348
349    def subscriptions(requestor, service):
350        """
351        Called when a subscriptions retrieval request has been received.
352
353        @param requestor: The entity the request originated from.
354        @type requestor: L{jid.JID}
355        @param service: The entity the request was addressed to.
356        @type service: L{jid.JID}
357        @return: A deferred that fires with a C{list} of subscriptions as
358                 L{Subscription<wokkel.pubsub.Subscription>}.
359        @rtype: L{defer.Deferred}
360        """
361
362    def affiliations(requestor, service):
363        """
364        Called when a affiliations retrieval request has been received.
365
366        @param requestor: The entity the request originated from.
367        @type requestor: L{jid.JID}
368        @param service: The entity the request was addressed to.
369        @type service: L{jid.JID}
370        @return: A deferred that fires with a C{list} of affiliations as
371                 C{tuple}s of (node identifier as C{unicode}, affiliation state
372                 as C{str}). The affiliation can be C{'owner'}, C{'publisher'},
373                 or C{'outcast'}.
374        @rtype: L{defer.Deferred}
375        """
376
377    def create(requestor, service, nodeIdentifier):
378        """
379        Called when a node creation request has been received.
380
381        @param requestor: The entity the request originated from.
382        @type requestor: L{jid.JID}
383        @param service: The entity the request was addressed to.
384        @type service: L{jid.JID}
385        @param nodeIdentifier: The suggestion for the identifier of the node to
386                               be created. If the request did not include a
387                               suggestion for the node identifier, the value
388                               is C{None}.
389        @type nodeIdentifier: C{unicode} or C{NoneType}
390        @return: A deferred that fires with a C{unicode} that represents
391                 the identifier of the new node.
392        @rtype: L{defer.Deferred}
393        """
394
395    def getConfigurationOptions():
396        """
397        Retrieve all known node configuration options.
398
399        The returned dictionary holds the possible node configuration options
400        by option name. The value of each entry represents the specifics for
401        that option in a dictionary:
402
403         - C{'type'} (C{str}): The option's type (see
404           L{Field<wokkel.data_form.Field>}'s doc string for possible values).
405         - C{'label'} (C{unicode}): A human readable label for this option.
406         - C{'options'} (C{dict}): Optional list of possible values for this
407           option.
408
409        Example::
410
411            {
412            "pubsub#persist_items":
413                {"type": "boolean",
414                 "label": "Persist items to storage"},
415            "pubsub#deliver_payloads":
416                {"type": "boolean",
417                 "label": "Deliver payloads with event notifications"},
418            "pubsub#send_last_published_item":
419                {"type": "list-single",
420                 "label": "When to send the last published item",
421                 "options": {
422                     "never": "Never",
423                     "on_sub": "When a new subscription is processed"}
424                }
425            }
426
427        @rtype: C{dict}.
428        """
429
430    def getDefaultConfiguration(requestor, service, nodeType):
431        """
432        Called when a default node configuration request has been received.
433
434        @param requestor: The entity the request originated from.
435        @type requestor: L{jid.JID}
436        @param service: The entity the request was addressed to.
437        @type service: L{jid.JID}
438        @param nodeType: The type of node for which the configuration is
439                         retrieved, C{'leaf'} or C{'collection'}.
440        @type nodeType: C{str}
441        @return: A deferred that fires with a C{dict} representing the default
442                 node configuration. Keys are C{str}s that represent the
443                 field name. Values can be of types C{unicode}, C{int} or
444                 C{bool}.
445        @rtype: L{defer.Deferred}
446        """
447
448    def getConfiguration(requestor, service, nodeIdentifier):
449        """
450        Called when a node configuration retrieval request has been received.
451
452        @param requestor: The entity the request originated from.
453        @type requestor: L{jid.JID}
454        @param service: The entity the request was addressed to.
455        @type service: L{jid.JID}
456        @param nodeIdentifier: The identifier of the node to retrieve the
457                               configuration from.
458        @type nodeIdentifier: C{unicode}
459        @return: A deferred that fires with a C{dict} representing the node
460                 configuration. Keys are C{str}s that represent the field name.
461                 Values can be of types C{unicode}, C{int} or C{bool}.
462        @rtype: L{defer.Deferred}
463        """
464
465    def setConfiguration(requestor, service, nodeIdentifier, options):
466        """
467        Called when a node configuration change request has been received.
468
469        @param requestor: The entity the request originated from.
470        @type requestor: L{jid.JID}
471        @param service: The entity the request was addressed to.
472        @type service: L{jid.JID}
473        @param nodeIdentifier: The identifier of the node to change the
474                               configuration of.
475        @type nodeIdentifier: C{unicode}
476        @return: A deferred that fires with C{None} when the node's
477                 configuration has been changed.
478        @rtype: L{defer.Deferred}
479        """
480
481    def items(requestor, service, nodeIdentifier, maxItems, itemIdentifiers):
482        """
483        Called when a items retrieval request has been received.
484
485        @param requestor: The entity the request originated from.
486        @type requestor: L{jid.JID}
487        @param service: The entity the request was addressed to.
488        @type service: L{jid.JID}
489        @param nodeIdentifier: The identifier of the node to retrieve items
490                               from.
491        @type nodeIdentifier: C{unicode}
492        """
493
494    def retract(requestor, service, nodeIdentifier, itemIdentifiers):
495        """
496        Called when a item retraction request has been received.
497
498        @param requestor: The entity the request originated from.
499        @type requestor: L{jid.JID}
500        @param service: The entity the request was addressed to.
501        @type service: L{jid.JID}
502        @param nodeIdentifier: The identifier of the node to retract items
503                               from.
504        @type nodeIdentifier: C{unicode}
505        """
506
507    def purge(requestor, service, nodeIdentifier):
508        """
509        Called when a node purge request has been received.
510
511        @param requestor: The entity the request originated from.
512        @type requestor: L{jid.JID}
513        @param service: The entity the request was addressed to.
514        @type service: L{jid.JID}
515        @param nodeIdentifier: The identifier of the node to be purged.
516        @type nodeIdentifier: C{unicode}
517        """
518
519    def delete(requestor, service, nodeIdentifier):
520        """
521        Called when a node deletion request has been received.
522
523        @param requestor: The entity the request originated from.
524        @type requestor: L{jid.JID}
525        @param service: The entity the request was addressed to.
526        @type service: L{jid.JID}
527        @param nodeIdentifier: The identifier of the node to be delete.
528        @type nodeIdentifier: C{unicode}
529        """
530
531
532
533class IPubSubResource(Interface):
534
535    def locateResource(request):
536        """
537        Locate a resource that will handle the request.
538
539        @param request: The publish-subscribe request.
540        @type request: L{wokkel.pubsub.PubSubRequest}
541        """
542
543
544    def getInfo(requestor, service, nodeIdentifier):
545        """
546        Get node type and meta data.
547
548        @param requestor: The entity the request originated from.
549        @type requestor: L{jid.JID}
550        @param service: The publish-subscribe service entity.
551        @type service: L{jid.JID}
552        @param nodeIdentifier: Identifier of the node to request the info for.
553        @type nodeIdentifier: L{unicode}
554        @return: A deferred that fires with a dictionary. If not empty,
555                 it must have the keys C{'type'} and C{'meta-data'} to keep
556                 respectively the node type and a dictionary with the meta
557                 data for that node.
558        @rtype: L{defer.Deferred}
559        """
560
561
562    def getNodes(requestor, service, nodeIdentifier):
563        """
564        Get all nodes contained by this node.
565
566        @param requestor: The entity the request originated from.
567        @type requestor: L{jid.JID}
568        @param service: The publish-subscribe service entity.
569        @type service: L{jid.JID}
570        @param nodeIdentifier: Identifier of the node to request the childs for.
571        @type nodeIdentifier: L{unicode}
572        @return: A deferred that fires with a list of child node identifiers.
573        @rtype: L{defer.Deferred}
574        """
575
576
577    def getConfigurationOptions():
578        """
579        Retrieve all known node configuration options.
580
581        The returned dictionary holds the possible node configuration options
582        by option name. The value of each entry represents the specifics for
583        that option in a dictionary:
584
585         - C{'type'} (C{str}): The option's type (see
586           L{Field<wokkel.data_form.Field>}'s doc string for possible values).
587         - C{'label'} (C{unicode}): A human readable label for this option.
588         - C{'options'} (C{dict}): Optional list of possible values for this
589           option.
590
591        Example::
592
593            {
594            "pubsub#persist_items":
595                {"type": "boolean",
596                 "label": "Persist items to storage"},
597            "pubsub#deliver_payloads":
598                {"type": "boolean",
599                 "label": "Deliver payloads with event notifications"},
600            "pubsub#send_last_published_item":
601                {"type": "list-single",
602                 "label": "When to send the last published item",
603                 "options": {
604                     "never": "Never",
605                     "on_sub": "When a new subscription is processed"}
606                }
607            }
608
609        @rtype: C{dict}.
610        """
611
612
613    def publish(request):
614        """
615        Called when a publish request has been received.
616
617        @param request: The publish-subscribe request.
618        @type request: L{wokkel.pubsub.PubSubRequest}
619        @return: deferred that fires on success.
620        @rtype: L{defer.Deferred}
621        """
622
623
624    def subscribe(request):
625        """
626        Called when a subscribe request has been received.
627
628        @param request: The publish-subscribe request.
629        @type request: L{wokkel.pubsub.PubSubRequest}
630        @return: A deferred that fires with a
631                 L{Subscription<wokkel.pubsub.Subscription>}.
632        @rtype: L{defer.Deferred}
633        """
634
635
636    def unsubscribe(request):
637        """
638        Called when a subscribe request has been received.
639
640        @param request: The publish-subscribe request.
641        @type request: L{wokkel.pubsub.PubSubRequest}
642        @return: A deferred that fires with C{None} when unsubscription has
643                 succeeded.
644        @rtype: L{defer.Deferred}
645        """
646
647
648    def subscriptions(request):
649        """
650        Called when a subscriptions retrieval request has been received.
651
652        @param request: The publish-subscribe request.
653        @type request: L{wokkel.pubsub.PubSubRequest}
654        @return: A deferred that fires with a C{list} of subscriptions as
655                 L{Subscription<wokkel.pubsub.Subscription>}.
656        @rtype: L{defer.Deferred}
657        """
658
659
660    def affiliations(request):
661        """
662        Called when a affiliations retrieval request has been received.
663
664        @param request: The publish-subscribe request.
665        @type request: L{wokkel.pubsub.PubSubRequest}
666        @return: A deferred that fires with a C{list} of affiliations as
667                 C{tuple}s of (node identifier as C{unicode}, affiliation state
668                 as C{str}). The affiliation can be C{'owner'}, C{'publisher'},
669                 or C{'outcast'}.
670        @rtype: L{defer.Deferred}
671        """
672
673
674    def create(request):
675        """
676        Called when a node creation request has been received.
677
678        @param request: The publish-subscribe request.
679        @type request: L{wokkel.pubsub.PubSubRequest}
680        @return: A deferred that fires with a C{unicode} that represents
681                 the identifier of the new node.
682        @rtype: L{defer.Deferred}
683        """
684
685
686    def default(request):
687        """
688        Called when a default node configuration request has been received.
689
690        @param request: The publish-subscribe request.
691        @type request: L{wokkel.pubsub.PubSubRequest}
692        @return: A deferred that fires with a C{dict} representing the default
693                 node configuration. Keys are C{str}s that represent the
694                 field name. Values can be of types C{unicode}, C{int} or
695                 C{bool}.
696        @rtype: L{defer.Deferred}
697        """
698
699
700    def configureGet(request):
701        """
702        Called when a node configuration retrieval request has been received.
703
704        @param request: The publish-subscribe request.
705        @type request: L{wokkel.pubsub.PubSubRequest}
706        @return: A deferred that fires with a C{dict} representing the node
707                 configuration. Keys are C{str}s that represent the field name.
708                 Values can be of types C{unicode}, C{int} or C{bool}.
709        @rtype: L{defer.Deferred}
710        """
711
712
713    def configureSet(request):
714        """
715        Called when a node configuration change request has been received.
716
717        @param request: The publish-subscribe request.
718        @type request: L{wokkel.pubsub.PubSubRequest}
719        @return: A deferred that fires with C{None} when the node's
720                 configuration has been changed.
721        @rtype: L{defer.Deferred}
722        """
723
724
725    def items(request):
726        """
727        Called when a items retrieval request has been received.
728
729        @param request: The publish-subscribe request.
730        @type request: L{wokkel.pubsub.PubSubRequest}
731        @return: A deferred that fires with a C{list} of L{pubsub.Item}.
732        @rtype: L{defer.Deferred}
733        """
734
735
736    def retract(request):
737        """
738        Called when a item retraction request has been received.
739
740        @param request: The publish-subscribe request.
741        @type request: L{wokkel.pubsub.PubSubRequest}
742        @return: A deferred that fires with C{None} when the given items have
743                 been retracted.
744        @rtype: L{defer.Deferred}
745        """
746
747
748    def purge(request):
749        """
750        Called when a node purge request has been received.
751
752        @param request: The publish-subscribe request.
753        @type request: L{wokkel.pubsub.PubSubRequest}
754        @return: A deferred that fires with C{None} when the node has been
755                 purged.
756        @rtype: L{defer.Deferred}
757        """
758
759
760    def delete(request):
761        """
762        Called when a node deletion request has been received.
763
764        @param request: The publish-subscribe request.
765        @type request: L{wokkel.pubsub.PubSubRequest}
766        @return: A deferred that fires with C{None} when the node has been
767                 deleted.
768        @rtype: L{defer.Deferred}
769        """
Note: See TracBrowser for help on using the repository browser.