o
    h*                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ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mZmZmZmZ zd dlmZ d dlmZmZ d dlmZ W n e yi   edw dZ!G dd de
Z"eG dd deZ#dS )    N)	timedelta)SpooledTemporaryFile)ImproperlyConfiguredSuspiciousOperation)File)timezone)deconstructible)force_bytes)BaseStorage)check_location
clean_nameget_available_overwrite_name	safe_joinsetting)NotFound)BlobClient)_quotezfCould not load Google Cloud Storage bindings.
See https://github.com/GoogleCloudPlatform/gcloud-python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   sd   || _ t|d | _|| _|| _|j|| _| js*d|v r*t	| j |j|j
d| _d | _d| _d S )Nr   w)
chunk_sizeF)name	mimetypes
guess_type	mime_type_mode_storagebucketget_blobblobr   blob_chunk_size_file	_is_dirty)selfr   modeZstorage r&   `/var/www/html/magazine_api/magazine_env/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*   ,   s   zGoogleCloudFile.sizec                 C   sR   | j d u r&t| jjdtdd| _ d| jv r&d| _| j| j  | j 	d | j S )Nz.GSStorageFileZFILE_UPLOAD_TEMP_DIR)max_sizesuffixdirrFr   )
r"   r   r   max_memory_sizer   r   r#   r    Zdownload_to_fileseekr+   r&   r&   r'   	_get_file0   s   

zGoogleCloudFile._get_filec                 C   s
   || _ d S r)   )r"   )r$   valuer&   r&   r'   	_set_file=   s   
zGoogleCloudFile._set_fileNc                    s*   d| j vr	td|d u rd}t |S )Nr/   z!File was not opened in read mode.)r   AttributeErrorsuperread)r$   Z	num_bytes	__class__r&   r'   r8   B   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   r6   r#   r7   writer	   )r$   contentr9   r&   r'   r;   K   s   
zGoogleCloudFile.writec                 C   sZ   | j d ur+| jr!| j| j}| jj| jd| j|	d| jj
d | j   d | _ d S d S )NTacl)rewindr   predefined_acl)r"   r#   r   get_object_parametersr   r    upload_from_filefiler   getdefault_aclclose)r$   blob_paramsr&   r&   r'   rE   Q   s   



zGoogleCloudFile.closer)   )__name__
__module____qualname__r(   propertyr*   r2   r4   rB   r8   r;   rE   __classcell__r&   r&   r9   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# Zd( fd%d&	Z  ZS ))GoogleCloudStoragec                    s*   t  jdi | t|  d | _d | _d S )Nr&   )r7   r(   r   _bucket_client)r$   settingsr9   r&   r'   r(   ^   s   
zGoogleCloudStorage.__init__c                 C   sh   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t di t ddt ddS )NZGS_PROJECT_IDZGS_CREDENTIALSZGS_BUCKET_NAMEZGS_CUSTOM_ENDPOINTZGS_LOCATION ZGS_DEFAULT_ACLZGS_QUERYSTRING_AUTHTZGS_EXPIRATIONiQ )secondsZGS_FILE_OVERWRITEZGS_CACHE_CONTROLZGS_OBJECT_PARAMETERSZGS_MAX_MEMORY_SIZEr   ZGS_BLOB_CHUNK_SIZE)
project_idcredentialsbucket_namecustom_endpointlocationrD   querystring_auth
expirationfile_overwritecache_controlobject_parametersr0   r!   )r   r   r+   r&   r&   r'   get_default_settingsf   s   z'GoogleCloudStorage.get_default_settingsc                 C   s"   | j d u rt| j| jd| _ | j S )N)projectrS   )rN   r   rR   rS   r+   r&   r&   r'   clientz   s   
zGoogleCloudStorage.clientc                 C   s    | j d u r| j| j| _ | j S r)   )rM   r^   r   rT   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   rV   
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)ra   r   r   r    FileNotFoundError)r$   r   r%   file_objectr&   r&   r'   _open   s
   zGoogleCloudStorage._openc           	      C   s   t |}| |}||_t|d| }i }| |}|d| j|d< t|vr+|j|t< |	 D ]\}}t
|j|| q/|jj|fd|jd| |S )Nrwr=   r?   T)r>   r*   )r   ra   r   r   r@   poprD   CONTENT_TYPEr   itemssetattrr    rA   r*   )	r$   r   r<   Zcleaned_namerd   Zupload_paramsrF   propvalr&   r&   r'   _save   s   


zGoogleCloudStorage._savec                 C   s2   | j  }d|vr| jrtdt | j|d< |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.
        rZ   zThe GS_CACHE_CONTROL setting is deprecated. Use GS_OBJECT_PARAMETERS to set any writable blob property or override GoogleCloudStorage.get_object_parameters to vary the parameters per object.)r[   copyrZ   warningswarnDeprecationWarning)r$   r   r[   r&   r&   r'   r@      s   

z(GoogleCloudStorage.get_object_parametersc                 C   s6   |  t|}z	| j| W d S  ty   Y d S w r)   )ra   r   r   Zdelete_blobr   r`   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)r^   Z
get_bucketr   r   ra   r   boolr   r`   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	delimiterr5   )
ra   r   endswithr   Z
list_blobslistprefixesr   splitappend)
r$   r   iteratorZblobsr{   filesdirsr    partsZ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)   )ra   r   r   r*   r   r&   r&   r'   r*      s   
zGoogleCloudStorage.sizec                 C   s$   |  t|}| |}t|jS r)   )ra   r   r   r   
make_naiveupdatedr   r&   r&   r'   modified_time   s   
z GoogleCloudStorage.modified_timec                 C   4   |  t|}| |}|j}tdr|S t|S )NUSE_TZ)ra   r   r   r   r   r   r   )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   )ra   r   r   Ztime_createdr   r   r   )r$   r   r    createdr&   r&   r'   get_created_time  s   
z#GoogleCloudStorage.get_created_timec                 C   s   |  t|}| j|}| |}|d| jdkp| j }| js'|r'|j	S |r5dj
| jt|dddS | js@|j| jddS |j| j| jdd	S )
z
        Return public url or a signed url for the Blob.
        This DOES NOT check for existance of Blob - that makes codes too slow
        for many use cases.
        r=   Z
publicReadz {storage_base_url}/{quoted_name}s   /~)safe)Zstorage_base_urlZquoted_nameZv4)rX   version)Zbucket_bound_hostnamerX   r   )ra   r   r   r    r@   rC   rD   rW   rU   Z
public_urlr   r   Zgenerate_signed_urlrX   )r$   r   r    rF   Zno_signed_urlr&   r&   r'   url  s*   


zGoogleCloudStorage.urlNc                    s&   t |}| jrt||S t ||S r)   )r   rY   r   r7   get_available_name)r$   r   
max_lengthr9   r&   r'   r   ,  s   
z%GoogleCloudStorage.get_available_name)rb   r)   )rG   rH   rI   r(   r\   rJ   r^   r   ra   re   rm   r@   rr   rt   r   r   r*   r   r   r   r   r   rK   r&   r&   r9   r'   rL   \   s*    


	
rL   )$r   ro   datetimer   tempfiler   Zdjango.core.exceptionsr   r   Zdjango.core.files.baser   Zdjango.utilsr   Zdjango.utils.deconstructr   Zdjango.utils.encodingr	   Zstorages.baser
   Zstorages.utilsr   r   r   r   r   Zgoogle.cloud.exceptionsr   Zgoogle.cloud.storager   r   Zgoogle.cloud.storage.blobr   ImportErrorrh   r   rL   r&   r&   r&   r'   <module>   s,    >