The pending database is where various types of events which need confirmation are stored. These can include email address registration events, held messages (but only for user confirmation), auto-approvals, and probe bounces. This is not where messages held for administrator approval are kept.
In order to pend an event, you first need a pending database.
>>> from mailman.interfaces.pending import IPendings
>>> from zope.component import getUtility
>>> pendingdb = getUtility(IPendings)
There are nothing in the pendings database.
>>> pendingdb.count
0
The pending database can add any IPendable to the database, returning a token that can be used in urls and such.
>>> from zope.interface import implementer
>>> from mailman.interfaces.pending import IPendable
>>> @implementer(IPendable)
... class SimplePendable(dict):
... pass
>>> subscription = SimplePendable(
... type='subscription',
... address='aperson@example.com',
... display_name='Anne Person',
... language='en',
... password='xyz')
>>> token = pendingdb.add(subscription)
>>> len(token)
40
There’s exactly one entry in the pendings database now.
>>> pendingdb.count
1
You can confirm the pending, which means returning the IPendable structure (as a dictionary) from the database that matches the token. If the token isn’t in the database, None is returned.
>>> pendable = pendingdb.confirm(b'missing')
>>> print(pendable)
None
>>> pendable = pendingdb.confirm(token)
>>> dump_msgdata(pendable)
address : aperson@example.com
display_name: Anne Person
language : en
password : xyz
type : subscription
After confirmation, the token is no longer in the database.
>>> print(pendingdb.confirm(token))
None
There are a few other things you can do with the pending database. When you confirm a token, you can leave it in the database, or in other words, not expunge it.
>>> event_1 = SimplePendable(type='one')
>>> token_1 = pendingdb.add(event_1)
>>> event_2 = SimplePendable(type='two')
>>> token_2 = pendingdb.add(event_2)
>>> event_3 = SimplePendable(type='three')
>>> token_3 = pendingdb.add(event_3)
>>> pendable = pendingdb.confirm(token_1, expunge=False)
>>> dump_msgdata(pendable)
type: one
>>> pendable = pendingdb.confirm(token_1, expunge=True)
>>> dump_msgdata(pendable)
type: one
>>> print(pendingdb.confirm(token_1))
None
You can iterate over all the pendings in the database.
>>> pendables = list(pendingdb)
>>> def sort_key(item):
... token, pendable = item
... return pendable['type']
>>> sorted_pendables = sorted(pendables, key=sort_key)
>>> for token, pendable in sorted_pendables:
... print(pendable['type'])
three
two
An event can be given a lifetime when it is pended, otherwise it just uses a default lifetime.
>>> from datetime import timedelta
>>> yesterday = timedelta(days=-1)
>>> event_4 = SimplePendable(type='four')
>>> token_4 = pendingdb.add(event_4, lifetime=yesterday)
Every once in a while the pending database is cleared of old records.
>>> pendingdb.evict()
>>> print(pendingdb.confirm(token_4))
None
>>> pendable = pendingdb.confirm(token_2)
>>> dump_msgdata(pendable)
type: two