
    Ջgg                         d dl Z d dlZd dlZd dlmZ  ej
                  e      Z	 d dlm	Z	 d dl
mZmZ  G d de      Zy# e$ rZ ed      edZ[ww xY w)    N)	BaseCache)AnonymousCredentials)storage
exceptionsz$no google-cloud-storage module foundc                        e Zd ZdZ	 	 	 	 d fd	Zed        Zd ZddZddZ	d Z
d Zd	 Zd
 ZddZd Zd Zd ZddZ x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``.
    c                 P   t         |   |       t        |t              st	        d      |r&t        j                  dt               dd|| _        nt        j                  di || _        | j                  j                  |      | _
        |xs d| _        || _        || _        y )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__s          `/var/www/html/venv/lib/python3.12/site-packages/flask_caching/contrib/googlecloudstoragecache.pyr   z GoogleCloudStorageCache.__init__,   s     	)&#&IJJ">> 02FFLDL #>>3F3DLll--f5$*..L+    c                 l    |j                  d|d          |j                  d      }|r||d<    | |i |S )Nr   CACHE_GCS_BUCKETCACHE_KEY_PREFIXr   )insertget)clsappconfigargsr   r   s         r   factoryzGoogleCloudStorageCache.factoryC   sB    Av012ZZ 23
#-F< D#F##r    c                    d }d}d}| j                   |z   }| j                  j                  |      }||j                  xr | j	                         |j                  kD  }|r| j
                  rI| j                  |       n7	 |j                         }d}|j                  dk(  rt        j                  |      }|rdnd}t        j                  d|||       |S # t        j                  $ r Y 5w xY w)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
expiredstrs           r   r%   zGoogleCloudStorageCache.getK   s    ??S({{##H-&&I499;9I9I+IG66LL*!335F"'K((,>>!%F!3 %,[
*Hk:N	 "** s   ?6C C+*C+c                    d}| j                   |z   }d}	 t        j                  |      }| j
                  j                  |      }|| j                  }|dk7  r| j                  |      |_	        	 |j                  ||       d}t        j                  d||       |S # t        t        f$ r d}Y w xY w# t        j                  $ r Y Ew xY w)	NFr.   zapplication/octet-streamr   )delta)r5   Tzset key %r -> %s)r   r6   dumpsUnicodeDecodeError	TypeErrorr   r@   r   r2   r1   upload_from_stringr   TooManyRequestsr9   r:   )r   r;   valuetimeoutr<   r?   r5   r@   s           r   setzGoogleCloudStorageCache.setc   s    ??S()	6JJu%E {{)?**Ga<  $yywy7D	##E#EF 	'6: #I. 	65L	6 )) 		s#   B 0B5 B21B25C
Cc                     | j                   |z   }| j                  |      rt        j                  d|       y| j	                  |||      S )Nzadd key %r -> not addedF)r   _hasr9   r:   rK   )r   r;   rI   rJ   r?   s        r   addzGoogleCloudStorageCache.addz   sA    ??S(99XLL2H=88C00r    c                 B    | j                   |z   }| j                  |      S N)r   r3   r   r;   r?   s      r   deletezGoogleCloudStorageCache.delete   s    ??S(||H%%r    c                 8      j                   fd|D              S )Nc              3   <   K   | ]  }j                   |z     y wrP   )r   ).0r;   r   s     r   	<genexpr>z6GoogleCloudStorageCache.delete_many.<locals>.<genexpr>   s      G33!6 Gs   _delete_many)r   keyss   ` r   delete_manyz#GoogleCloudStorageCache.delete_many   s       G$ GGGr    c                 B    | j                   |z   }| j                  |      S rP   )r   rM   rQ   s      r   haszGoogleCloudStorageCache.has   s    ??S(yy""r    c                 &    | j                  d      S )NT)	clear_all)_prune)r   s    r   clearzGoogleCloudStorageCache.clear   s    {{T{**r    c                    d}| j                         }| j                  j                  | j                  | j                  d      }g }|D ]c  }|s|j
                  s|j
                  |k  s"|j                  |j                         |dz  }t        |      dk(  sQ| j                  |       g }e |r| j                  |       t        j                  d|       y)Nr   z$items(name,customTime),nextPageToken)prefixfields   d   zevicted %d key(s)T)r2   r   
list_blobsr   r   r1   appendnamelenrX   r9   r:   )r   r^   nremovednowresponse_iterator	to_deleter@   s          r   r_   zGoogleCloudStorageCache._prune   s    iik LL33KK??9 4 

 	% 	#DD,,1A1AC1G  +Ay>S(%%i0 "I	# i(((3r    c                 &    | j                  |g      S rP   rW   )r   r;   s     r   r3   zGoogleCloudStorageCache._delete   s      #''r    c                     	 | j                   j                         5  |D ]  }| j                  j                  |        	 d d d        y# 1 sw Y   yxY w# t        j
                  t        j                  f$ r Y yw xY w)NT)r   batchr   delete_blobr   r8   rH   )r   rY   r;   s      r   rX   z$GoogleCloudStorageCache._delete_many   sy    	##% 1 1CKK++C011
 1
  ##Z%?%?@ 		s.   A #A	 A 	AA A #A;:A;c                    d}d}| j                   j                  |      }|M|j                  xr | j                         |j                  kD  }|r| j                  r| j                  |       nd}|rdnd}t        j                  d|||       |S )NFTr/   r   zhas key %r -> %s %s)r   r0   r1   r2   r   r3   r9   r:   )r   r;   r<   r=   r@   rA   s         r   rM   zGoogleCloudStorageCache._has   s    {{##C(&&I499;9I9I+IG66LL%$+[
*CDr    c                     t         j                   j                  t         j                  j                        t        j                  |      z   S )N)seconds)datetimerk   timezoneutc	timedelta)r   rC   s     r   r2   zGoogleCloudStorageCache._now   s<      $$X%6%6%:%:;h>P>P?
 
 	
r    )Ni,  FFrP   )F)r   )__name__
__module____qualname____doc__r   classmethodr*   r%   rK   rN   rR   rZ   r\   r`   r_   r3   rX   rM   r2   __classcell__)r   s   @r   r   r      sm    8 ',M. $ $0.1&H#+.( 
r    r   )ru   r6   loggingflask_caching.backends.baser   	getLoggerry   r9   google.auth.credentialsr   google.cloudr   r   ImportErroreRuntimeErrorr   r   r    r   <module>r      sa       1 
		8	$F<0
t
i t
	  F
=
>AEFs   A   A	AA