-
-
Notifications
You must be signed in to change notification settings - Fork 454
/
__init__.py
298 lines (225 loc) · 9.44 KB
/
__init__.py
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
"""Package providing reddit class mixins."""
from json import dumps
from ....const import API_PATH
from .editable import EditableMixin
from .fullname import FullnameMixin
from .gildable import GildableMixin
from .inboxable import InboxableMixin
from .inboxtoggleable import InboxToggleableMixin
from .messageable import MessageableMixin
from .replyable import ReplyableMixin
from .reportable import ReportableMixin
from .savable import SavableMixin
from .votable import VotableMixin
class ThingModerationMixin:
"""Provides moderation methods for Comments and Submissions."""
REMOVAL_MESSAGE_API = None
def approve(self):
"""Approve a :class:`~.Comment` or :class:`~.Submission`.
Approving a comment or submission reverts a removal, resets the report
counter, adds a green check mark indicator (only visible to other
moderators) on the website view, and sets the ``approved_by`` attribute
to the authenticated user.
Example usage:
.. code:: python
# approve a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.approve()
# approve a submission:
submission = reddit.submission(id='5or86n')
submission.mod.approve()
"""
self.thing._reddit.post(
API_PATH["approve"], data={"id": self.thing.fullname}
)
def distinguish(self, how="yes", sticky=False):
"""Distinguish a :class:`~.Comment` or :class:`~.Submission`.
:param how: One of 'yes', 'no', 'admin', 'special'. 'yes' adds a
moderator level distinguish. 'no' removes any distinction. 'admin'
and 'special' require special user privileges to use.
:param sticky: Comment is stickied if True, placing it at the top of
the comment page regardless of score. If thing is not a top-level
comment, this parameter is silently ignored.
Example usage:
.. code:: python
# distinguish and sticky a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.distinguish(how='yes', sticky=True)
# undistinguish a submission:
submission = reddit.submission(id='5or86n')
submission.mod.distinguish(how='no')
See also :meth:`~.undistinguish`
"""
data = {"how": how, "id": self.thing.fullname}
if sticky and getattr(self.thing, "is_root", False):
data["sticky"] = True
self.thing._reddit.post(API_PATH["distinguish"], data=data)
def ignore_reports(self):
"""Ignore future reports on a Comment or Submission.
Calling this method will prevent future reports on this Comment or
Submission from both triggering notifications and appearing in the
various moderation listings. The report count will still increment on
the Comment or Submission.
Example usage:
.. code:: python
# ignore future reports on a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.ignore_reports()
# ignore future reports on a submission
submission = reddit.submission(id='5or86n')
submission.mod.ignore_reports()
See also :meth:`~.unignore_reports`
"""
self.thing._reddit.post(
API_PATH["ignore_reports"], data={"id": self.thing.fullname}
)
def lock(self):
"""Lock the a :class:`~.Comment` or :class:`~.Submission`.
Example usage:
.. code:: python
# lock a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.lock()
# lock a submission:
submission = reddit.submission(id='5or86n')
submission.mod.lock()
See also :meth:`~.unlock`
"""
self.thing._reddit.post(
API_PATH["lock"], data={"id": self.thing.fullname}
)
def remove(self, spam=False):
"""Remove a :class:`~.Comment` or :class:`~.Submission`.
:param spam: When True, use the removal to help train the Subreddit's
spam filter (default: False).
Example usage:
.. code:: python
# remove a comment and mark as spam:
comment = reddit.comment('dkk4qjd')
comment.mod.remove(spam=True)
# remove a submission
submission = reddit.submission(id='5or86n')
submission.mod.remove()
"""
data = {"id": self.thing.fullname, "spam": bool(spam)}
self.thing._reddit.post(API_PATH["remove"], data=data)
def removal_reasons(self):
"""Return list of available removal reasons.
reason ids are required in order to use :meth:`.add_removal_reason`.
For example:
.. code:: python
removal_reasons = submission.mod.removal_reasons()
"""
url = API_PATH["removal_reasons_list"].format(
subreddit=self.submission.subreddit
)
return self.submission._reddit.get(
url, data={"link": self.submission.fullname}
)["data"]
def add_removal_reason(self, reason_id, mod_note=""):
"""Add a removal reason for a Comment or Submission.
:param reason_id: The removal reason template ID.
:param mod_note: A message for the other mods on Reddit redesign
Example usage:
.. code:: python
# Select arbitrary reason (assuming there is any)
reasons = comment.mod.removal_reasons()
reason_id = next(x for x in reasons)
comment = reddit.comment('dkk4qjd')
comment.mod.add_removal_reason(reason_id=reason_id)
# remove a submission and add a mod note
submission = reddit.submission(id='5or86n')
submission.mod.remove(reason_id=""110ni21zo23ql", mod_note="foo")
"""
# Only the first element of the item_id list is used.
data = {
"item_ids": [self.thing.fullname],
"mod_note": mod_note,
"reason_id": reason_id,
}
self.thing._reddit.post(API_PATH["removal_reasons"], data=data)
def send_removal_message(
self,
message,
title="ignored",
type="public", # pylint: disable=redefined-builtin
):
"""Send a removal message for a Comment or Submission.
Reddit adds human-readable information about the object to the message.
:param type: One of 'public', 'private', 'private_exposed'.
'public' leaves a stickied comment on the post.
'private' sends a Modmail message with hidden username.
'private_exposed' sends a Modmail message without hidden username.
:param title: The short reason given in the message.
(Ignored if type is 'public'.)
:param message: The body of the message.
If ``type`` is 'public', the new :class:`~.Comment` is returned.
"""
# The API endpoint used to send removal messages is different
# for posts and comments, so the derived classes specify which one.
if self.REMOVAL_MESSAGE_API is None:
raise NotImplementedError("ThingModerationMixin must be extended.")
url = API_PATH[self.REMOVAL_MESSAGE_API]
# Only the first element of the item_id list is used.
data = {
"item_id": [self.thing.fullname],
"message": message,
"title": title,
"type": type,
}
return self.thing._reddit.post(url, data={"json": dumps(data)}) or None
def undistinguish(self):
"""Remove mod, admin, or special distinguishing on object.
Also unstickies the object if applicable.
Example usage:
.. code:: python
# undistinguish a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.undistinguish()
# undistinguish a submission:
submission = reddit.submission(id='5or86n')
submission.mod.undistinguish()
See also :meth:`~.distinguish`
"""
self.distinguish(how="no")
def unignore_reports(self):
"""Resume receiving future reports on a Comment or Submission.
Future reports on this Comment or Submission will cause notifications,
and appear in the various moderation listings.
Example usage:
.. code:: python
# accept future reports on a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.unignore_reports()
# accept future reports on a submission
submission = reddit.submission(id='5or86n')
submission.mod.unignore_reports()
See also :meth:`~.ignore_reports`
"""
self.thing._reddit.post(
API_PATH["unignore_reports"], data={"id": self.thing.fullname}
)
def unlock(self):
"""Unlock the a :class:`~.Comment` or :class:`~.Submission`.
Example usage:
# unlock a comment:
comment = reddit.comment('dkk4qjd')
comment.mod.unlock()
# unlock a submission:
submission = reddit.submission(id='5or86n')
submission.mod.unlock()
See also :meth:`~.lock`
"""
self.thing._reddit.post(
API_PATH["unlock"], data={"id": self.thing.fullname}
)
class UserContentMixin(
EditableMixin,
GildableMixin,
InboxToggleableMixin,
ReplyableMixin,
ReportableMixin,
SavableMixin,
VotableMixin,
):
"""A convenience mixin that applies to both Comments and Submissions."""