Checkpointing.
[mailman.git] / src / mailman / rest / docs / post-moderation.rst
blobf082de15778d3dcef00c6a81d0d583b6d73dc389
1 ===============
2 Post Moderation
3 ===============
5 Messages which are held for approval can be accepted, rejected, discarded, or
6 deferred by the list moderators.
9 Viewing the list of held messages
10 =================================
12 Held messages can be moderated through the REST API.  A mailing list starts
13 with no held messages.
15     >>> ant = create_list('ant@example.com')
16     >>> dump_json('http://localhost:9001/3.0/lists/ant@example.com/held')
17     http_etag: "..."
18     start: 0
19     total_size: 0
21 When a message gets held for moderator approval, it shows up in this list.
24     >>> msg = message_from_string("""\
25     ... From: anne@example.com
26     ... To: ant@example.com
27     ... Subject: Something
28     ... Message-ID: <alpha>
29     ...
30     ... Something else.
31     ... """)
33     >>> from mailman.app.moderator import hold_message
34     >>> request_id = hold_message(ant, msg, {'extra': 7}, 'Because')
35     >>> transaction.commit()
37     >>> dump_json('http://localhost:9001/3.0/lists/ant@example.com/held')
38     entry 0:
39         extra: 7
40         hold_date: 2005-08-01T07:49:23
41         http_etag: "..."
42         message_id: <alpha>
43         msg: From: anne@example.com
44     To: ant@example.com
45     Subject: Something
46     Message-ID: <alpha>
47     X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
48     <BLANKLINE>
49     Something else.
50     <BLANKLINE>
51         reason: Because
52         request_id: 1
53         sender: anne@example.com
54         subject: Something
55     http_etag: "..."
56     start: 0
57     total_size: 1
59 You can get an individual held message by providing the *request id* for that
60 message.  This will include the text of the message.
63     >>> def url(request_id):
64     ...     return ('http://localhost:9001/3.0/lists/'
65     ...             'ant@example.com/held/{0}'.format(request_id))
67     >>> dump_json(url(request_id))
68     extra: 7
69     hold_date: 2005-08-01T07:49:23
70     http_etag: "..."
71     message_id: <alpha>
72     msg: From: anne@example.com
73     To: ant@example.com
74     Subject: Something
75     Message-ID: <alpha>
76     X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
77     <BLANKLINE>
78     Something else.
79     <BLANKLINE>
80     reason: Because
81     request_id: 1
82     sender: anne@example.com
83     subject: Something
86 Disposing of held messages
87 ==========================
89 Individual messages can be moderated through the API by POSTing back to the
90 held message's resource.   The POST data requires an action of one of the
91 following:
93   * discard - throw the message away.
94   * reject - bounces the message back to the original author.
95   * defer - defer any action on the message (continue to hold it)
96   * accept - accept the message for posting.
98 Let's see what happens when the above message is deferred.
100     >>> dump_json(url(request_id), {
101     ...     'action': 'defer',
102     ...     })
103     content-length: 0
104     date: ...
105     server: ...
106     status: 204
108 The message is still in the moderation queue.
110     >>> dump_json(url(request_id))
111     extra: 7
112     hold_date: 2005-08-01T07:49:23
113     http_etag: "..."
114     message_id: <alpha>
115     msg: From: anne@example.com
116     To: ant@example.com
117     Subject: Something
118     Message-ID: <alpha>
119     X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
120     <BLANKLINE>
121     Something else.
122     <BLANKLINE>
123     reason: Because
124     request_id: 1
125     sender: anne@example.com
126     subject: Something
128 The held message can be discarded.
130     >>> dump_json(url(request_id), {
131     ...     'action': 'discard',
132     ...     })
133     content-length: 0
134     date: ...
135     server: ...
136     status: 204
138 Messages can also be accepted via the REST API.  Let's hold a new message for
139 moderation.
142     >>> del msg['message-id']
143     >>> msg['Message-ID'] = '<bravo>'
144     >>> request_id = hold_message(ant, msg)
145     >>> transaction.commit()
147     >>> results = call_http(url(request_id))
148     >>> print(results['message_id'])
149     <bravo>
151     >>> dump_json(url(request_id), {
152     ...     'action': 'accept',
153     ...     })
154     content-length: 0
155     date: ...
156     server: ...
157     status: 204
159     >>> from mailman.testing.helpers import get_queue_messages
160     >>> messages = get_queue_messages('pipeline')
161     >>> len(messages)
162     1
163     >>> print(messages[0].msg['message-id'])
164     <bravo>
166 Messages can be rejected via the REST API too.  These bounce the message back
167 to the original author.
170     >>> del msg['message-id']
171     >>> msg['Message-ID'] = '<charlie>'
172     >>> request_id = hold_message(ant, msg)
173     >>> transaction.commit()
175     >>> results = call_http(url(request_id))
176     >>> print(results['message_id'])
177     <charlie>
179     >>> dump_json(url(request_id), {
180     ...     'action': 'reject',
181     ...     })
182     content-length: 0
183     date: ...
184     server: ...
185     status: 204
187     >>> from mailman.testing.helpers import get_queue_messages
188     >>> messages = get_queue_messages('virgin')
189     >>> len(messages)
190     1
191     >>> print(messages[0].msg['subject'])
192     Request to mailing list "Ant" rejected