U
    'ci+                     @   s   d ddddddgZ ddlZddlZddlZddlZdd	lmZ dd
lmZ e	e
ZG dd  d ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdS )CacheHandlerCacheFileHandlerDjangoSessionCacheHandlerFlaskSessionCacheHandlerMemoryCacheHandlerRedisCacheHandlerMemcacheCacheHandler    N)
RedisError)CLIENT_CREDS_ENV_VARSc                   @   s    e Zd ZdZdd Zdd ZdS )r   a  
    An abstraction layer for handling the caching and retrieval of
    authorization tokens.

    Custom extensions of this class must implement get_cached_token
    and save_token_to_cache methods with the same input and output
    structure as the CacheHandler class.
    c                 C   s
   t  dS )z@
        Get and return a token_info dictionary object.
        NNotImplementedErrorself r   9/tmp/pip-unpacked-wheel-5vxoxy0m/spotipy/cache_handler.pyget_cached_token    s    zCacheHandler.get_cached_tokenc                 C   s
   t  dS )zS
        Save a token_info dictionary object to the cache and return None.
        Nr   r   
token_infor   r   r   save_token_to_cache'   s    z CacheHandler.save_token_to_cacheN)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   	c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
r   zd
    Handles reading and writing cached Spotify authorization tokens
    as json files on disk.
    Nc                 C   sF   || _ |r|| _n0d}|p&ttd }|r<|dt| 7 }|| _dS )a  
        Parameters:
             * cache_path: May be supplied, will otherwise be generated
                           (takes precedence over `username`)
             * username: May be supplied or set as environment variable
                         (will set `cache_path` to `.cache-{username}`)
             * encoder_cls: May be supplied as a means of overwriting the
                        default serializer used for writing tokens to disk
        z.cacheZclient_username-N)encoder_cls
cache_pathosgetenvr
   str)r   r   usernamer   r   r   r   __init__4   s    zCacheFileHandler.__init__c              
   C   s   d }z0t | jdd}| }W 5 Q R X t|}W nz tk
r } z6|jtjkrft	d| j  nt
d| j  W 5 d }~X Y n( tjk
r   t
d| j  Y nX |S )Nutf-8encodingzcache does not exist at: zCouldn't read cache at: z$Couldn't decode JSON from cache at: )openr   readjsonloadsOSErrorerrnoENOENTloggerdebugwarningJSONDecodeError)r   r   fZtoken_info_stringerrorr   r   r   r   K   s    "z!CacheFileHandler.get_cached_tokenc              	   C   s   zDt | jddd}|tj|| jd W 5 Q R X t| jd W nJ tk
rj   t	
d| j  Y n& tk
r   t	
d| j  Y nX d S )Nwr!   r"   )clsi  z"Couldn't write token to cache at: z+Couldn't set permissions to cache file at: )r$   r   writer&   dumpsr   r   chmodr(   r+   r-   FileNotFoundError)r   r   r/   r   r   r   r   ]   s     z$CacheFileHandler.save_token_to_cache)NNNr   r   r   r   r    r   r   r   r   r   r   r   .   s      
c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
r   z
    A cache handler that simply stores the token info in memory as an
    instance attribute of this class. The token info will be lost when this
    instance is freed.
    Nc                 C   s
   || _ dS )zg
        Parameters:
            * token_info: The token info to store in memory. Can be None.
        Nr   r   r   r   r   r    p   s    zMemoryCacheHandler.__init__c                 C   s   | j S Nr8   r   r   r   r   r   w   s    z#MemoryCacheHandler.get_cached_tokenc                 C   s
   || _ d S r9   r8   r   r   r   r   r   z   s    z&MemoryCacheHandler.save_token_to_cache)Nr7   r   r   r   r   r   i   s   
c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   z
    A cache handler that stores the token info in the session framework
    provided by Django.

    Read more at https://docs.djangoproject.com/en/3.2/topics/http/sessions/
    c                 C   s
   || _ dS )z
        Parameters:
            * request: HttpRequest object provided by Django for every
            incoming request
        N)request)r   r:   r   r   r   r       s    z"DjangoSessionCacheHandler.__init__c                 C   s8   d }z| j jd }W n tk
r2   td Y nX |S Nr   zToken not found in the session)r:   sessionKeyErrorr+   r,   r   r   r   r   r      s    z*DjangoSessionCacheHandler.get_cached_tokenc              
   C   sH   z|| j jd< W n2 tk
rB } ztd|  W 5 d }~X Y nX d S Nr   Error saving token to cache: )r:   r<   	Exceptionr+   r-   r   r   er   r   r   r      s    z-DjangoSessionCacheHandler.save_token_to_cacheNr7   r   r   r   r   r   ~   s   	c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   zd
    A cache handler that stores the token info in the session framework
    provided by flask.
    c                 C   s
   || _ d S r9   )r<   )r   r<   r   r   r   r       s    z!FlaskSessionCacheHandler.__init__c                 C   s6   d }z| j d }W n tk
r0   td Y nX |S r;   )r<   r=   r+   r,   r   r   r   r   r      s    z)FlaskSessionCacheHandler.get_cached_tokenc              
   C   sF   z|| j d< W n2 tk
r@ } ztd|  W 5 d }~X Y nX d S r>   )r<   r@   r+   r-   rA   r   r   r   r      s    z,FlaskSessionCacheHandler.save_token_to_cacheNr7   r   r   r   r   r      s   	c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
r   zB
    A cache handler that stores the token info in the Redis.
    Nc                 C   s   || _ |r|nd| _dS )a  
        Parameters:
            * redis: Redis object provided by redis-py library
            (https://github.com/redis/redis-py)
            * key: May be supplied, will otherwise be generated
                   (takes precedence over `token_info`)
        r   N)rediskey)r   rC   rD   r   r   r   r       s    zRedisCacheHandler.__init__c              
   C   s^   d }z"| j | j}|r$t|W S W n2 tk
rX } ztd|  W 5 d }~X Y nX |S )Nz Error getting token from cache: )rC   getrD   r&   r'   r	   r+   r-   rA   r   r   r   r      s    "z"RedisCacheHandler.get_cached_tokenc              
   C   sR   z| j | jt| W n2 tk
rL } ztd|  W 5 d }~X Y nX d S )Nr?   )rC   setrD   r&   r4   r	   r+   r-   rA   r   r   r   r      s    z%RedisCacheHandler.save_token_to_cache)Nr7   r   r   r   r   r      s   
c                   @   s0   e Zd ZdZd
ddddZdd Zdd	 ZdS )r   zWA Cache handler that stores the token info in Memcache using the pymemcache client
    N)returnc                 C   s   || _ |r|nd| _dS )a*  
        Parameters:
            * memcache: memcache client object provided by pymemcache
            (https://pymemcache.readthedocs.io/en/latest/getting_started.html)
            * key: May be supplied, will otherwise be generated
                   (takes precedence over `token_info`)
        r   N)memcacherD   )r   rH   rD   r   r   r   r       s    zMemcacheCacheHandler.__init__c              
   C   sj   ddl m} z&| j| j}|r0t| W S W n2 |k
rd } zt	d|  W 5 d }~X Y nX d S )Nr   MemcacheErrorzError getting token to cache: )

pymemcacherJ   rH   rE   rD   r&   r'   decoder+   r-   )r   rJ   r   rB   r   r   r   r      s    z%MemcacheCacheHandler.get_cached_tokenc              
   C   s^   ddl m} z| j| jt| W n2 |k
rX } ztd|  W 5 d }~X Y nX d S )Nr   rI   r?   )	rK   rJ   rH   rF   rD   r&   r4   r+   r-   )r   r   rJ   rB   r   r   r   r      s
    z(MemcacheCacheHandler.save_token_to_cache)Nr7   r   r   r   r   r      s   	)__all__r)   r&   loggingr   rC   r	   Zspotipy.utilr
   	getLoggerr   r+   r   r   r   r   r   r   r   r   r   r   r   <module>   s*   	
; "