Skip to content

Commit

Permalink
Add SubredditModeration with approve and remove.
Browse files Browse the repository at this point in the history
  • Loading branch information
bboe committed Mar 20, 2016
1 parent 4ebf88d commit ebfe0d7
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 84 deletions.
6 changes: 2 additions & 4 deletions praw/models/reddit/mixins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
from .gildable import GildableMixin # NOQA
from .inboxable import InboxableMixin # NOQA
from .messageable import MessageableMixin # NOQA
from .moderatable import ModeratableMixin # NOQA
from .replyable import ReplyableMixin # NOQA
from .reportable import ReportableMixin # NOQA
from .savable import SavableMixin # NOQA
from .votable import VotableMixin # NOQA


class UserContentMixin(EditableMixin, GildableMixin, ModeratableMixin,
ReplyableMixin, ReportableMixin, SavableMixin,
VotableMixin):
class UserContentMixin(EditableMixin, GildableMixin, ReplyableMixin,
ReportableMixin, SavableMixin, VotableMixin):
"""A convenience mixin that applies to both Comments and Submissions."""
79 changes: 0 additions & 79 deletions praw/models/reddit/mixins/moderatable.py

This file was deleted.

85 changes: 84 additions & 1 deletion praw/models/reddit/subreddit.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def __init__(self, reddit, display_name=None, _data=None):
self.display_name = display_name
self._path = API_PATH['subreddit'].format(subreddit=self.display_name)
self._prepare_relationships()
self.mod = SubredditModeration(self)

def _info_path(self):
return API_PATH['subreddit_about'].format(subreddit=self.display_name)
Expand Down Expand Up @@ -122,11 +123,93 @@ def submit(self, title, selftext=None, url=None, resubmit=True,
return self._reddit.post(API_PATH['submit'], data=data)


class SubredditModeration(object):
"""Provides a set of moderation functions to a subreddit."""

def __init__(self, subreddit):
"""Create a SubredditModeration instance.
:param subreddit: The subreddit to moderate.
"""
self.subreddit = subreddit

def approve(self, thing):
"""Approve a Comment or Submission.
:param thing: An instance of Comment or 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.
"""
self.subreddit._reddit.post(API_PATH['approve'],
data={'id': thing.fullname})

def distinguish(self, as_made_by='mod'):
"""Distinguish object as made by mod, admin or special.
Distinguished objects have a different author color. With Reddit
Enhancement Suite it is the background color that changes.
:returns: The json response from the server.
"""
url = self.reddit_session.config['distinguish']
data = {'id': self.fullname,
'how': 'yes' if as_made_by == 'mod' else as_made_by}
return self.reddit_session.request_json(url, data=data)

def ignore_reports(self):
"""Ignore future reports on this object.
This prevents future reports from causing notifications or appearing
in the various moderation listing. The report count will still
increment.
"""
url = self.reddit_session.config['ignore_reports']
data = {'id': self.fullname}
return self.reddit_session.request_json(url, data=data)

def remove(self, thing, spam=False):
"""Remove a Comment or Submission.
:param thing: An instance of Comment or Submission.
:param spam: When True, use the removal to help train the Subreddit's
spam filter (Default: False)
"""
data = {'id': thing.fullname, 'spam': bool(spam)}
self.subreddit._reddit.post(API_PATH['remove'], data=data)

def undistinguish(self):
"""Remove mod, admin or special distinguishing on object.
:returns: The json response from the server.
"""
return self.distinguish(as_made_by='no')

def unignore_reports(self):
"""Remove ignoring of future reports on this object.
Undoes 'ignore_reports'. Future reports will now cause notifications
and appear in the various moderation listings.
"""
url = self.reddit_session.config['unignore_reports']
data = {'id': self.fullname}
return self.reddit_session.request_json(url, data=data)


class SubredditRelationship(object):
"""Represents a relationship between a redditor and subreddit."""

def __init__(self, subreddit, relationship):
"""Create an SubredditRelationship instance.
"""Create a SubredditRelationship instance.
:param subreddit: The subreddit for the relationship.
:param relationship: The name of the relationship.
Expand Down
102 changes: 102 additions & 0 deletions tests/integration/cassettes/TestSubredditModeration.test_approve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"http_interactions": [
{
"recorded_at": "2016-03-20T06:34:00",
"request": {
"body": {
"encoding": "utf-8",
"string": "grant_type=password&username=<USERNAME>&password=<PASSWORD>"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "identity",
"Authorization": "Basic <BASIC_AUTH>",
"Connection": "keep-alive",
"Content-Length": "57",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "<USER_AGENT> PRAW/4.0.0a1 prawcore/0.0.7"
},
"method": "POST",
"uri": "https://www.reddit.com/api/v1/access_token"
},
"response": {
"body": {
"encoding": "UTF-8",
"string": "{\"access_token\": \"7302867-O-GDsqGMLBCnkbRipX0Iiv0lYvU\", \"token_type\": \"bearer\", \"expires_in\": 3600, \"scope\": \"*\"}"
},
"headers": {
"CF-RAY": "286722c8c7a239a6-PHX",
"Connection": "keep-alive",
"Content-Length": "113",
"Content-Type": "application/json; charset=UTF-8",
"Date": "Sun, 20 Mar 2016 06:34:00 GMT",
"Server": "cloudflare-nginx",
"Set-Cookie": "__cfduid=debcc4e298201f19f1d79dc741797de021458455640; expires=Mon, 20-Mar-17 06:34:00 GMT; path=/; domain=.reddit.com; HttpOnly",
"Strict-Transport-Security": "max-age=15552000; includeSubDomains; preload",
"X-Moose": "majestic",
"cache-control": "max-age=0, must-revalidate",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "1; mode=block"
},
"status": {
"code": 200,
"message": "OK"
},
"url": "https://www.reddit.com/api/v1/access_token"
}
},
{
"recorded_at": "2016-03-20T06:34:01",
"request": {
"body": {
"encoding": "utf-8",
"string": "api_type=json&id=t3_4b536h"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "identity",
"Authorization": "bearer 7302867-O-GDsqGMLBCnkbRipX0Iiv0lYvU",
"Connection": "keep-alive",
"Content-Length": "26",
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": "loid=M1Bw5euB4Y5c5QetHq; __cfduid=debcc4e298201f19f1d79dc741797de021458455640; loidcreated=2016-03-20T06%3A34%3A00.484Z",
"User-Agent": "<USER_AGENT> PRAW/4.0.0a1 prawcore/0.0.7"
},
"method": "POST",
"uri": "https://oauth.reddit.com/api/approve/?raw_json=1"
},
"response": {
"body": {
"encoding": "UTF-8",
"string": "{}"
},
"headers": {
"CF-RAY": "286722ccdf5c39a6-PHX",
"Connection": "keep-alive",
"Content-Length": "2",
"Content-Type": "application/json; charset=UTF-8",
"Date": "Sun, 20 Mar 2016 06:34:01 GMT",
"Server": "cloudflare-nginx",
"Strict-Transport-Security": "max-age=15552000; includeSubDomains; preload",
"X-Moose": "majestic",
"cache-control": "private, s-maxage=0, max-age=0, must-revalidate",
"expires": "-1",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-ratelimit-remaining": "599.0",
"x-ratelimit-reset": "359",
"x-ratelimit-used": "1",
"x-ua-compatible": "IE=edge",
"x-xss-protection": "1; mode=block"
},
"status": {
"code": 200,
"message": "OK"
},
"url": "https://oauth.reddit.com/api/approve/?raw_json=1"
}
}
],
"recorded_with": "betamax/0.5.1"
}

0 comments on commit ebfe0d7

Please sign in to comment.