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

343 lines
11 KiB
Python

"""Provide the Front class."""
from __future__ import annotations
from typing import TYPE_CHECKING, Iterator
from ..const import API_PATH
from ..util import _deprecate_args
from .base import PRAWBase
from .listing.generator import ListingGenerator
from .util import stream_generator
if TYPE_CHECKING: # pragma: no cover
import praw.models
class Inbox(PRAWBase):
"""Inbox is a Listing class that represents the inbox."""
def all( # noqa: A003
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Message | praw.models.Comment]:
"""Return a :class:`.ListingGenerator` for all inbox comments and messages.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
To output the type and ID of all items available via this listing do:
.. code-block:: python
for item in reddit.inbox.all(limit=None):
print(repr(item))
"""
return ListingGenerator(self._reddit, API_PATH["inbox"], **generator_kwargs)
def collapse(self, items: list[praw.models.Message]):
"""Mark an inbox message as collapsed.
:param items: A list containing instances of :class:`.Message`.
Requests are batched at 25 items (reddit limit).
For example, to collapse all unread Messages, try:
.. code-block:: python
from praw.models import Message
unread_messages = []
for item in reddit.inbox.unread(limit=None):
if isinstance(item, Message):
unread_messages.append(item)
reddit.inbox.collapse(unread_messages)
.. seealso::
:meth:`.Message.uncollapse`
"""
while items:
data = {"id": ",".join(x.fullname for x in items[:25])}
self._reddit.post(API_PATH["collapse"], data=data)
items = items[25:]
def comment_replies(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Comment]:
"""Return a :class:`.ListingGenerator` for comment replies.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
To output the author of one request worth of comment replies try:
.. code-block:: python
for reply in reddit.inbox.comment_replies():
print(reply.author)
"""
return ListingGenerator(
self._reddit, API_PATH["comment_replies"], **generator_kwargs
)
def mark_all_read(self):
"""Mark all messages as read with just one API call.
Example usage:
.. code-block:: python
reddit.inbox.mark_all_read()
.. note::
This method returns after Reddit acknowledges your request, instead of after
the request has been fulfilled.
"""
self._reddit.post(API_PATH["read_all_messages"])
def mark_read(self, items: list[praw.models.Comment | praw.models.Message]):
"""Mark Comments or Messages as read.
:param items: A list containing instances of :class:`.Comment` and/or
:class:`.Message` to be marked as read relative to the authorized user's
inbox.
Requests are batched at 25 items (reddit limit).
For example, to mark all unread Messages as read, try:
.. code-block:: python
from praw.models import Message
unread_messages = []
for item in reddit.inbox.unread(limit=None):
if isinstance(item, Message):
unread_messages.append(item)
reddit.inbox.mark_read(unread_messages)
.. seealso::
- :meth:`.Comment.mark_read`
- :meth:`.Message.mark_read`
"""
while items:
data = {"id": ",".join(x.fullname for x in items[:25])}
self._reddit.post(API_PATH["read_message"], data=data)
items = items[25:]
def mark_unread(self, items: list[praw.models.Comment | praw.models.Message]):
"""Unmark Comments or Messages as read.
:param items: A list containing instances of :class:`.Comment` and/or
:class:`.Message` to be marked as unread relative to the authorized user's
inbox.
Requests are batched at 25 items (Reddit limit).
For example, to mark the first 10 items as unread try:
.. code-block:: python
to_unread = list(reddit.inbox.all(limit=10))
reddit.inbox.mark_unread(to_unread)
.. seealso::
- :meth:`.Comment.mark_unread`
- :meth:`.Message.mark_unread`
"""
while items:
data = {"id": ",".join(x.fullname for x in items[:25])}
self._reddit.post(API_PATH["unread_message"], data=data)
items = items[25:]
def mentions(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Comment]:
r"""Return a :class:`.ListingGenerator` for mentions.
A mention is :class:`.Comment` in which the authorized redditor is named in its
body like u/spez.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
For example, to output the author and body of the first 25 mentions try:
.. code-block:: python
for mention in reddit.inbox.mentions(limit=25):
print(f"{mention.author}\\n{mention.body}\\n")
"""
return ListingGenerator(self._reddit, API_PATH["mentions"], **generator_kwargs)
def message(self, message_id: str) -> praw.models.Message:
"""Return a :class:`.Message` corresponding to ``message_id``.
:param message_id: The base36 ID of a message.
For example:
.. code-block:: python
message = reddit.inbox.message("7bnlgu")
"""
listing = self._reddit.get(API_PATH["message"].format(id=message_id))
messages = {
message.fullname: message for message in [listing[0]] + listing[0].replies
}
for _fullname, message in messages.items():
message.parent = messages.get(message.parent_id, None)
return messages[f"t4_{message_id.lower()}"]
def messages(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Message]:
"""Return a :class:`.ListingGenerator` for inbox messages.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
For example, to output the subject of the most recent 5 messages try:
.. code-block:: python
for message in reddit.inbox.messages(limit=5):
print(message.subject)
"""
return ListingGenerator(self._reddit, API_PATH["messages"], **generator_kwargs)
def sent(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Message]:
"""Return a :class:`.ListingGenerator` for sent messages.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
For example, to output the recipient of the most recent 15 messages try:
.. code-block:: python
for message in reddit.inbox.sent(limit=15):
print(message.dest)
"""
return ListingGenerator(self._reddit, API_PATH["sent"], **generator_kwargs)
def stream(
self, **stream_options: str | int | dict[str, str]
) -> Iterator[praw.models.Comment | praw.models.Message]:
"""Yield new inbox items as they become available.
Items are yielded oldest first. Up to 100 historical items will initially be
returned.
Keyword arguments are passed to :func:`.stream_generator`.
For example, to retrieve all new inbox items, try:
.. code-block:: python
for item in reddit.inbox.stream():
print(item)
"""
return stream_generator(self.unread, **stream_options)
def submission_replies(
self, **generator_kwargs: str | int | dict[str, str]
) -> Iterator[praw.models.Comment]:
"""Return a :class:`.ListingGenerator` for submission replies.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
To output the author of one request worth of submission replies try:
.. code-block:: python
for reply in reddit.inbox.submission_replies():
print(reply.author)
"""
return ListingGenerator(
self._reddit, API_PATH["submission_replies"], **generator_kwargs
)
def uncollapse(self, items: list[praw.models.Message]):
"""Mark an inbox message as uncollapsed.
:param items: A list containing instances of :class:`.Message`.
Requests are batched at 25 items (reddit limit).
For example, to uncollapse all unread Messages, try:
.. code-block:: python
from praw.models import Message
unread_messages = []
for item in reddit.inbox.unread(limit=None):
if isinstance(item, Message):
unread_messages.append(item)
reddit.inbox.uncollapse(unread_messages)
.. seealso::
:meth:`.Message.collapse`
"""
while items:
data = {"id": ",".join(x.fullname for x in items[:25])}
self._reddit.post(API_PATH["uncollapse"], data=data)
items = items[25:]
@_deprecate_args("mark_read")
def unread(
self,
*,
mark_read: bool = False,
**generator_kwargs: str | int | dict[str, str],
) -> Iterator[praw.models.Comment | praw.models.Message]:
"""Return a :class:`.ListingGenerator` for unread comments and messages.
:param mark_read: Marks the inbox as read (default: ``False``).
.. note::
This only marks the inbox as read not the messages. Use
:meth:`.Inbox.mark_read` to mark the messages.
Additional keyword arguments are passed in the initialization of
:class:`.ListingGenerator`.
For example, to output the author of unread comments try:
.. code-block:: python
from praw.models import Comment
for item in reddit.inbox.unread(limit=None):
if isinstance(item, Comment):
print(item.author)
"""
self._safely_add_arguments(
arguments=generator_kwargs, key="params", mark=mark_read
)
return ListingGenerator(self._reddit, API_PATH["unread"], **generator_kwargs)