summaryrefslogtreecommitdiff
path: root/src/mailman/model/docs/requests.rst
blob: ad892a18bf9c82b9e3b7636175a15fcd1e279663 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
.. _model-requests:

==================
Moderator requests
==================

Various actions will be held for moderator approval, such as subscriptions to
closed lists, or postings by non-members.  The requests database is the low
level interface to these actions requiring approval.

An :ref:`application level interface <app-moderator>` for holding messages and
membership changes is also available.


Mailing list-centric
====================

A set of requests are always related to a particular mailing list.  Adapt the
mailing list to get its requests.
::

    >>> from mailman.interfaces.requests import IListRequests
    >>> from zope.interface.verify import verifyObject

    >>> mlist = create_list('test@example.com')
    >>> requests = IListRequests(mlist)
    >>> verifyObject(IListRequests, requests)
    True
    >>> requests.mailing_list
    <mailing list "test@example.com" at ...>


Holding requests
================

The list's requests database starts out empty.

    >>> print(requests.count)
    0
    >>> dump_list(requests.held_requests)
    *Empty*

At the lowest level, the requests database is very simple.  Holding a request
requires a request type (as an enum value), a key, and an optional dictionary
of associated data.  The request database assigns no semantics to the held
data, except for the request type.

    >>> from mailman.interfaces.requests import RequestType

We can hold messages for moderator approval.

    >>> requests.hold_request(RequestType.held_message, 'hold_1')
    1

We can hold subscription requests for moderator approval.

    >>> requests.hold_request(RequestType.subscription, 'hold_2')
    2

We can hold unsubscription requests for moderator approval.

    >>> requests.hold_request(RequestType.unsubscription, 'hold_3')
    3


Getting requests
================

We can see the total number of requests being held.

    >>> print(requests.count)
    3

We can also see the number of requests being held by request type.

    >>> print(requests.count_of(RequestType.subscription))
    1
    >>> print(requests.count_of(RequestType.unsubscription))
    1

We can also see when there are multiple held requests of a particular type.

    >>> print(requests.hold_request(RequestType.held_message, 'hold_4'))
    4
    >>> print(requests.count_of(RequestType.held_message))
    2

We can ask the requests database for a specific request, by providing the id
of the request data we want.  This returns a 2-tuple of the key and data we
originally held.

    >>> key, data = requests.get_request(2)
    >>> print(key)
    hold_2

There was no additional data associated with request 2.

    >>> print(data)
    None

If we ask for a request that is not in the database, we get None back.

    >>> print(requests.get_request(801))
    None


Additional data
===============

When a request is held, additional data can be associated with it, in the form
of a dictionary with string values.

    >>> data = dict(foo='yes', bar='no')
    >>> requests.hold_request(RequestType.held_message, 'hold_5', data)
    5

The data is returned when the request is retrieved.  The dictionary will have
an additional key which holds the name of the request type.

    >>> key, data = requests.get_request(5)
    >>> print(key)
    hold_5
    >>> dump_msgdata(data)
    _request_type: held_message
    bar          : no
    foo          : yes
    type         : data


Iterating over requests
=======================

To make it easier to find specific requests, the list requests can be iterated
over by type.

    >>> print(requests.count_of(RequestType.held_message))
    3
    >>> for request in requests.of_type(RequestType.held_message):
    ...     key, data = requests.get_request(request.id)
    ...     print(request.id, request.request_type, key)
    ...     if data is not None:
    ...         for key in sorted(data):
    ...             print('    {0}: {1}'.format(key, data[key]))
    1 RequestType.held_message hold_1
    4 RequestType.held_message hold_4
    5 RequestType.held_message hold_5
        _request_type: held_message
        bar: no
        foo: yes
        type: data


Deleting requests
=================

Once a specific request has been handled, it can be deleted from the requests
database.

    >>> print(requests.count)
    5
    >>> requests.delete_request(2)
    >>> print(requests.count)
    4

Request 2 is no longer in the database.

    >>> print(requests.get_request(2))
    None

    >>> for request in requests.held_requests:
    ...     requests.delete_request(request.id)
    >>> print(requests.count)
    0