o
    {l~i .                     @   sV  d dl Z d dlZd dl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 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 d dlmZ d dlmZ d dlmZ 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# W n e$y   edw dZ%dZ&G dd deeZ'eG dd deZ(dS )    N)	timedelta)SpooledTemporaryFile)ImproperlyConfigured)SuspiciousOperation)File)timezone)deconstructible)BaseStorage)CompressedFileMixin)check_location)
clean_name)get_available_overwrite_name)	safe_join)setting)to_bytes)NotFound)Blob)Client)_quote)DEFAULT_RETRYzfCould not load Google Cloud Storage bindings.
See https://github.com/GoogleCloudPlatform/gcloud-pythoncontent_encodingcontent_typec                       s`   e Zd Zdd Zedd Zdd Zdd ZeeeZd fd
d	Z	 fddZ
dd Z  ZS )GoogleCloudFilec                 C   sj   || _ t|d | _|| _|| _|jj||jd| _	| j	s-d|v r-t
| j |j|jd| _	d | _d| _d S )Nr   )
chunk_sizewF)name	mimetypes
guess_type	mime_type_mode_storagebucketget_blobblob_chunk_sizeblobr   _file	_is_dirty)selfr   modestorage r*   _/var/www/newdalilibackend/backend/venv/lib/python3.10/site-packages/storages/backends/gcloud.py__init__(   s   
zGoogleCloudFile.__init__c                 C   s   | j jS N)r$   sizer'   r*   r*   r+   r.   5   s   zGoogleCloudFile.sizec                 C   sz   | j d u r:t| jjdtdd| _ d| jv r&d| _| j| j  | j 	d | jj
r:| jjdkr:| j| j| j d| _ | j S )	Nz.GSStorageFileFILE_UPLOAD_TEMP_DIR)max_sizesuffixdirrFr   gzip)r(   file)r%   r   r    max_memory_sizer   r   r&   r$   download_to_fileseekr5   r   _decompress_filer/   r*   r*   r+   	_get_file9   s   

zGoogleCloudFile._get_filec                 C   s
   || _ d S r-   )r%   )r'   valuer*   r*   r+   	_set_fileH   s   
zGoogleCloudFile._set_fileNc                    s*   d| j vr	td|d u rd}t |S )Nr4   z!File was not opened in read mode.)r   AttributeErrorsuperread)r'   	num_bytes	__class__r*   r+   rA   M   s
   
zGoogleCloudFile.readc                    s(   d| j vr	tdd| _t t|S )Nr   z"File was not opened in write mode.T)r   r?   r&   r@   writer   )r'   contentrC   r*   r+   rE   V   s   
zGoogleCloudFile.writec              	   C   s\   | j d ur,| jr"| j| j}| jj| jd| jt	|
d| jjd | j   d | _ d S d S )NTacl)rewindr   retrypredefined_acl)r%   r&   r    get_object_parametersr   r$   upload_from_filer6   r   r   getdefault_aclclose)r'   blob_paramsr*   r*   r+   rO   \   s   


zGoogleCloudFile.closer-   )__name__
__module____qualname__r,   propertyr.   r;   r=   r6   rA   rE   rO   __classcell__r*   r*   rC   r+   r   '   s    

	r   c                       s   e Zd Z fddZdd Zedd Zedd Zd	d
 Zd'ddZ	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd(d#d$Zd( fd%d&	Z  ZS ))GoogleCloudStoragec                    s*   t  jdi | t|  d | _d | _d S )Nr*   )r@   r,   r   _bucket_client)r'   settingsrC   r*   r+   r,   m   s   
zGoogleCloudStorage.__init__c                 C   sr   t dt dt dt dd t ddt dt dd	t d
tddt ddt ddt dd	t di t ddt ddS )NGS_PROJECT_IDGS_CREDENTIALSGS_BUCKET_NAMEGS_CUSTOM_ENDPOINTGS_LOCATION GS_DEFAULT_ACLGS_QUERYSTRING_AUTHTGS_EXPIRATIONiQ )secondsGS_IS_GZIPPEDFGZIP_CONTENT_TYPES)ztext/cssztext/javascriptzapplication/javascriptzapplication/x-javascriptzimage/svg+xmlGS_FILE_OVERWRITEGS_OBJECT_PARAMETERSGS_MAX_MEMORY_SIZEr   GS_BLOB_CHUNK_SIZE)
project_idcredentialsbucket_namecustom_endpointlocationrN   querystring_auth
expirationr5   gzip_content_typesfile_overwriteobject_parametersr7   r#   )r   r   r/   r*   r*   r+   get_default_settingsu   s$   
z'GoogleCloudStorage.get_default_settingsc                 C   s"   | j d u rt| j| jd| _ | j S )N)projectrk   )rX   r   rj   rk   r/   r*   r*   r+   client   s   
zGoogleCloudStorage.clientc                 C   s    | j d u r| j| j| _ | j S r-   )rW   rv   r!   rl   r/   r*   r*   r+   r!      s   
zGoogleCloudStorage.bucketc                 C   s*   zt | j|W S  ty   td| w )aA  
        Normalizes the name so that paths like /path/to/ignored/../something.txt
        and ./file.txt work.  Note that clean_name adds ./ to some paths so
        they need to be fixed here. We check to make sure that the path pointed
        to is not outside the directory specified by the LOCATION setting.
        z Attempted access to '%s' denied.)r   rn   
ValueErrorr   r'   r   r*   r*   r+   _normalize_name   s
   z"GoogleCloudStorage._normalize_namerbc                 C   s0   |  t|}t||| }|jstd| |S )NzFile does not exist: %s)ry   r   r   r$   FileNotFoundError)r'   r   r(   file_objectr*   r*   r+   _open   s
   zGoogleCloudStorage._openc                 C   sb   | d t }tjd|dd}|t|  W d    n1 s%w   Y  | d |S )Nr   wbg        )r(   fileobjmtime)r9   ioBytesIOr5   GzipFilerE   r   rA   )r'   rF   zbufzfiler*   r*   r+   _compress_content   s   

z$GoogleCloudStorage._compress_contentc           	      C   s   t |}| |}||_t|d| }i }| |}|d| j|d< |t|j|t< | j	rB|t | j
v rBt|vrB| |}d|t< | D ]\}}t|j|| qF|jj|fdtt|dd d| |S )NrwrG   rJ   r5   Tr.   )rH   rI   r.   )r   ry   r   r   rK   poprN   CONTENT_TYPEr   r5   rq   CONTENT_ENCODINGr   itemssetattrr$   rL   r   getattr)	r'   r   rF   cleaned_namer|   upload_paramsrP   propvalr*   r*   r+   _save   s8   



zGoogleCloudStorage._savec                 C   s   | j  }|S )zOverride this to return a dictionary of overwritable blob-property to value.

        Returns GS_OBJECT_PARAMETRS by default. See the docs for all possible options.
        )rs   copy)r'   r   rs   r*   r*   r+   rK      s   
z(GoogleCloudStorage.get_object_parametersc                 C   s:   |  t|}z| jj|td W d S  ty   Y d S w )N)rI   )ry   r   r!   delete_blobr   r   rx   r*   r*   r+   delete   s   zGoogleCloudStorage.deletec                 C   sL   |sz
| j | j W dS  ty   Y dS w | t|}t| j|S )NTF)rv   
get_bucketr!   r   ry   r   boolr"   rx   r*   r*   r+   exists   s   zGoogleCloudStorage.existsc           
      C   s   |  t|}|r|ds|d7 }| jj|dd}t|}|j}g }g }|D ]}|jd}|	|d  q'|D ]}	|	d}|	|d  q9t||fS )N/)prefix	delimiterr>   )
ry   r   endswithr!   
list_blobslistprefixesr   splitappend)
r'   r   iteratorblobsr   filesdirsr$   partsfolder_pathr*   r*   r+   listdir   s   
zGoogleCloudStorage.listdirc                 C   s&   | j |}|d u rtd||S )NzFile does not exist: {})r!   r"   r   formatr'   r   r$   r*   r*   r+   	_get_blob  s   zGoogleCloudStorage._get_blobc                 C   s   |  t|}| |}|jS r-   )ry   r   r   r.   r   r*   r*   r+   r.     s   
zGoogleCloudStorage.sizec                 C   4   |  t|}| |}|j}tdr|S t|S )NUSE_TZ)ry   r   r   updatedr   r   
make_naive)r'   r   r$   r   r*   r*   r+   get_modified_time  s   
z$GoogleCloudStorage.get_modified_timec                 C   r   )z
        Return the creation time (as a datetime) of the file specified by name.
        The datetime will be timezone-aware if USE_TZ=True.
        r   )ry   r   r   time_createdr   r   r   )r'   r   r$   createdr*   r*   r+   get_created_time!  s   
z#GoogleCloudStorage.get_created_timeNc           
      C   s   |  t|}| j|}| |}|d| jdkp| j }| js'|r'|j	S |r5dj
| jt|dddS | j| jdd}|p@i }| D ]\}}	|	rS||vrS|	||< qE|jd
i |S )z
        Return public URL or a signed URL for the Blob.

        The existnce of blobs are not verified for public URLs, it makes the code too
        slow.
        rG   
publicReadz {storage_base_url}/{quoted_name}s   /~)safe)storage_base_urlquoted_namev4)bucket_bound_hostnamerp   versionNr*   )ry   r   r!   r$   rK   rM   rN   ro   rm   
public_urlr   r   rp   r   generate_signed_url)
r'   r   
parametersr$   rP   no_signed_urldefault_paramsparamskeyr<   r*   r*   r+   url+  s.   


zGoogleCloudStorage.urlc                    s&   t |}| jrt||S t ||S r-   )r   rr   r   r@   get_available_name)r'   r   
max_lengthrC   r*   r+   r   O  s   
z%GoogleCloudStorage.get_available_name)rz   r-   )rQ   rR   rS   r,   rt   rT   rv   r!   ry   r}   r   r   rK   r   r   r   r   r.   r   r   r   r   rU   r*   r*   rC   r+   rV   k   s*    


"	

$rV   ))r5   r   r   datetimer   tempfiler   django.core.exceptionsr   r   django.core.files.baser   django.utilsr   django.utils.deconstructr   storages.baser	   storages.compressr
   storages.utilsr   r   r   r   r   r   google.cloud.exceptionsr   google.cloud.storager   r   google.cloud.storage.blobr   google.cloud.storage.retryr   ImportErrorr   r   r   rV   r*   r*   r*   r+   <module>   sD    D