184 lines
6.3 KiB
Python
184 lines
6.3 KiB
Python
"""Provide the Subreddits class."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any, Iterator
|
|
from warnings import warn
|
|
|
|
from ..const import API_PATH
|
|
from ..util import _deprecate_args
|
|
from . import Subreddit
|
|
from .base import PRAWBase
|
|
from .listing.generator import ListingGenerator
|
|
from .util import stream_generator
|
|
|
|
if TYPE_CHECKING: # pragma: no cover
|
|
import praw.models
|
|
|
|
|
|
class Subreddits(PRAWBase):
|
|
"""Subreddits is a Listing class that provides various subreddit lists."""
|
|
|
|
@staticmethod
|
|
def _to_list(subreddit_list: list[str | praw.models.Subreddit]) -> str:
|
|
return ",".join([str(x) for x in subreddit_list])
|
|
|
|
def default(
|
|
self, **generator_kwargs: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Return a :class:`.ListingGenerator` for default subreddits.
|
|
|
|
Additional keyword arguments are passed in the initialization of
|
|
:class:`.ListingGenerator`.
|
|
|
|
"""
|
|
return ListingGenerator(
|
|
self._reddit, API_PATH["subreddits_default"], **generator_kwargs
|
|
)
|
|
|
|
def gold(self, **generator_kwargs: Any) -> Iterator[praw.models.Subreddit]:
|
|
"""Alias for :meth:`.premium` to maintain backwards compatibility."""
|
|
warn(
|
|
"'subreddits.gold' has be renamed to 'subreddits.premium'.",
|
|
category=DeprecationWarning,
|
|
stacklevel=2,
|
|
)
|
|
return self.premium(**generator_kwargs)
|
|
|
|
def new(
|
|
self, **generator_kwargs: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Return a :class:`.ListingGenerator` for new subreddits.
|
|
|
|
Additional keyword arguments are passed in the initialization of
|
|
:class:`.ListingGenerator`.
|
|
|
|
"""
|
|
return ListingGenerator(
|
|
self._reddit, API_PATH["subreddits_new"], **generator_kwargs
|
|
)
|
|
|
|
def popular(
|
|
self, **generator_kwargs: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Return a :class:`.ListingGenerator` for popular subreddits.
|
|
|
|
Additional keyword arguments are passed in the initialization of
|
|
:class:`.ListingGenerator`.
|
|
|
|
"""
|
|
return ListingGenerator(
|
|
self._reddit, API_PATH["subreddits_popular"], **generator_kwargs
|
|
)
|
|
|
|
def premium(
|
|
self, **generator_kwargs: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Return a :class:`.ListingGenerator` for premium subreddits.
|
|
|
|
Additional keyword arguments are passed in the initialization of
|
|
:class:`.ListingGenerator`.
|
|
|
|
"""
|
|
return ListingGenerator(
|
|
self._reddit, API_PATH["subreddits_gold"], **generator_kwargs
|
|
)
|
|
|
|
def recommended(
|
|
self,
|
|
subreddits: list[str | praw.models.Subreddit],
|
|
omit_subreddits: list[str | praw.models.Subreddit] | None = None,
|
|
) -> list[praw.models.Subreddit]:
|
|
"""Return subreddits recommended for the given list of subreddits.
|
|
|
|
:param subreddits: A list of :class:`.Subreddit` instances and/or subreddit
|
|
names.
|
|
:param omit_subreddits: A list of :class:`.Subreddit` instances and/or subreddit
|
|
names to exclude from the results (Reddit's end may not work as expected).
|
|
|
|
"""
|
|
if not isinstance(subreddits, list):
|
|
msg = "subreddits must be a list"
|
|
raise TypeError(msg)
|
|
if omit_subreddits is not None and not isinstance(omit_subreddits, list):
|
|
msg = "omit_subreddits must be a list or None"
|
|
raise TypeError(msg)
|
|
|
|
params = {"omit": self._to_list(omit_subreddits or [])}
|
|
url = API_PATH["sub_recommended"].format(subreddits=self._to_list(subreddits))
|
|
return [
|
|
Subreddit(self._reddit, sub["sr_name"])
|
|
for sub in self._reddit.get(url, params=params)
|
|
]
|
|
|
|
def search(
|
|
self, query: str, **generator_kwargs: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Return a :class:`.ListingGenerator` of subreddits matching ``query``.
|
|
|
|
Subreddits are searched by both their title and description.
|
|
|
|
:param query: The query string to filter subreddits by.
|
|
|
|
Additional keyword arguments are passed in the initialization of
|
|
:class:`.ListingGenerator`.
|
|
|
|
.. seealso::
|
|
|
|
:meth:`.search_by_name` to search by subreddit names
|
|
|
|
"""
|
|
self._safely_add_arguments(arguments=generator_kwargs, key="params", q=query)
|
|
return ListingGenerator(
|
|
self._reddit, API_PATH["subreddits_search"], **generator_kwargs
|
|
)
|
|
|
|
@_deprecate_args("query", "include_nsfw", "exact")
|
|
def search_by_name(
|
|
self,
|
|
query: str,
|
|
*,
|
|
include_nsfw: bool = True,
|
|
exact: bool = False,
|
|
) -> list[praw.models.Subreddit]:
|
|
r"""Return list of :class:`.Subreddit`\ s whose names begin with ``query``.
|
|
|
|
:param query: Search for subreddits beginning with this string.
|
|
:param exact: Return only exact matches to ``query`` (default: ``False``).
|
|
:param include_nsfw: Include subreddits labeled NSFW (default: ``True``).
|
|
|
|
"""
|
|
result = self._reddit.post(
|
|
API_PATH["subreddits_name_search"],
|
|
data={"include_over_18": include_nsfw, "exact": exact, "query": query},
|
|
)
|
|
return [self._reddit.subreddit(x) for x in result["names"]]
|
|
|
|
def search_by_topic(self, query: str) -> list[praw.models.Subreddit]:
|
|
"""Return list of Subreddits whose topics match ``query``.
|
|
|
|
:param query: Search for subreddits relevant to the search topic.
|
|
|
|
.. note::
|
|
|
|
As of 09/01/2020, this endpoint always returns 404.
|
|
|
|
"""
|
|
result = self._reddit.get(
|
|
API_PATH["subreddits_by_topic"], params={"query": query}
|
|
)
|
|
return [self._reddit.subreddit(x["name"]) for x in result if x.get("name")]
|
|
|
|
def stream(
|
|
self, **stream_options: str | int | dict[str, str]
|
|
) -> Iterator[praw.models.Subreddit]:
|
|
"""Yield new subreddits as they are created.
|
|
|
|
Subreddits are yielded oldest first. Up to 100 historical subreddits will
|
|
initially be returned.
|
|
|
|
Keyword arguments are passed to :func:`.stream_generator`.
|
|
|
|
"""
|
|
return stream_generator(self.new, **stream_options)
|