2026-02-01 09:31:38 +01:00

115 lines
3.7 KiB
Python

"""Provide the Redditors class."""
from __future__ import annotations
from itertools import islice
from types import SimpleNamespace
from typing import TYPE_CHECKING, Iterable, Iterator
import prawcore
from ..const import API_PATH
from .base import PRAWBase
from .listing.generator import ListingGenerator
from .util import stream_generator
if TYPE_CHECKING: # pragma: no cover
import praw.models
class PartialRedditor(SimpleNamespace):
"""A namespace object that provides a subset of :class:`.Redditor` attributes."""
class Redditors(PRAWBase):
"""Redditors is a Listing class that provides various :class:`.Redditor` lists."""
def new(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Subreddit]:
"""Return a :class:`.ListingGenerator` for new :class:`.Redditors`.
:returns: :class:`.Redditor` profiles, which are a type of :class:`.Subreddit`.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
"""
return ListingGenerator(self._reddit, API_PATH["users_new"], **generator_kwargs)
def partial_redditors(self, ids: Iterable[str]) -> Iterator[PartialRedditor]:
"""Get user summary data by redditor IDs.
:param ids: An iterable of redditor fullname IDs.
:returns: A iterator producing :class:`.PartialRedditor` objects.
Each ID must be prefixed with ``t2_``.
Invalid IDs are ignored by the server.
"""
iterable = iter(ids)
while True:
chunk = list(islice(iterable, 100))
if not chunk:
break
params = {"ids": ",".join(chunk)}
try:
results = self._reddit.get(API_PATH["user_by_fullname"], params=params)
except prawcore.exceptions.NotFound:
# None of the given IDs matched any Redditor.
continue
for fullname, user_data in results.items():
yield PartialRedditor(fullname=fullname, **user_data)
def popular(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Subreddit]:
"""Return a :class:`.ListingGenerator` for popular :class:`.Redditors`.
:returns: :class:`.Redditor` profiles, which are a type of :class:`.Subreddit`.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
"""
return ListingGenerator(
self._reddit, API_PATH["users_popular"], **generator_kwargs
)
def search(
self, query: str, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Subreddit]:
r"""Return a :class:`.ListingGenerator` of Redditors for ``query``.
:param query: The query string to filter Redditors by.
:returns: :class:`.Redditor`\ s.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
"""
self._safely_add_arguments(arguments=generator_kwargs, key="params", q=query)
return ListingGenerator(
self._reddit, API_PATH["users_search"], **generator_kwargs
)
def stream(
self, **stream_options: str | int | dict[str, str]
) -> Iterator[praw.models.Subreddit]:
"""Yield new Redditors as they are created.
Redditors are yielded oldest first. Up to 100 historical Redditors will
initially be returned.
Keyword arguments are passed to :func:`.stream_generator`.
:returns: :class:`.Redditor` profiles, which are a type of :class:`.Subreddit`.
"""
return stream_generator(self.new, **stream_options)