o
    ]fg                  
   @   s   d dl Z d dlZd dlZd dlmZ eeZzd dlm	Z	 d dl
mZmZ W n ey8 Z zededZ[ww G dd deZdS )    N)	BaseCache)AnonymousCredentials)storage
exceptionsz$no google-cloud-storage module foundc                       s   e Zd ZdZ				d" fdd	Zedd Zd	d
 Zd#ddZd#ddZ	dd Z
dd Zdd Zdd Zd$ddZdd Zdd Zdd Zd%d d!Z  ZS )&GoogleCloudStorageCachea  Uses an Google Cloud Storage bucket as a cache backend.
    Note: User-contributed functionality. This project does not guarantee that
    this functionality will be maintained or functional at any given time.
    Note: Cache keys must meet GCS criteria for a valid object name (a sequence
    of Unicode characters whose UTF-8 encoding is at most 1024 bytes long).
    Note: Expired cache objects are not automatically purged. If
    delete_expired_objects_on_read=True, they will be deleted following an
    attempted read (which reduces performance). Otherwise, you have to delete
    stale objects yourself. Consider an GCS bucket lifecycle rule or other
    out-of-band process. For example you can use the following rule.
    {"rule": [{"action": {"type": "Delete"}, "condition": {"daysSinceCustomTime": 0}}]}
    https://cloud.google.com/storage/docs/lifecycle#dayssincecustomtime
    :param bucket: Required. Name of the bucket to use. It must already exist.
    :param key_prefix: A prefix that should be added to all keys.
    :param default_timeout: the default timeout that is used if no timeout is
                            specified on :meth:`~BaseCache.set`. A timeout of
                            0 indicates that the cache never expires.
    :param delete_expired_objects_on_read: If True, if a read finds a stale
                                           object, it will be deleted before
                                           a response is returned. Will slow
                                           down responses.
    :param anonymous: If true, use anonymous credentials. Useful for testing.
    Any additional keyword arguments will be passed to ``google.cloud.storage.Client``.
    N,  Fc                    sx   t  | t|tstd|rtjdt dd|| _n	tjdi || _| j	|| _
|p2d| _|| _|| _d S )Nz*GCSCache bucket parameter must be a stringtest)credentialsproject  )super__init__
isinstancestr
ValueErrorr   Clientr   _client
get_bucketbucket
key_prefixdefault_timeoutdelete_expired_objects_on_read)selfr   r   r   r   	anonymouskwargs	__class__r   f/home/ubuntu/webapp/venv/lib/python3.10/site-packages/flask_caching/contrib/googlecloudstoragecache.pyr   ,   s   	



z GoogleCloudStorageCache.__init__c                 C   s4   | d|d  |d}|r||d< | |i |S )Nr   CACHE_GCS_BUCKETCACHE_KEY_PREFIXr   )insertget)clsappconfigargsr   r   r   r   r   factoryC   s
   
zGoogleCloudStorageCache.factoryc                 C   s   d }d}d}| j | }| j|}|d urG|jo|  |jk}|r*| jr)| | nz| }d}|jdkr;t	
|}W n
 tjyF   Y nw |rKdnd}td||| |S )NFmisshitapplication/json	(expired)r   zget key %r -> %s %s)r   r   get_blobcustom_time_nowr   _deletedownload_as_bytescontent_typejsonloadsr   NotFoundloggerdebug)r   keyresultexpiredhit_or_missfull_keyblob
expiredstrr   r   r   r"   K   s.   



zGoogleCloudStorageCache.getc              	   C   s   d}| j | }d}zt|}W n ttfy   d}Y nw | j|}|d u r+| j}|dkr6| j|d|_	z|j
||d d}W n
 tjyK   Y nw td|| |S )	NFr*   zapplication/octet-streamr   )delta)r1   Tzset key %r -> %s)r   r2   dumpsUnicodeDecodeError	TypeErrorr   r<   r   r.   r-   upload_from_stringr   TooManyRequestsr5   r6   )r   r7   valuetimeoutr8   r;   r1   r<   r   r   r   setc   s*   
zGoogleCloudStorageCache.setc                 C   s2   | j | }| |rtd| dS | |||S )Nzadd key %r -> not addedF)r   _hasr5   r6   rF   )r   r7   rD   rE   r;   r   r   r   addz   s
   

zGoogleCloudStorageCache.addc                 C      | j | }| |S N)r   r/   r   r7   r;   r   r   r   delete      

zGoogleCloudStorageCache.deletec                    s      fdd|D S )Nc                 3   s    | ]} j | V  qd S rJ   )r   ).0r7   r   r   r   	<genexpr>   s    z6GoogleCloudStorageCache.delete_many.<locals>.<genexpr>_delete_many)r   keysr   rO   r   delete_many   s   z#GoogleCloudStorageCache.delete_manyc                 C   rI   rJ   )r   rG   rK   r   r   r   has   rM   zGoogleCloudStorageCache.hasc                 C   s   | j ddS )NT)	clear_all)_prunerO   r   r   r   clear      zGoogleCloudStorageCache.clearc                 C   s   d}|   }| jj| j| jdd}g }|D ]#}|s!|jr8|j|k r8||j |d7 }t|dkr8| 	| g }q|r@| 	| t
d| dS )Nr   z$items(name,customTime),nextPageToken)prefixfields   d   zevicted %d key(s)T)r.   r   
list_blobsr   r   r-   appendnamelenrR   r5   r6   )r   rV   nremovednowresponse_iterator	to_deleter<   r   r   r   rW      s(   

zGoogleCloudStorageCache._prunec                 C   s   |  |gS rJ   rQ   )r   r7   r   r   r   r/      rY   zGoogleCloudStorageCache._deletec              	   C   sh   z%| j   |D ]}| j| q	W d    W dS 1 sw   Y  W dS  tjtjfy3   Y dS w )NT)r   batchr   delete_blobr   r4   rC   )r   rS   r7   r   r   r   rR      s   z$GoogleCloudStorageCache._delete_manyc                 C   sj   d}d}| j |}|d ur%|jo|  |jk}|r#| jr"| | nd}|r)dnd}td||| |S )NFTr+   r   zhas key %r -> %s %s)r   r,   r-   r.   r   r/   r5   r6   )r   r7   r8   r9   r<   r=   r   r   r   rG      s   
zGoogleCloudStorageCache._hasr   c                 C   s   t j t jjt j|d S )N)seconds)datetimerc   timezoneutc	timedelta)r   r>   r   r   r   r.      s   zGoogleCloudStorageCache._now)Nr   FFrJ   )F)r   )__name__
__module____qualname____doc__r   classmethodr'   r"   rF   rH   rL   rT   rU   rX   rW   r/   rR   rG   r.   __classcell__r   r   r   r   r      s*    



	r   )ri   r2   loggingflask_caching.backends.baser   	getLoggerrm   r5   google.auth.credentialsr   google.cloudr   r   ImportErroreRuntimeErrorr   r   r   r   r   <module>   s    

