o
    2gPc                     @   s   d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ erDddlZe
eef Ze
def Ze
eef ZG dd dZG dd deZG dd deZG dd deZ dS )z6Provides classes for interacting with moderator notes.    )islice)TYPE_CHECKINGAny	GeneratorListOptionalTupleUnion   )API_PATH   )PRAWBase)ListingGenerator)Comment)Redditor)
SubmissionNzpraw.models.Subredditc                   @   s  e Zd ZdZ		d'ddZdededefd	d
Zde	e de	e de
d fddZdededefddZdede	e de	e dede
d f
ddZddddddee dedee dee deeeeef  deddfdd Zd!dddd"d#ed$ee dee dee fd%d&ZdS )(BaseModNotesz7Provides base methods to interact with moderator notes.redditpraw.Redditc                 C   s
   || _ dS )zpInitialize a :class:`.BaseModNotes` instance.

        :param reddit: An instance of :class:`.Reddit`.

        N)_reddit)selfr    r   M/home/garg/my-data/venv/lib/python3.10/site-packages/praw/models/mod_notes.py__init__   s   
	zBaseModNotes.__init__redditor	subredditgenerator_kwargsc                 K   s*   t j|d||d t| jtd fi |S )Nparams)	argumentskeyr   user	mod_notes)r   _safely_add_argumentsr   r   r   )r   r   r   r   r   r   r   _all_generator#   s   zBaseModNotes._all_generator	redditors
subredditsreturnpraw.models.ModNoteNNc           
      c   s    t |}t |}	 tt|d}tt|d}t||gs d S dtt|dtt|d}| jjt	d |d}|d D ]
}	| jj
|	V  q?q
)NTi  ,)r%   usersmod_notes_bulkr   r!   )iterlistr   anyjoinmapstrr   getr   	_objector	objectify)
r   r$   r%   subreddits_iterredditors_itersubreddits_chunkusers_chunkr   response	note_dictr   r   r   _bulk_generator1   s   zBaseModNotes._bulk_generatorerror_message
attributesc                 K   s0   |  \}}|pt| |d }|d u rt||S N)popitemgetattr	TypeError)r   r=   r>   	attribute_valuevaluer   r   r   _ensure_attributeC   s
   zBaseModNotes._ensure_attribute	all_notesc                 k   sN    |r|D ]}|D ]}| j ||fi |E d H  q	qd S | ||E d H  d S r?   )r#   r<   )r   rG   r$   r%   r   r   r   r   r   r   _notesJ   s   zBaseModNotes._notesN)labelr   r   thingrI   noterJ   other_settingsr(   c          	      K   s   d}|r7t |tr"|}t| d|rt| d|s!t| jj|gd}n|j}t| d|p-|j}t| d|p6|j}| j	d|d}| j	d|d}t|t||d	}|rU||d
< |r[||d< |
| | jjtd |dS )a  Create a :class:`.ModNote` for a redditor in the specified subreddit.

        :param label: The label for the note. As of this writing, this can be one of the
            following: ``"ABUSE_WARNING"``, ``"BAN"``, ``"BOT_BAN"``,
            ``"HELPFUL_USER"``, ``"PERMA_BAN"``, ``"SOLID_CONTRIBUTOR"``,
            ``"SPAM_WARNING"``, ``"SPAM_WATCH"``, or ``None`` (default: ``None``).
        :param note: The content of the note. As of this writing, this is limited to 250
            characters.
        :param redditor: The redditor to create the note for (default: ``None``).

            .. note::

                This parameter is required if ``thing`` is not provided or this is not
                called from a :class:`.Redditor` instance (e.g.,
                ``reddit.redditor.notes``).

        :param subreddit: The subreddit associated with the note (default: ``None``).

            .. note::

                This parameter is required if ``thing`` is not provided or this is not
                called from a :class:`.Subreddit` instance (e.g.,
                ``reddit.subreddit.mod``).

        :param thing: Either the fullname of a comment/submission, a :class:`.Comment`,
            or a :class:`.Submission` to associate with the note.
        :param other_settings: Additional keyword arguments can be provided to handle
            new parameters as Reddit introduces them.

        :returns: The new :class:`.ModNote` object.

        For example, to create a note for u/spez in r/test:

        .. code-block:: python

            reddit.subreddit("test").mod.notes.create(
                label="HELPFUL_USER", note="Test note", redditor="spez"
            )
            # or
            reddit.redditor("spez").mod.notes.create(
                label="HELPFUL_USER", note="Test note", subreddit="test"
            )
            # or
            reddit.notes.create(
                label="HELPFUL_USER", note="Test note", redditor="spez", subreddit="test"
            )

        Nr   r   )	fullnameszEither the 'redditor' or 'thing' parameters must be provided or this method must be called from a Redditor instance (e.g., 'redditor.notes').r   zEither the 'subreddit' or 'thing' parameters must be provided or this method must be called from a Subreddit instance (e.g., 'subreddit.mod.notes').r   )r    r   rK   rI   	reddit_idr!   )data)
isinstancer2   rA   nextr   infofullnameauthorr   rF   updatepostr   )	r   rI   rK   r   r   rJ   rL   rP   rQ   r   r   r   createZ   s>   :



zBaseModNotes.createF)
delete_allnote_idr   r   rZ   r[   c                C   s   | j d|d}| j d|d}|s|du rd}t||r.| d|g|gD ]}|  q%dS t|t||d}| jjtd	 |d
 dS )aH  Delete note(s) for a redditor.

        :param delete_all: When ``True``, delete all notes for the specified redditor in
            the specified subreddit (default: ``False``).

            .. note::

                This will make a request for each note.

        :param note_id: The ID of the note to delete. This parameter is ignored if
            ``delete_all`` is ``True``.
        :param redditor: The redditor to delete the note(s) for (default: ``None``). Can
            be a :class:`.Redditor` instance or a redditor name.

            .. note::

                This parameter is required if this method is **not** called from a
                :class:`.Redditor` instance (e.g., ``redditor.notes``).

        :param subreddit: The subreddit to delete the note(s) from (default: ``None``).
            Can be a :class:`.Subreddit` instance or a subreddit name.

            .. note::

                This parameter is required if this method is **not** called from a
                :class:`.Subreddit` instance (e.g., ``reddit.subreddit.mod``).


        For example, to delete a note with the ID
        ``"ModNote_d324b280-5ecc-435d-8159-3e259e84e339"``, try:

        .. code-block:: python

            reddit.subreddit("test").mod.notes.delete(
                note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", redditor="spez"
            )
            # or
            reddit.redditor("spez").notes.delete(
                note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", subreddit="test"
            )
            # or
            reddit.notes.delete(
                note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339",
                subreddit="test",
                redditor="spez",
            )

        To delete all notes for u/spez, try:

        .. code-block:: python

            reddit.subreddit("test").mod.notes.delete(delete_all=True, redditor="spez")
            # or
            reddit.redditor("spez").notes.delete(delete_all=True, subreddit="test")
            # or
            reddit.notes.delete(delete_all=True, subreddit="test", redditor="spez")

        zEither the 'redditor' parameter must be provided or this method must be called from a Redditor instance (e.g., 'redditor.notes').rN   zEither the 'subreddit' parameter must be provided or this method must be called from a Subreddit instance (e.g., 'subreddit.mod.notes').rO   Nz2Either 'note_id' or 'delete_all' must be provided.T)r    r   r[   r!   r,   )rF   rB   rH   deleter2   r   r   )r   rZ   r[   r   r   msgrK   r   r   r   r   r\      s(   B
zBaseModNotes.delete)r   r   )__name__
__module____qualname____doc__r   RedditorTypeSubredditTyper   r#   r   r   r<   r2   rF   boolrH   r   r	   r   r   rY   r\   r   r   r   r   r      s~    



	
cr   c                
       R   e Zd ZdZdddef fddZddd	ed
ee de	de
d fddZ  ZS )RedditorModNotesa  Provides methods to interact with moderator notes at the redditor level.

    .. note::

        The authenticated user must be a moderator of the provided subreddit(s).

    For example, all the notes for u/spez in r/test can be iterated through like so:

    .. code-block:: python

        redditor = reddit.redditor("spez")

        for note in redditor.notes.subreddits("test"):
            print(f"{note.label}: {note.note}")

    r   r   r   c                       t  | || _dS )zInitialize a :class:`.RedditorModNotes` instance.

        :param reddit: An instance of :class:`.Reddit`.
        :param redditor: An instance of :class:`.Redditor`.

        N)superr   r   )r   r   r   	__class__r   r   r   '     
zRedditorModNotes.__init__NrG   r%   rG   r   r&   r'   c                O   sR   t |dkrd}t||du rt |dk}| j|| jgt | t|fi |S )aI  Return notes for this :class:`.Redditor` from one or more subreddits.

        :param subreddits: One or more subreddits to retrieve the notes from. Must be
            either a :class:`.Subreddit` or a subreddit name.
        :param all_notes: Whether to return all notes or only the latest note (default:
            ``True`` if only one subreddit is provided otherwise ``False``).

            .. note::

                Setting this to ``True`` will result in a request for each subreddit.


        :returns: A generator that yields the most recent :class:`.ModNote` (or ``None``
            if this redditor doesn't have any notes) per subreddit in their relative
            order. If ``all_notes`` is ``True``, this will yield all notes or ``None``
            from each subreddit for this redditor.

        For example, all the notes for u/spez in r/test can be iterated through like so:

        .. code-block:: python

            redditor = reddit.redditor("spez")

            for note in redditor.notes.subreddits("test"):
                print(f"{note.label}: {note.note}")

        For example, the latest note for u/spez from r/test and r/redditdev can be
        iterated through like so:

        .. code-block:: python

            redditor = reddit.redditor("spez")
            subreddit = reddit.subreddit("redditdev")

            for note in redditor.notes.subreddits("test", subreddit):
                print(f"{note.label}: {note.note}")

        For example, **all** the notes for u/spez in r/test and r/redditdev can be
        iterated through like so:

        .. code-block:: python

            redditor = reddit.redditor("spez")
            subreddit = reddit.subreddit("redditdev")

            for note in redditor.notes.subreddits("test", subreddit, all_notes=True):
                print(f"{note.label}: {note.note}")

        r   z&At least 1 subreddit must be provided.Nr   )len
ValueErrorrH   r   r.   )r   rG   r%   r   r]   r   r   r   r%   1  s   7zRedditorModNotes.subreddits)r^   r_   r`   ra   rb   r   rc   r   rd   r   r   r%   __classcell__r   r   ri   r   rf         rf   c                
       re   )SubredditModNotesa  Provides methods to interact with moderator notes at the subreddit level.

    .. note::

        The authenticated user must be a moderator of this subreddit.

    For example, all the notes for u/spez in r/test can be iterated through like so:

    .. code-block:: python

        subreddit = reddit.subreddit("test")

        for note in subreddit.mod.notes.redditors("spez"):
            print(f"{note.label}: {note.note}")

    r   r   r   c                    rg   )zInitialize a :class:`.SubredditModNotes` instance.

        :param reddit: An instance of :class:`.Reddit`.
        :param subreddit: An instance of :class:`.Subreddit`.

        N)rh   r   r   )r   r   r   ri   r   r   r     rk   zSubredditModNotes.__init__Nrl   r$   rG   r   r&   r'   c                O   sR   t |dkrd}t||du rt |dk}| j|t|| jgt | fi |S )a'  Return notes from this :class:`.Subreddit` for one or more redditors.

        :param redditors: One or more redditors to retrieve notes for. Must be either a
            :class:`.Redditor` or a redditor name.
        :param all_notes: Whether to return all notes or only the latest note (default:
            ``True`` if only one redditor is provided otherwise ``False``).

            .. note::

                Setting this to ``True`` will result in a request for each redditor.


        :returns: A generator that yields the most recent :class:`.ModNote` (or ``None``
            if the user doesn't have any notes in this subreddit) per redditor in their
            relative order. If ``all_notes`` is ``True``, this will yield all notes for
            each redditor.

        For example, all the notes for u/spez in r/test can be iterated through like so:

        .. code-block:: python

            subreddit = reddit.subreddit("test")

            for note in subreddit.mod.notes.redditors("spez"):
                print(f"{note.label}: {note.note}")

        For example, the latest note for u/spez and u/bboe from r/test can be iterated
        through like so:

        .. code-block:: python

            subreddit = reddit.subreddit("test")
            redditor = reddit.redditor("bboe")

            for note in subreddit.mod.notes.redditors("spez", redditor):
                print(f"{note.label}: {note.note}")

        For example, **all** the notes for both u/spez and u/bboe in r/test can be
        iterated through like so:

        .. code-block:: python

            subreddit = reddit.subreddit("test")
            redditor = reddit.redditor("bboe")

            for note in subreddit.mod.notes.redditors("spez", redditor, all_notes=True):
                print(f"{note.label}: {note.note}")

        r   z%At least 1 redditor must be provided.Nr   )rm   rn   rH   r.   r   )r   rG   r$   r   r]   r   r   r   r$     s   7zSubredditModNotes.redditors)r^   r_   r`   ra   rc   r   rb   r   rd   r   r   r$   ro   r   r   ri   r   rq   u  rp   rq   c                   @   s   e Zd ZdZdddddddedeeeee	f   deee	  deee  d	eee
  d
eded fddZddd	e
dee d
eded fddZdS )RedditModNotesa`  Provides methods to interact with moderator notes at a global level.

    .. note::

        The authenticated user must be a moderator of the provided subreddit(s).

    For example, the latest note for u/spez in r/redditdev and r/test, and for u/bboe in
    r/redditdev can be iterated through like so:

    .. code-block:: python

        redditor = reddit.redditor("bboe")
        subreddit = reddit.subreddit("redditdev")

        pairs = [(subreddit, "spez"), ("test", "spez"), (subreddit, redditor)]

        for note in reddit.notes(pairs=pairs):
            print(f"{note.label}: {note.note}")

    FN)rG   pairsr$   r%   thingsrG   rs   r$   r%   rt   r   r&   r'   c                   s<  |du rg }|du rg } du rg  |du rg }||   | s&d}t |t|t  dkrGt|t  dkrGt t dkrDddg }g }	| fddt|D  | }
|
D ]6}t|ttfrt||jj |	|j	j
 q\t|tr|\}}|| |	| q\dt| }t|| j|||	fi |S )	ac  Get note(s) for each subreddit/user pair, or ``None`` if they don't have any.

        :param all_notes: Whether to return all notes or only the latest note for each
            subreddit/redditor pair (default: ``False``).

            .. note::

                Setting this to ``True`` will result in a request for each unique
                subreddit/redditor pair. If ``subreddits`` and ``redditors`` are
                provided, this will make a request equivalent to number of redditors
                multiplied by the number of subreddits.

        :param pairs: A list of subreddit/redditor tuples.

            .. note::

                Required if ``subreddits``, ``redditors``, nor ``things`` are provided.

        :param redditors: A list of redditors to return notes for. This parameter is
            used in tandem with ``subreddits`` to get notes from multiple subreddits for
            each of the provided redditors.

            .. note::

                Required if ``items`` or ``things`` is not provided or if ``subreddits``
                **is** provided.

        :param subreddits: A list of subreddits to return notes for. This parameter is
            used in tandem with ``redditors`` to get notes for multiple redditors from
            each of the provided subreddits.

            .. note::

                Required if ``items`` or ``things`` is not provided or if ``redditors``
                **is** provided.

        :param things: A list of comments and/or submissions to return notes for.
        :param generator_kwargs: Additional keyword arguments passed to the generator.
            This parameter is ignored when ``all_notes`` is ``False``.

        :returns: A generator that yields the most recent :class:`.ModNote` (or ``None``
            if the user doesn't have any notes) per entry in their relative order. If
            ``all_notes`` is ``True``, this will yield all notes for each entry.

        .. note::

            This method will merge the subreddits and redditors provided from ``pairs``,
            ``redditors``, ``subreddits``, and ``things``.

        .. note::

            This method accepts :class:`.Redditor` instances or redditor names and
            :class:`.Subreddit` instances or subreddit names where applicable.

        For example, the latest note for u/spez in r/redditdev and r/test, and for
        u/bboe in r/redditdev can be iterated through like so:

        .. code-block:: python

            redditor = reddit.redditor("bboe")
            subreddit = reddit.subreddit("redditdev")

            pairs = [(subreddit, "spez"), ("test", "spez"), (subreddit, redditor)]

            for note in reddit.notes(pairs=pairs):
                print(f"{note.label}: {note.note}")

        For example, **all** the notes for u/spez and u/bboe in r/announcements,
        r/redditdev, and r/test can be iterated through like so:

        .. code-block:: python

            redditor = reddit.redditor("bboe")
            subreddit = reddit.subreddit("redditdev")

            for note in reddit.notes(
                redditors=["spez", redditor],
                subreddits=["announcements", subreddit, "test"],
                all_notes=True,
            ):
                print(f"{note.label}: {note.note}")

        For example, the latest note for the authors of the last 5 comments and
        submissions from r/test can be iterated through like so:

        .. code-block:: python

            submissions = list(reddit.subreddit("test").new(limit=5))
            comments = list(reddit.subreddit("test").comments(limit=5))

            for note in reddit.notes(things=submissions + comments):
                print(f"{note.label}: {note.note}")

        .. note::

            Setting ``all_notes`` to ``True`` will make a request for each redditor and
            subreddit combination. The previous example will make 6 requests.

        NzWEither the 'pairs', 'redditors', 'subreddits', or 'things' parameters must be provided.r   z;'redditors' must be non-empty if 'subreddits' is not empty.z;'subreddits' must be non-empty if 'redditors' is not empty.c                    s"   g | ]}t  D ]}||fqqS r   )set).0r   r   r%   r   r   
<listcomp>q  s    z+RedditModNotes.__call__.<locals>.<listcomp>z1Cannot get subreddit and author fields from type )rB   rm   ru   rR   r   r   appendrV   namer   display_namer   typern   rH   )r   rG   rs   r$   r%   rt   r   r]   merged_redditorsmerged_subredditsitemsitemr   r   r   rw   r   __call__  sX   m



zRedditModNotes.__call__rl   c                O   sT   g }g }|D ]}| |j | |j q|du rt|dk}| j|||fi |S )a]  Return notes associated with the author of a :class:`.Comment` or :class:`.Submission`.

        :param things: One or more things to return notes on. Must be a
            :class:`.Comment` or :class:`.Submission`.
        :param all_notes: Whether to return all notes, or only the latest (default:
            ``True`` if only one thing is provided otherwise ``False``).

            .. note::

                Setting this to ``True`` will result in a request for each thing.


        :returns: A generator that yields the most recent :class:`.ModNote` (or ``None``
            if the user doesn't have any notes) per entry in their relative order. If
            ``all_notes`` is ``True``, this will yield all notes for each entry.

        For example, to get the latest note for the authors of the top 25 submissions in
        r/test:

        .. code-block:: python

            submissions = reddit.subreddit("test").top(limit=25)
            for note in reddit.notes.things(*submissions):
                print(f"{note.label}: {note.note}")

        For example, to get the latest note for the authors of the last 25 comments in
        r/test:

        .. code-block:: python

            comments = reddit.subreddit("test").comments(limit=25)
            for note in reddit.notes.things(*comments):
                print(f"{note.label}: {note.note}")

        Nr   )ry   r   rV   rm   rH   )r   rG   rt   r   r%   r$   rJ   r   r   r   rt     s   )zRedditModNotes.things)r^   r_   r`   ra   rd   r   r   r   rc   rb   	ThingTyper   r   r   rt   r   r   r   r   rr     sB    


	
 !rr   )!ra   	itertoolsr   typingr   r   r   r   r   r   r	   constr   baser   listing.generatorr   reddit.commentr   reddit.redditorr   reddit.submissionr   praw.modelsprawr2   rb   rc   r   r   rf   rq   rr   r   r   r   r   <module>   s(    $  ``