comparison idavoll/iidavoll.py @ 206:274a45d2a5ab

Implement root collection that includes all leaf nodes.
author Ralph Meijer <ralphm@ik.nu>
date Mon, 04 Aug 2008 13:47:10 +0000
parents b4bf0a5ce50d
children
comparison
equal deleted inserted replaced
205:e6b710bf2b24 206:274a45d2a5ab
11 """ Interface to a backend service of a pubsub service. """ 11 """ Interface to a backend service of a pubsub service. """
12 12
13 13
14 def __init__(storage): 14 def __init__(storage):
15 """ 15 """
16 @param storage: L{storage} object. 16 @param storage: Object providing L{IStorage}.
17 """ 17 """
18 18
19 19
20 def supportsPublisherAffiliation(): 20 def supportsPublisherAffiliation():
21 """ Reports if the backend supports the publisher affiliation. 21 """ Reports if the backend supports the publisher affiliation.
162 162
163 def registerNotifier(observerfn, *args, **kwargs): 163 def registerNotifier(observerfn, *args, **kwargs):
164 """ Register callback which is called for notification. """ 164 """ Register callback which is called for notification. """
165 165
166 166
167 def getNotificationList(nodeIdentifier, items): 167 def getNotifications(nodeIdentifier, items):
168 """ 168 """
169 Get list of entities to notify. 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}
170 """ 199 """
171 200
172 201
173 def getItems(nodeIdentifier, requestor, maxItems=None, itemIdentifiers=[]): 202 def getItems(nodeIdentifier, requestor, maxItems=None, itemIdentifiers=[]):
174 """ Retrieve items from persistent storage 203 """ Retrieve items from persistent storage
195 def getNode(nodeIdentifier): 224 def getNode(nodeIdentifier):
196 """ 225 """
197 Get Node. 226 Get Node.
198 227
199 @param nodeIdentifier: NodeID of the desired node. 228 @param nodeIdentifier: NodeID of the desired node.
200 @type nodeIdentifier: L{str} 229 @type nodeIdentifier: C{str}
201 @return: deferred that returns a L{Node} object. 230 @return: deferred that returns a L{INode} providing object.
202 """ 231 """
203 232
204 233
205 def getNodeIds(): 234 def getNodeIds():
206 """ 235 """
207 Return all NodeIDs. 236 Return all NodeIDs.
208 237
209 @return: deferred that returns a list of NodeIDs (L{str}). 238 @return: deferred that returns a list of NodeIDs (C{unicode}).
210 """ 239 """
211 240
212 241
213 def createNode(nodeIdentifier, owner, config=None): 242 def createNode(nodeIdentifier, owner, config):
214 """ 243 """
215 Create new node. 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.
216 275
217 The implementation should make sure, the passed owner JID is stripped 276 The implementation should make sure, the passed owner JID is stripped
218 of the resource (e.g. using C{owner.userhostJID()}). 277 of the resource (e.g. using C{owner.userhostJID()}).
219 278
220 @param nodeIdentifier: NodeID of the new node. 279 @param entity: JID of the entity.
221 @type nodeIdentifier: L{str} 280 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
222 @param owner: JID of the new nodes's owner. 281 @return: deferred that returns a C{list} of tuples of the form
223 @type owner: L{jid.JID} 282 C{(nodeIdentifier, affiliation)}, where C{nodeIdentifier} is
224 @param config: Configuration 283 of the type L{unicode} and C{affiliation} is one of
225 @return: deferred that fires on creation. 284 C{'owner'}, C{'publisher'} and C{'outcast'}.
226 """ 285 """
227 286
228 287
229 def deleteNode(nodeIdentifier): 288 def getSubscriptions(entity):
230 """ 289 """
231 Delete a node. 290 Get all subscriptions for an entity.
232
233 @param nodeIdentifier: NodeID of the new node.
234 @type nodeIdentifier: L{str}
235 @return: deferred that fires on deletion.
236 """
237
238
239 def getAffiliations(entity):
240 """
241 Get all affiliations for entity.
242 291
243 The implementation should make sure, the passed owner JID is stripped 292 The implementation should make sure, the passed owner JID is stripped
244 of the resource (e.g. using C{owner.userhostJID()}). 293 of the resource (e.g. using C{owner.userhostJID()}).
245 294
246 @param entity: JID of the entity. 295 @param entity: JID of the entity.
247 @type entity: L{jid.JID} 296 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
248 @return: deferred that returns a L{list} of tuples of the form 297 @return: deferred that returns a C{list} of tuples of the form
249 C{(nodeIdentifier, affiliation)}, where C{nodeIdentifier} is
250 of the type L{str} and C{affiliation} is one of C{'owner'},
251 C{'publisher'} and C{'outcast'}.
252 """
253
254
255 def getSubscriptions(entity):
256 """
257 Get all subscriptions for an entity.
258
259 The implementation should make sure, the passed owner JID is stripped
260 of the resource (e.g. using C{owner.userhostJID()}).
261
262 @param entity: JID of the entity.
263 @type entity: L{jid.JID}
264 @return: deferred that returns a L{list} of tuples of the form
265 C{(nodeIdentifier, subscriber, state)}, where 298 C{(nodeIdentifier, subscriber, state)}, where
266 C{nodeIdentifier} is of the type L{str}, C{subscriber} of the 299 C{nodeIdentifier} is of the type C{unicode}, C{subscriber} of
267 type {jid.JID}, and C{state} is C{'subscribed'} or 300 the type J{JID<twisted.words.protocols.jabber.jid.JID>}, and
268 C{'pending'}. 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.
269 """ 316 """
270 317
271 318
272 319
273 class INode(Interface): 320 class INode(Interface):
293 Get node's configuration. 340 Get node's configuration.
294 341
295 The configuration must at least have two options: 342 The configuration must at least have two options:
296 C{pubsub#persist_items}, and C{pubsub#deliver_payloads}. 343 C{pubsub#persist_items}, and C{pubsub#deliver_payloads}.
297 344
298 @return: L{dict} of configuration options. 345 @return: C{dict} of configuration options.
299 """ 346 """
300 347
301 348
302 def getMetaData(): 349 def getMetaData():
303 """ 350 """
304 Get node's meta data. 351 Get node's meta data.
305 352
306 The meta data must be a superset of the configuration options, and 353 The meta data must be a superset of the configuration options, and
307 also at least should have a C{pubsub#node_type} entry. 354 also at least should have a C{pubsub#node_type} entry.
308 355
309 @return: L{dict} of meta data. 356 @return: C{dict} of meta data.
310 """ 357 """
311 358
312 359
313 def setConfiguration(options): 360 def setConfiguration(options):
314 """ 361 """
326 def getAffiliation(entity): 373 def getAffiliation(entity):
327 """ 374 """
328 Get affiliation of entity with this node. 375 Get affiliation of entity with this node.
329 376
330 @param entity: JID of entity. 377 @param entity: JID of entity.
331 @type entity: L{jid.JID} 378 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
332 @return: deferred that returns C{'owner'}, C{'publisher'}, C{'outcast'} 379 @return: deferred that returns C{'owner'}, C{'publisher'}, C{'outcast'}
333 or C{None}. 380 or C{None}.
334 """ 381 """
335 382
336 383
337 def getSubscription(subscriber): 384 def getSubscription(subscriber):
338 """ 385 """
339 Get subscription to this node of subscriber. 386 Get subscription to this node of subscriber.
340 387
341 @param subscriber: JID of the new subscriptions' entity. 388 @param subscriber: JID of the new subscriptions' entity.
342 @type subscriber: L{jid.JID} 389 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
343 @return: deferred that returns the subscription state (C{'subscribed'}, 390 @return: deferred that returns the subscription state (C{'subscribed'},
344 C{'pending'} or C{None}). 391 C{'pending'} or C{None}).
345 """ 392 """
346 393
347 394
348 def addSubscription(subscriber, state): 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):
349 """ 411 """
350 Add new subscription to this node with given state. 412 Add new subscription to this node with given state.
351 413
352 @param subscriber: JID of the new subscriptions' entity. 414 @param subscriber: JID of the new subscriptions' entity.
353 @type subscriber: L{jid.JID} 415 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
354 @param state: C{'subscribed'} or C{'pending'} 416 @param state: C{'subscribed'} or C{'pending'}
355 @type state: L{str} 417 @type state: C{str}
418 @param config: Subscription configuration.
419 @param config: C{dict}
356 @return: deferred that fires on subscription. 420 @return: deferred that fires on subscription.
357 """ 421 """
358 422
359 423
360 def removeSubscription(subscriber): 424 def removeSubscription(subscriber):
361 """ 425 """
362 Remove subscription to this node. 426 Remove subscription to this node.
363 427
364 @param subscriber: JID of the subscriptions' entity. 428 @param subscriber: JID of the subscriptions' entity.
365 @type subscriber: L{jid.JID} 429 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
366 @return: deferred that fires on removal. 430 @return: deferred that fires on removal.
367 """
368
369
370 def getSubscribers():
371 """
372 Get list of subscribers to this node.
373
374 Retrieves the list of entities that have a subscription to this
375 node. That is, having the state C{'subscribed'}.
376
377 @return: a deferred that returns a L{list} of L{jid.JID}s.
378 """ 431 """
379 432
380 433
381 def isSubscribed(entity): 434 def isSubscribed(entity):
382 """ 435 """
384 437
385 Only returns C{True} when the subscription state (if present) is 438 Only returns C{True} when the subscription state (if present) is
386 C{'subscribed'} for any subscription that matches the bare JID. 439 C{'subscribed'} for any subscription that matches the bare JID.
387 440
388 @param subscriber: bare JID of the subscriptions' entity. 441 @param subscriber: bare JID of the subscriptions' entity.
389 @type subscriber: L{jid.JID} 442 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
390 @return: deferred that returns a L{bool}. 443 @return: deferred that returns a C{bool}.
391 """ 444 """
392 445
393 446
394 def getAffiliations(): 447 def getAffiliations():
395 """ 448 """
396 Get affiliations of entities with this node. 449 Get affiliations of entities with this node.
397 450
398 @return: deferred that returns a L{list} of tuples (jid, affiliation), 451 @return: deferred that returns a C{list} of tuples (jid, affiliation),
399 where jid is a L(jid.JID) and affiliation is one of C{'owner'}, 452 where jid is a L(JID<twisted.words.protocols.jabber.jid.JID>)
453 and affiliation is one of C{'owner'},
400 C{'publisher'}, C{'outcast'}. 454 C{'publisher'}, C{'outcast'}.
401 """ 455 """
402 456
403 457
404 458
413 467
414 @param items: The list of items to be stored. Each item is the 468 @param items: The list of items to be stored. Each item is the
415 L{domish} representation of the XML fragment as defined 469 L{domish} representation of the XML fragment as defined
416 for C{<item/>} in the 470 for C{<item/>} in the
417 C{http://jabber.org/protocol/pubsub} namespace. 471 C{http://jabber.org/protocol/pubsub} namespace.
418 @type items: L{list} of {domish.Element} 472 @type items: C{list} of {domish.Element}
419 @param publisher: JID of the publishing entity. 473 @param publisher: JID of the publishing entity.
420 @type publisher: L{jid.JID} 474 @type publisher: L{JID<twisted.words.protocols.jabber.jid.JID>}
421 @return: deferred that fires upon success. 475 @return: deferred that fires upon success.
422 """ 476 """
423 477
424 478
425 def removeItems(itemIdentifiers): 479 def removeItems(itemIdentifiers):
426 """ 480 """
427 Remove items by id. 481 Remove items by id.
428 482
429 @param itemIdentifiers: L{list} of item ids. 483 @param itemIdentifiers: C{list} of item ids.
430 @return: deferred that fires with a L{list} of ids of the items that 484 @return: deferred that fires with a C{list} of ids of the items that
431 were deleted 485 were deleted
432 """ 486 """
433 487
434 488
435 def getItems(maxItems=None): 489 def getItems(maxItems=None):
441 the returned items to a maximum of that number of most recently 495 the returned items to a maximum of that number of most recently
442 published items. 496 published items.
443 497
444 @param maxItems: if given, a natural number (>0) that limits the 498 @param maxItems: if given, a natural number (>0) that limits the
445 returned number of items. 499 returned number of items.
446 @return: deferred that fires with a L{list} of found items. 500 @return: deferred that fires with a C{list} of found items.
447 """ 501 """
448 502
449 503
450 def getItemsById(itemIdentifiers): 504 def getItemsById(itemIdentifiers):
451 """ 505 """
453 507
454 Each item in the returned list is a unicode string that 508 Each item in the returned list is a unicode string that
455 represent the XML of the item as it was published, including the 509 represent the XML of the item as it was published, including the
456 item wrapper with item id. 510 item wrapper with item id.
457 511
458 @param itemIdentifiers: L{list} of item ids. 512 @param itemIdentifiers: C{list} of item ids.
459 @return: deferred that fires with a L{list} of found items. 513 @return: deferred that fires with a C{list} of found items.
460 """ 514 """
461 515
462 516
463 def purge(): 517 def purge():
464 """ 518 """