o
    {l~i8                     @   s8  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 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 eG dd deZdd Z dd Z!dZ"eG dd deZ#dS )    N)datetime)	timedelta)SpooledTemporaryFile)ResourceNotFoundError)parse_connection_string)
BlobClient)BlobSasPermissions)BlobServiceClient)ContentSettings)generate_blob_sas)SuspiciousOperation)File)timezone)deconstructible)BaseStorage)
clean_name)get_available_overwrite_name)	safe_joinsetting)to_bytesc                       sR   e Zd Zdd Zdd Zdd ZeeeZ fddZ fd	d
Z	dd Z
  ZS )AzureStorageFilec                 C   s.   || _ || _|| _d| _d | _||| _d S )NF)name_mode_storage	_is_dirty_file_get_valid_path_path)selfr   modestorage r"   f/var/www/newdalilibackend/backend/venv/lib/python3.10/site-packages/storages/backends/azure_storage.py__init__   s   zAzureStorageFile.__init__c                 C   s~   | j d ur| j S t| jjdtdd d}d| jv sd| jv r/| jjj| j| jj	d}|
| d| jv r9|d || _ | j S )Nz.AzureStorageFileFILE_UPLOAD_TEMP_DIR)max_sizesuffixdirratimeoutr   )r   r   r   max_memory_sizer   r   clientdownload_blobr   r,   readintoseek)r   filedownload_streamr"   r"   r#   	_get_file$   s    




zAzureStorageFile._get_filec                 C   s
   || _ d S N)r   )r   valuer"   r"   r#   	_set_file9   s   
zAzureStorageFile._set_filec                    s.   d| j vrd| j vrtdt j|i |S )Nr)   r*   z!File was not opened in read mode.)r   AttributeErrorsuperread)r   argskwargs	__class__r"   r#   r:   >   s   zAzureStorageFile.readc                    s<   d| j vrd| j vrd| j vrtdd| _t t|S )Nw+r*   z"File was not opened in write mode.T)r   r8   r   r9   writer   )r   contentr=   r"   r#   rA   C   s   zAzureStorageFile.writec                 C   sL   | j d u rd S | jr| j d | j| j| j  d| _| j   d | _ d S )Nr   F)r   r   r1   r   _saver   closer   r"   r"   r#   rD   I   s   


zAzureStorageFile.close)__name__
__module____qualname__r$   r4   r7   propertyr2   r:   rA   rD   __classcell__r"   r"   r=   r#   r      s    
r   c                 C   s<   z| j jW S  ty   Y nw z| jW S  ty   Y d S w r5   )r2   content_typer8   )rB   r"   r"   r#   _content_typeT   s   
rL   c                 C   sL   |  d} t| tkrtdt t| std| ddkr$td| S )Nz./zFile name max len is %dz7File name must contain one or more printable characters/   z0File name must not contain more than 256 slashes)striplen_AZURE_NAME_MAX_LEN
ValueErrorcount)sr"   r"   r#   r   `   s   
r   i   c                       s  e Zd Z fddZdd Zdd Zedd Zed	d
 Zedd Z	edd Z
dd Zedd Zdd Zdd Zd6ddZef fdd	Zdd Zdd Zd d! Zd"d# Zd$d% Zd7d'd(Zd8d)d*Zd+d, Zd-d. Zd9d0d1Zd9d2d3Zd4d5 Z  ZS ):AzureStoragec                    s   t  jdi | d | _d | _d | _d | _d | _t | _	| j
rG| jr&| jsIt| j
dd}| js9d|v r9|d | _| jsKd|v rM|d | _d S d S d S d S d S )NT)case_sensitive_keysAccountName
AccountKeyr"   )r9   r$   _service_client_custom_service_client_client_custom_client_user_delegation_keyr   utcnow_user_delegation_key_expiryconnection_stringaccount_nameaccount_keyr   )r   settingsparsedr=   r"   r#   r$   v   s"   

zAzureStorage.__init__c                 C   s   i dt ddt ddt di dt dd	t d
ddt dddt dddt dddt ddt dddt dddddt d d!t d"d#t d$d%d&t d'd(t d)t d*t d+d d,S )-Nra   AZURE_ACCOUNT_NAMErb   AZURE_ACCOUNT_KEYobject_parametersAZURE_OBJECT_PARAMETERSazure_containerAZURE_CONTAINER	azure_ssl	AZURE_SSLTupload_max_connAZURE_UPLOAD_MAX_CONN   r,   AZURE_CONNECTION_TIMEOUT_SECS   r-   AZURE_BLOB_MAX_MEMORY_SIZEi    expiration_secsAZURE_URL_EXPIRATION_SECSoverwrite_filesAZURE_OVERWRITE_FILESFlocationAZURE_LOCATION default_content_typezapplication/octet-streamcache_controlAZURE_CACHE_CONTROL	sas_tokenAZURE_SAS_TOKENendpoint_suffixAZURE_ENDPOINT_SUFFIXzcore.windows.netcustom_domainAZURE_CUSTOM_DOMAINr`   AZURE_CONNECTION_STRINGAZURE_TOKEN_CREDENTIALAZURE_API_VERSION)token_credentialapi_versionr   rE   r"   r"   r#   get_default_settings   sL   




	



z!AzureStorage.get_default_settingsc                 C   s   | j d urt| j S | jr|r| jnd| j| j}d| j|}d }| jr/| j| jd}n| j	r6| j	}n| j
r<| j
}i }| jrF| j|d< t|fd|i|S )Nz
{}.blob.{}z{}://{})ra   rb   r   
credential)r`   r	   from_connection_stringr   formatra   r   azure_protocolrb   r}   r   r   )r   use_custom_domainaccount_domainaccount_urlr   optionsr"   r"   r#   _get_service_client   s2   

z AzureStorage._get_service_clientc                 C      | j d u r| jdd| _ | j S )NFr   )rY   r   rE   r"   r"   r#   service_client   s   
zAzureStorage.service_clientc                 C   r   )NTr   )rZ   r   rE   r"   r"   r#   custom_service_client   s
   
z"AzureStorage.custom_service_clientc                 C       | j d u r| j| j| _ | j S r5   )r[   r   get_container_clientri   rE   r"   r"   r#   r.      
   
zAzureStorage.clientc                 C   r   r5   )r\   r   r   ri   rE   r"   r"   r#   custom_client   r   zAzureStorage.custom_clientc                 C   sV   | j d u rd S | jd u s|| jkr(t }|tdd }| jj||d| _|| _| jS )N   )days)key_start_timekey_expiry_time)r   r]   r_   r   r^   r   r   get_user_delegation_key)r   expirynowr   r"   r"   r#   r      s   


z$AzureStorage.get_user_delegation_keyc                 C   s   | j rdS dS )Nhttpshttp)rk   rE   r"   r"   r#   r      s   zAzureStorage.azure_protocolc                 C   s*   zt | j|W S  ty   td| w )Nz Attempted access to '%s' denied.)r   rw   rR   r   r   r   r"   r"   r#   _normalize_name   s
   zAzureStorage._normalize_namec                 C   s   t | t|S r5   )r   r   r   r   r"   r"   r#   r         zAzureStorage._get_valid_pathrbc                 C   s   t ||| S r5   )r   )r   r   r    r"   r"   r#   _open  s   zAzureStorage._openc                    s&   t |}| jrt||S t ||S )z
        Returns a filename that's free on the target storage system, and
        available for new content to be written to.
        )r   ru   r   r9   get_available_name)r   r   
max_lengthr=   r"   r#   r     s   
zAzureStorage.get_available_namec                 C   s   | j | |}| S r5   )r.   get_blob_clientr   exists)r   r   blob_clientr"   r"   r#   r     s   zAzureStorage.existsc                 C   s4   z| j j| || jd W d S  ty   Y d S w Nr+   )r.   delete_blobr   r,   r   r   r"   r"   r#   delete  s
   zAzureStorage.deletec                 C   s&   | j | |}|j| jd}|jS r   )r.   r   r   get_blob_propertiesr,   size)r   r   r   
propertiesr"   r"   r#   r     s   zAzureStorage.sizec                 C   sd   t |}| |}| ||}t|tr|j}|d | jj||t	di || j
| j| jd |S )Nr   )content_settingsmax_concurrencyr,   	overwriter"   )r   r    _get_content_settings_parameters
isinstancer   r2   r1   r.   upload_blobr
   rm   r,   ru   )r   r   rB   cleaned_nameparamsr"   r"   r#   rC     s   


zAzureStorage._savec                 C   s   t  t|d S )N)seconds)r   r^   r   )r   expirer"   r"   r#   
_expire_at1  r   zAzureStorage._expire_atNc           
      C   s   |  |}|pi }|d u r| j}d }|r5| |}| |}t| j| j|f| j|tdd|d|}|}| j	
|j}	tj|	|djS )NT)r:   )rb   user_delegation_key
permissionr   )r   )r   rs   r   r   r   ra   ri   rb   r   r   r   urlr   from_blob_url)
r   r   r   
parametersr   r   r   r   r}   container_blob_urlr"   r"   r#   r   5  s.   



zAzureStorage.urlc                 C   sR   i }t |\}}t|p|p| j}| j|d< ||d< ||d< || | |S )Nr{   rK   content_encoding)	mimetypes
guess_typerL   rz   r{   updateget_object_parameters)r   r   rB   r   guessed_typer   rK   r"   r"   r#   r   O  s   
z-AzureStorage._get_content_settings_parametersc                 C   s
   | j  S )z
        Returns a dictionary that is passed to content settings. Override this
        method to adjust this on a per-object basis to set e.g ContentDisposition.

        By default, returns the value of AZURE_OBJECT_PARAMETERS.
        )rg   copyr   r"   r"   r#   r   ^  s   
z"AzureStorage.get_object_parametersc                 C   sd   | j | |}|j| jd}tddst|jS t	 }t
|jr,t|j|S |j|S )z
        Returns an (aware) datetime object containing the last modified time if
        USE_TZ is True, otherwise returns a naive datetime in the local timezone.
        r+   USE_TZF)r.   r   r   r   r,   r   r   
make_naivelast_modifiedget_current_timezoneis_naive
make_aware
astimezone)r   r   r   r   tzr"   r"   r#   get_modified_timeg  s   
zAzureStorage.get_modified_timery   c                 C   s@   |r|  |}|r|ds|d7 }dd | jj|| jdD S )z!Return all files for a given pathrM   c                 S   s   g | ]}|j qS r"   )r   ).0blobr"   r"   r#   
<listcomp>  s    z)AzureStorage.list_all.<locals>.<listcomp>)name_starts_withr,   )r   endswithr.   
list_blobsr,   )r   pathr"   r"   r#   list_ally  s   
zAzureStorage.list_allc                 C   s`   g }t  }| |D ]}|t|d }d|v r$||ddd  q
|| q
t||fS )z
        Return directories and files for a given path.
        Leave the path empty to list the root.
        Order of dirs and files is undefined.
        NrM      r   )setr   rP   addsplitappendlist)r   r   filesdirsr   nr"   r"   r#   listdir  s   zAzureStorage.listdirc                 C   s0   t t| d td }| js|td8 }|S )Nfoo_1234567)rQ   rP   r   ru   )r   max_lenr"   r"   r#   get_name_max_len  s   zAzureStorage.get_name_max_len)r   )NNr5   )ry   )rF   rG   rH   r$   r   r   rI   r   r   r.   r   r   r   r   r   r   rQ   r   r   r   r   rC   r   r   r   r   r   r   r   r   rJ   r"   r"   r=   r#   rU   t   s>    








	

rU   )$r   r   r   tempfiler   azure.core.exceptionsr   azure.core.utilsr   azure.storage.blobr   r   r	   r
   r   django.core.exceptionsr   django.core.files.baser   django.utilsr   django.utils.deconstructr   storages.baser   storages.utilsr   r   r   r   r   r   rL   r   rQ   rU   r"   r"   r"   r#   <module>   s8    9