~nkarageuzian/mailman/bug-1312884

6873 by Barry Warsaw
Documentation reorganization.
1
====================
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
2
The pending database
3
====================
4
5
The pending database is where various types of events which need confirmation
6
are stored.  These can include email address registration events, held
7
messages (but only for user confirmation), auto-approvals, and probe bounces.
8
This is not where messages held for administrator approval are kept.
9
7002.1.3 by Barry Warsaw
checkpointing
10
In order to pend an event, you first need a pending database.
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
11
6661 by Barry Warsaw
Remove the mailman.interface magic. Use the more specific interface imports.
12
    >>> from mailman.interfaces.pending import IPendings
6793 by Barry Warsaw
As before, replace config.db.requests and config.db.pendings with utilities.
13
    >>> from zope.component import getUtility
14
    >>> pendingdb = getUtility(IPendings)
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
15
6940 by Barry Warsaw
Many documentation fixes for better Sphinx output.
16
The pending database can add any ``IPendable`` to the database, returning a
17
token that can be used in urls and such.
7152 by Barry Warsaw
General code cleanup.
18
::
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
19
7152 by Barry Warsaw
General code cleanup.
20
    >>> from zope.interface import implementer
6661 by Barry Warsaw
Remove the mailman.interface magic. Use the more specific interface imports.
21
    >>> from mailman.interfaces.pending import IPendable
7152 by Barry Warsaw
General code cleanup.
22
    >>> @implementer(IPendable)
23
    ... class SimplePendable(dict):
24
    ...     pass
25
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
26
    >>> subscription = SimplePendable(
27
    ...     type='subscription',
28
    ...     address='aperson@example.com',
7118.1.1 by Barry Warsaw
Schema change. After discussion at Pycon, we decided to change "real_name" to
29
    ...     display_name='Anne Person',
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
30
    ...     language='en',
31
    ...     password='xyz')
32
    >>> token = pendingdb.add(subscription)
33
    >>> len(token)
34
    40
35
6940 by Barry Warsaw
Many documentation fixes for better Sphinx output.
36
There's not much you can do with tokens except to `confirm` them, which
37
basically means returning the ``IPendable`` structure (as a dictionary) from
7002.1.3 by Barry Warsaw
checkpointing
38
the database that matches the token.  If the token isn't in the database, None
39
is returned.
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
40
6750 by Barry Warsaw
De-u-literal-ify our doctests.
41
    >>> pendable = pendingdb.confirm(bytes('missing'))
7251 by Barry Warsaw
Use print functions consistently through, and update all __future__ imports to
42
    >>> print(pendable)
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
43
    None
44
    >>> pendable = pendingdb.confirm(token)
7002.1.3 by Barry Warsaw
checkpointing
45
    >>> dump_msgdata(pendable)
7118.1.1 by Barry Warsaw
Schema change. After discussion at Pycon, we decided to change "real_name" to
46
    address     : aperson@example.com
47
    display_name: Anne Person
48
    language    : en
49
    password    : xyz
50
    type        : subscription
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
51
52
After confirmation, the token is no longer in the database.
53
7251 by Barry Warsaw
Use print functions consistently through, and update all __future__ imports to
54
    >>> print(pendingdb.confirm(token))
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
55
    None
56
57
There are a few other things you can do with the pending database.  When you
6940 by Barry Warsaw
Many documentation fixes for better Sphinx output.
58
confirm a token, you can leave it in the database, or in other words, not
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
59
expunge it.
60
61
    >>> event_1 = SimplePendable(type='one')
62
    >>> token_1 = pendingdb.add(event_1)
63
    >>> event_2 = SimplePendable(type='two')
64
    >>> token_2 = pendingdb.add(event_2)
65
    >>> event_3 = SimplePendable(type='three')
66
    >>> token_3 = pendingdb.add(event_3)
67
    >>> pendable = pendingdb.confirm(token_1, expunge=False)
7002.1.3 by Barry Warsaw
checkpointing
68
    >>> dump_msgdata(pendable)
69
    type: one
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
70
    >>> pendable = pendingdb.confirm(token_1, expunge=True)
7002.1.3 by Barry Warsaw
checkpointing
71
    >>> dump_msgdata(pendable)
72
    type: one
7251 by Barry Warsaw
Use print functions consistently through, and update all __future__ imports to
73
    >>> print(pendingdb.confirm(token_1))
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
74
    None
75
76
An event can be given a lifetime when it is pended, otherwise it just uses a
77
default lifetime.
78
79
    >>> from datetime import timedelta
80
    >>> yesterday = timedelta(days=-1)
81
    >>> event_4 = SimplePendable(type='four')
82
    >>> token_4 = pendingdb.add(event_4, lifetime=yesterday)
83
84
Every once in a while the pending database is cleared of old records.
85
86
    >>> pendingdb.evict()
7251 by Barry Warsaw
Use print functions consistently through, and update all __future__ imports to
87
    >>> print(pendingdb.confirm(token_4))
6537 by Barry Warsaw
Move the pending database into the SQLAlchemy/Elixir layer. The old
88
    None
89
    >>> pendable = pendingdb.confirm(token_2)
7002.1.3 by Barry Warsaw
checkpointing
90
    >>> dump_msgdata(pendable)
91
    type: two