Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Unreleased
- :meth:`.Inbox.mark_all_read` to mark all messages as read with one API call.
- :meth:`~.InboxableMixin.unblock_subreddit` to unblock a subreddit.
- :meth:`.update_crowd_control_level` to update the crowd control level of a post.
- :meth:`.moderator_subreddits`, which returns information about the subreddits that the
authenticated user moderates, has been restored.
- The configuration setting ``refresh_token`` has been added back. See
https://www.reddit.com/r/redditdev/comments/olk5e6/followup_oauth2_api_changes_regarding_refresh/
for more info.
Expand Down
27 changes: 27 additions & 0 deletions asyncpraw/models/reddit/redditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ async def moderated(self) -> List["asyncpraw.models.Subreddit"]:
:returns: A ``list`` of :class:`~asyncpraw.models.Subreddit` objects. Return
``[]`` if the redditor has no moderated subreddits.

:raises: ``asyncprawcore.ServerError`` in certain cicumstances. See the note
below.

.. note::

The redditor's own user profile subreddit will not be returned, but other
Expand All @@ -305,6 +308,30 @@ async def moderated(self) -> List["asyncpraw.models.Subreddit"]:
print(subreddit.display_name)
print(subreddit.title)

.. note::

A ``asyncprawcore.ServerError`` exception may be raised if the redditor
moderates a large number of subreddits. If that happens, try switching to
:ref:`read-only mode <read_only_application>`. For example,

.. code-block:: python

reddit.read_only = True
redditor = await reddit.redditor("reddit")
async for subreddit in redditor.moderated():
print(str(subreddit))

It is possible that requests made in read-only mode will also raise a
``asyncprawcore.ServerError`` exception.

When used in read-only mode, this method does not retrieve information about
subreddits that require certain special permissions to access, e.g., private
subreddits and premium-only subreddits.

.. seealso::

:meth:`.User.moderator_subreddits`

"""
return await self._reddit.get(API_PATH["moderated"].format(user=self)) or []

Expand Down
40 changes: 39 additions & 1 deletion asyncpraw/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ def contributor_subreddits(
) -> AsyncIterator["asyncpraw.models.Subreddit"]:
"""Return a :class:`.ListingGenerator` of contributor subreddits.

These are subreddits that the user is a contributor of.
These are subreddits in which the user is an approved user.

Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.

To print a list of the subreddits that you are an approved user in, try:

.. code-block:: python

async for subreddit in reddit.user.contributor_subreddits(limit=None):
print(str(subreddit))

"""
return ListingGenerator(
self._reddit, API_PATH["my_contributor"], **generator_kwargs
Expand Down Expand Up @@ -157,6 +164,30 @@ async def me(
self._me = Redditor(self._reddit, _data=user_data)
return self._me

def moderator_subreddits(
self, **generator_kwargs: Union[str, int, Dict[str, str]]
) -> AsyncIterator["asyncpraw.models.Subreddit"]:
"""Return a :class:`.ListingGenerator` subreddits that the user moderates.

Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.

To print a list of the names of the subreddits you moderate, try:

.. code-block:: python

async for subreddit in reddit.user.moderator_subreddits(limit=None):
print(str(subreddit))

.. seealso::

:meth:`.Redditor.moderated`

"""
return ListingGenerator(
self._reddit, API_PATH["my_moderator"], **generator_kwargs
)

async def multireddits(self) -> List["asyncpraw.models.Multireddit"]:
"""Return a list of multireddits belonging to the user."""
return await self._reddit.get(API_PATH["my_multireddits"])
Expand All @@ -169,6 +200,13 @@ def subreddits(
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.

To print a list of the subreddits that you are subscribed to, try:

.. code-block:: python

async for subreddit in reddit.user.subreddits(limit=None):
print(str(subreddit))

"""
return ListingGenerator(
self._reddit, API_PATH["my_subreddits"], **generator_kwargs
Expand Down
219 changes: 219 additions & 0 deletions tests/integration/cassettes/TestUser.test_moderator_subreddits.json

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions tests/integration/models/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ async def test_me__bypass_cache(self, _):
me = await self.reddit.user.me(use_cache=False)
assert not hasattr(me, "praw_is_cached")

@mock.patch("asyncio.sleep", return_value=None)
async def test_moderator_subreddits(self, _):
self.reddit.read_only = False
with self.use_cassette():
mod_subs = await self.async_list(
self.reddit.user.moderator_subreddits(limit=None)
)
assert mod_subs
assert all(isinstance(x, Subreddit) for x in mod_subs)

async def test_multireddits(self):
self.reddit.read_only = False
with self.use_cassette():
Expand Down