1 # Copyright (C) 2012-2015 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """REST API for held message moderation."""
26 from mailman
.app
.moderator
import handle_message
27 from mailman
.interfaces
.action
import Action
28 from mailman
.interfaces
.messages
import IMessageStore
29 from mailman
.interfaces
.requests
import IListRequests
, RequestType
30 from mailman
.rest
.helpers
import (
31 CollectionMixin
, bad_request
, child
, etag
, no_content
, not_found
, okay
)
32 from mailman
.rest
.validator
import Validator
, enum_validator
33 from zope
.component
import getUtility
37 class _ModerationBase
:
38 """Common base class."""
40 def _make_resource(self
, request_id
):
41 requests
= IListRequests(self
._mlist
)
42 results
= requests
.get_request(request_id
)
46 resource
= dict(key
=key
, request_id
=request_id
)
47 # Flatten the IRequest payload into the JSON representation.
49 # Check for a matching request type, and insert the type name into the
51 request_type
= RequestType
[resource
.pop('_request_type')]
52 if request_type
is not RequestType
.held_message
:
54 resource
['type'] = RequestType
.held_message
.name
55 # This key isn't what you think it is. Usually, it's the Pendable
56 # record's row id, which isn't helpful at all. If it's not there,
58 resource
.pop('id', None)
63 class _HeldMessageBase(_ModerationBase
):
64 """Held messages are a little different."""
66 def _make_resource(self
, request_id
):
67 resource
= super(_HeldMessageBase
, self
)._make
_resource
(request_id
)
70 # Grab the message and insert its text representation into the
71 # resource. XXX See LP: #967954
72 key
= resource
.pop('key')
73 msg
= getUtility(IMessageStore
).get_message_by_id(key
)
74 resource
['msg'] = msg
.as_string()
75 # Some of the _mod_* keys we want to rename and place into the JSON
76 # resource. Others we can drop. Since we're mutating the dictionary,
77 # we need to make a copy of the keys. When you port this to Python 3,
78 # you'll need to list()-ify the .keys() dictionary view.
79 for key
in list(resource
):
80 if key
in ('_mod_subject', '_mod_hold_date', '_mod_reason',
81 '_mod_sender', '_mod_message_id'):
82 resource
[key
[5:]] = resource
.pop(key
)
83 elif key
.startswith('_mod_'):
85 # Also, held message resources will always be this type, so ignore
91 class HeldMessage(_HeldMessageBase
):
92 """Resource for moderating a held message."""
94 def __init__(self
, mlist
, request_id
):
96 self
._request
_id
= request_id
98 def on_get(self
, request
, response
):
100 request_id
= int(self
._request
_id
)
102 bad_request(response
)
104 resource
= self
._make
_resource
(request_id
)
108 okay(response
, etag(resource
))
110 def on_post(self
, request
, response
):
112 validator
= Validator(action
=enum_validator(Action
))
113 arguments
= validator(request
)
114 except ValueError as error
:
115 bad_request(response
, str(error
))
117 requests
= IListRequests(self
._mlist
)
119 request_id
= int(self
._request
_id
)
121 bad_request(response
)
123 results
= requests
.get_request(request_id
, RequestType
.held_message
)
127 handle_message(self
._mlist
, request_id
, **arguments
)
132 class HeldMessages(_HeldMessageBase
, CollectionMixin
):
133 """Resource for messages held for moderation."""
135 def __init__(self
, mlist
):
137 self
._requests
= None
139 def _resource_as_dict(self
, request
):
140 """See `CollectionMixin`."""
141 return self
._make
_resource
(request
.id)
143 def _get_collection(self
, request
):
144 requests
= IListRequests(self
._mlist
)
145 self
._requests
= requests
146 return list(requests
.of_type(RequestType
.held_message
))
148 def on_get(self
, request
, response
):
149 """/lists/listname/held"""
150 resource
= self
._make
_collection
(request
)
151 okay(response
, etag(resource
))
153 @child(r
'^(?P<id>[^/]+)')
154 def message(self
, request
, segments
, **kw
):
155 return HeldMessage(self
._mlist
, kw
['id'])