
    {i                        S r SSKJr  SSKJrJr  SSKJr  SSKJ	r	  SSK
Jr  \	(       a  SSKrSSKr " S	 S
\5      r " S S\5      r " S S\5      rg)a  Token Manager classes.

There should be a 1-to-1 mapping between an instance of a subclass of
:class:`.BaseTokenManager` and a :class:`.Reddit` instance.

A few proof of concept token manager classes are provided here, but it is expected that
PRAW users will create their own token manager classes suitable for their needs.

.. deprecated:: 7.4.0

    Tokens managers have been deprecated and will be removed in the near future.

    )annotations)ABCabstractmethod)Path)TYPE_CHECKING   )_deprecate_argsNc                      \ rS rSrSr\S
S j5       r\S
S j5       r\SS j5       r	\	R                  SS j5       r	S rSrg	)BaseTokenManager   z)An abstract class for all token managers.c                    g)aR  Handle callback that is invoked after a refresh token is used.

:param authorizer: The ``prawcore.Authorizer`` instance used containing
    ``access_token`` and ``refresh_token`` attributes.

This function will be called after refreshing the access and refresh tokens.
This callback can be used for saving the updated ``refresh_token``.

N self
authorizers     Q/home/james-whalen/.local/lib/python3.13/site-packages/praw/util/token_manager.pypost_refresh_callback&BaseTokenManager.post_refresh_callback            c                    g)aY  Handle callback that is invoked before refreshing PRAW's authorization.

:param authorizer: The ``prawcore.Authorizer`` instance used containing
    ``access_token`` and ``refresh_token`` attributes.

This callback can be used to inspect and modify the attributes of the
``prawcore.Authorizer`` instance, such as setting the ``refresh_token``.

Nr   r   s     r   pre_refresh_callback%BaseTokenManager.pre_refresh_callback,   r   r   c                    U R                   $ )z@Return the :class:`.Reddit` instance bound to the token manager._redditr   s    r   redditBaseTokenManager.reddit8   s     ||r   c                D    U R                   b  Sn[        U5      eXl         g )Nz7'reddit' can only be set once and is done automatically)r   RuntimeError)r   valuemsgs      r   r   r   =   s!    <<#KCs##r   c                    SU l         g)z1Initialize a :class:`.BaseTokenManager` instance.Nr   r   s    r   __init__BaseTokenManager.__init__D   s	    r   r   Nr   zprawcore.auth.BaseAuthorizer)returnpraw.Reddit)r"   r)   )__name__
__module____qualname____firstlineno____doc__r   r   r   propertyr   setterr%   __static_attributes__r   r   r   r   r      s\    3	 	 	 	   ]] r   r   c                  D   ^  \ rS rSrSrSU 4S jjrSS jrSS jrSrU =r	$ )	FileTokenManagerI   a  Provides a single-file based token manager.

It is expected that the file with the initial ``refresh_token`` is created prior to
use.

.. warning::

    The same ``file`` should not be used by more than one instance of this class
    concurrently. Doing so may result in data corruption. Consider using
    :class:`.SQLiteTokenManager` if you want more than one instance of PRAW to
    concurrently manage a specific ``refresh_token`` chain.

c                .   > [         TU ]  5         Xl        g)znInitialize a :class:`.FileTokenManager` instance.

:param filename: The file the contains the refresh token.

N)superr%   	_filename)r   filename	__class__s     r   r%   FileTokenManager.__init__X   s     	!r   c                    [        U R                  5      R                  S5       nUR                  UR                  5        SSS5        g! , (       d  f       g= f)z+Update the saved copy of the refresh token.wN)r   r7   openwriterefresh_tokenr   r   fps      r   r   &FileTokenManager.post_refresh_callbacka   s9    $..!&&s+rHHZ--. ,++s   A


Ac                    UR                   cP  [        U R                  5      R                  5        nUR	                  5       R                  5       Ul         SSS5        gg! , (       d  f       g= f)z%Load the refresh token from the file.N)r?   r   r7   r=   readstripr@   s      r   r   %FileTokenManager.pre_refresh_callbackf   sN    ##+dnn%**,+-779??+<
( -, ,,,s   $A
A-)r7   )r8   strr'   )
r*   r+   r,   r-   r.   r%   r   r   r1   __classcell__r9   s   @r   r3   r3   I   s    "/
= =r   r3   c                     ^  \ rS rSrSr\" SS5      SU 4S jj5       rS rSS jrSS jr	SS	 jr
SS
 jrSS jrSrU =r$ )SQLiteTokenManagerm   a  Provides a SQLite3 based token manager.

Unlike, :class:`.FileTokenManager`, the initial database need not be created ahead
of time, as it'll automatically be created on first use. However, initial refresh
tokens will need to be registered via :meth:`.register` prior to use.

.. warning::

    This class is untested on Windows because we encountered file locking issues in
    the test environment.

databasekeyc                 > [         TU ]  5         SSKnUR                  U5      U l        U R                  R                  S5        U R                  R                  S5        U R                  R                  5         X l        g)a  Initialize a :class:`.SQLiteTokenManager` instance.

:param database: The path to the SQLite database.
:param key: The key used to locate the refresh token. This ``key`` can be
    anything. You might use the ``client_id`` if you expect to have unique a
    refresh token for each ``client_id``, or you might use a redditor's
    ``username`` if you're managing multiple users' authentications.

r   NzACREATE TABLE IF NOT EXISTS tokens (id, refresh_token, updated_at)z<CREATE UNIQUE INDEX IF NOT EXISTS ux_tokens_id on tokens(id))r6   r%   sqlite3connect_connectionexecutecommitrN   )r   rM   rN   rP   r9   s       r   r%   SQLiteTokenManager.__init__{   sm     	"??84  O	
 	  J	
 	!r   c                    U R                   R                  SU R                  45      nUR                  5       nUc  [        eUS   $ )N+SELECT refresh_token FROM tokens WHERE id=?r   )rR   rS   rN   fetchoneKeyError)r   cursorresults      r   _getSQLiteTokenManager._get   sE    !!))9DHH;
 ">Nayr   c                    U R                   R                  SU R                  U45        U R                   R                  5         g)zSet the refresh token in the database.

This function will overwrite an existing value if the corresponding ``key``
already exists.

z2REPLACE INTO tokens VALUES (?, ?, datetime('now'))N)rR   rS   rN   rT   )r   r?   s     r   _setSQLiteTokenManager._set   s;     	  @XX}%	
 	!r   c                t    U R                   R                  SU R                  45      nUR                  5       SL$ )z7Return whether ``key`` already has a ``refresh_token``.rW   N)rR   rS   rN   rX   )r   rZ   s     r   is_registered SQLiteTokenManager.is_registered   s7    !!))9DHH;
  ,,r   c                H    U R                  UR                  5        SUl        g)z)Update the refresh token in the database.N)r_   r?   r   s     r   r   (SQLiteTokenManager.post_refresh_callback   s    		***+
 $(
 r   c                L    UR                   b   eU R                  5       Ul         g)z)Load the refresh token from the database.N)r?   r\   r   s     r   r   'SQLiteTokenManager.pre_refresh_callback   s"    ''///#'99;
 r   c                    U R                   R                  SU R                  U45      nU R                   R                  5         UR                  S:H  $ )zRegister the initial refresh token in the database.

:returns: ``True`` if ``refresh_token`` is saved to the database, otherwise,
    ``False`` if there is already a ``refresh_token`` for the associated
    ``key``.

z;INSERT OR IGNORE INTO tokens VALUES (?, ?, datetime('now'))r   )rR   rS   rN   rT   rowcount)r   r?   rZ   s      r   registerSQLiteTokenManager.register   sL     !!))IXX}%
 	!!##r   )rR   rN   )rM   rG   rN   rG   )r?   rG   )r(   boolr'   )r?   rG   r(   rl   )r*   r+   r,   r-   r.   r	   r%   r\   r_   rb   r   r   rj   r1   rH   rI   s   @r   rK   rK   m   sF     Z' (."-(/
$ $r   rK   )r.   
__future__r   abcr   r   pathlibr   typingr    r	   prawcoreprawr   r3   rK   r   r   r   <module>rt      sN    # #    )s )X!=' !=H^$) ^$r   