o
    ˷eP                     @   s  d Z ddlZddlm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Z	 dZ	 dZ	 dZdZdZdd Zdd Zdd ZG dd deZdd Zd/ddZdd Zd d! Z d"d# Z!d$d% Z"d0d&d'Z#d0d(d)Z$d*d+ Z%	,	d1d-d.Z&dS )2zVHelper functions for Cloud Storage utility classes.

These are *not* part of the API.
    N)md5)urlsplit)uuid4)resumable_media)environment_vars)_DEFAULT_TIMEOUT)DEFAULT_RETRY))DEFAULT_RETRY_IF_METAGENERATION_SPECIFIEDSTORAGE_EMULATOR_HOSTzhttps://storage.googleapis.comzstorage.googleapis.com))if_etag_matchzIf-Match)if_etag_not_matchzIf-None-Match))if_generation_matchifGenerationMatch)if_generation_not_matchifGenerationNotMatch)if_metageneration_matchifMetagenerationMatch)if_metageneration_not_matchifMetagenerationNotMatch)if_source_generation_matchifSourceGenerationMatch)if_source_generation_not_matchifSourceGenerationNotMatch)if_source_metageneration_matchifSourceMetagenerationMatch)"if_source_metageneration_not_matchifSourceMetagenerationNotMatchz`num_retries` has been deprecated and will be removed in a future release. Use the `retry` argument with a Retry or ConditionalRetryPolicy object, or None, instead.c                   C   s   t jttS N)osenvirongetSTORAGE_EMULATOR_ENV_VAR_DEFAULT_STORAGE_HOST r#   r#   T/var/www/ideatree/venv/lib/python3.10/site-packages/google/cloud/storage/_helpers.py_get_storage_hostC      r%   c                   C   s   t tjt tjS r   )r   getenvr   PROJECTLEGACY_PROJECTr#   r#   r#   r$   _get_environ_projectG   s   
r*   c                 C   s4   | du rdS t | d  | d  gstd| S )zPre-flight ``Bucket`` name validation.

    :type name: str or :data:`NoneType`
    :param name: Proposed bucket name.

    :rtype: str or :data:`NoneType`
    :returns: ``name`` if valid.
    Nr   z8Bucket names must start and end with a number or letter.)allisalnum
ValueError)namer#   r#   r$   _validate_nameN   s
   	r0   c                
   @   s   e Zd ZdZdddZedd Zedd Zed	d
 Zdd Z	dd Z
edd Zddddddddeef
ddZdd Zdd ZdddddeefddZdddddeefddZdS )_PropertyMixina1  Abstract mixin for cloud storage classes with associated properties.

    Non-abstract subclasses should implement:
      - path
      - client
      - user_project

    :type name: str
    :param name: The name of the object. Bucket names must start and end with a
                 number or letter.
    Nc                 C   s   || _ i | _t | _d S r   )r/   _propertiesset_changes)selfr/   r#   r#   r$   __init__m   s   z_PropertyMixin.__init__c                 C      t )z$Abstract getter for the object path.NotImplementedErrorr5   r#   r#   r$   pathr      z_PropertyMixin.pathc                 C   r7   )z&Abstract getter for the object client.r8   r:   r#   r#   r$   clientw   r<   z_PropertyMixin.clientc                 C   r7   )z,Abstract getter for the object user_project.r8   r:   r#   r#   r$   user_project|   r<   z_PropertyMixin.user_projectc                 C   s   |du r| j }|S )a  Check client or verify over-ride.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use.  If not passed, falls back to the
                       ``client`` stored on the current object.

        :rtype: :class:`google.cloud.storage.client.Client`
        :returns: The client passed in or the currently bound client.
        N)r=   )r5   r=   r#   r#   r$   _require_client   s   z_PropertyMixin._require_clientc                 C   s   i S )a@  Return any encryption headers needed to fetch the object.

        .. note::
           Defined here because :meth:`reload` calls it, but this method is
           really only relevant for :class:`~google.cloud.storage.blob.Blob`.

        :rtype: dict
        :returns: a mapping of encryption-related headers.
        r#   r:   r#   r#   r$   _encryption_headers   s   
z"_PropertyMixin._encryption_headersc                 C   s   i }| j dur| j |d< |S )zDefault query parameters.NuserProject)r>   )r5   paramsr#   r#   r$   _query_params   s   

z_PropertyMixin._query_paramsnoAclc                 C   sf   |  |}| j}||d< t|||||d |  }t|||d |j| j|||	|
| d}| | dS )a<  Reload properties from Cloud Storage.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

        :type projection: str
        :param projection: (Optional) If used, must be 'full' or 'noAcl'.
                           Defaults to ``'noAcl'``. Specifies the set of
                           properties to return.

        :type if_etag_match: Union[str, Set[str]]
        :param if_etag_match: (Optional) See :ref:`using-if-etag-match`

        :type if_etag_not_match: Union[str, Set[str]])
        :param if_etag_not_match: (Optional) See :ref:`using-if-etag-not-match`

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`

        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        
projectionr   r   r   r   )r   r   )query_paramsheaderstimeoutretry_target_objectN)r?   rC    _add_generation_match_parametersr@   _add_etag_match_headers_get_resourcer;   _set_properties)r5   r=   rE   r   r   r   r   r   r   rI   rJ   rG   rH   api_responser#   r#   r$   reload   s.   
:z_PropertyMixin.reloadc                 C   s   | j | || j|< dS )a  Update field of this object's properties.

        This method will only update the field provided and will not
        touch the other fields.

        It **will not** reload the properties from the server. The behavior is
        local only and syncing occurs via :meth:`patch`.

        :type name: str
        :param name: The field name to update.

        :type value: object
        :param value: The value being updated.
        N)r4   addr2   )r5   r/   valuer#   r#   r$   _patch_property   s   z_PropertyMixin._patch_propertyc                 C   s   || _ t | _dS )zSet the properties for the current object.

        :type value: dict or :class:`google.cloud.storage.batch._FutureDict`
        :param value: The properties to be set.
        N)r2   r3   r4   r5   rS   r#   r#   r$   rO   
  s   z_PropertyMixin._set_propertiesc                    sd     |} j}d|d< t|||||d  fdd jD }	|j j|	| ||d}
 |
 dS )a  Sends all changed properties in a PATCH request.

        Updates the ``_properties`` with the response from the backend.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`

        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        fullrE   rF   c                    s   i | ]}| j | qS r#   )r2   ).0keyr:   r#   r$   
<dictcomp>N      z(_PropertyMixin.patch.<locals>.<dictcomp>)rG   rK   rI   rJ   N)r?   rC   rL   r4   _patch_resourcer;   rO   )r5   r=   r   r   r   r   rI   rJ   rG   update_propertiesrP   r#   r:   r$   patch  s(   
.z_PropertyMixin.patchc           
      C   sR   |  |}| j}d|d< t|||||d |j| j| j|||| d}	| |	 dS )a  Sends all properties in a PUT request.

        Updates the ``_properties`` with the response from the backend.

        If :attr:`user_project` is set, bills the API request to that project.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: the client to use. If not passed, falls back to the
                       ``client`` stored on the current object.

        :type if_generation_match: long
        :param if_generation_match:
            (Optional) See :ref:`using-if-generation-match`

        :type if_generation_not_match: long
        :param if_generation_not_match:
            (Optional) See :ref:`using-if-generation-not-match`

        :type if_metageneration_match: long
        :param if_metageneration_match:
            (Optional) See :ref:`using-if-metageneration-match`

        :type if_metageneration_not_match: long
        :param if_metageneration_not_match:
            (Optional) See :ref:`using-if-metageneration-not-match`

        :type timeout: float or tuple
        :param timeout:
            (Optional) The amount of time, in seconds, to wait
            for the server response.  See: :ref:`configuring_timeouts`

        :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
        :param retry:
            (Optional) How to retry the RPC. See: :ref:`configuring_retries`
        rV   rE   rF   )rG   rI   rJ   rK   N)r?   rC   rL   _put_resourcer;   r2   rO   )
r5   r=   r   r   r   r   rI   rJ   rG   rP   r#   r#   r$   update[  s&   
.z_PropertyMixin.updater   )__name__
__module____qualname____doc__r6   propertyr;   r=   r>   r?   r@   rC   r   r   rQ   rT   rO   r	   r]   r_   r#   r#   r#   r$   r1   `   sT    




	
T
Ir1   c                    s"    fdd} fdd}t ||S )zHCreate a property descriptor around the :class:`_PropertyMixin` helpers.c                    s   | j  S )zScalar property getter.)r2   r    r:   	fieldnamer#   r$   _getter  s   z!_scalar_property.<locals>._getterc                    s   |   | dS )zScalar property setter.N)rT   rU   re   r#   r$   _setter  s   z!_scalar_property.<locals>._setter)rd   )rf   rg   rh   r#   re   r$   _scalar_property  s   
ri       c                 C   s>   |  |}t|dkr|| |  |}t|dksdS dS )a  Read blocks from a buffer and update a hash with them.

    :type buffer_object: bytes buffer
    :param buffer_object: Buffer containing bytes used to update a hash object.

    :type hash_obj: object that implements update
    :param hash_obj: A hash object (MD5 or CRC32-C).

    :type digest_block_size: int
    :param digest_block_size: The block size to write to the hash.
                              Defaults to 8192.
    r   N)readlenr_   )buffer_objecthash_objdigest_block_sizeblockr#   r#   r$   _write_buffer_to_hash  s
   


rq   c                 C   s"   t  }t| | | }t|S )a  Get MD5 hash of bytes (as base64).

    :type buffer_object: bytes buffer
    :param buffer_object: Buffer containing bytes used to compute an MD5
                          hash (as base64).

    :rtype: str
    :returns: A base64 encoded digest of the MD5 hash.
    )r   rq   digestbase64	b64encode)rm   rn   digest_bytesr#   r#   r$   _base64_md5hash  s   


rv   c                 K   sB   t D ]\}}||}|durt|tr|g}d|| |< qdS )zAdd generation match parameters into the given parameters list.

    :type headers: dict
    :param headers: Headers dict.

    :type match_parameters: dict
    :param match_parameters: if*etag*match parameters to add.
    N, )_ETAG_MATCH_PARAMETERSr    
isinstancestrjoin)rH   match_parameterssnakecase_nameheader_namerS   r#   r#   r$   rM     s   	

rM   c                 K   sZ   t D ](\}}||}|dur*t| tr| ||f qt| tr&|| |< qtdqdS )ab  Add generation match parameters into the given parameters list.

    :type parameters: list or dict
    :param parameters: Parameters list or dict.

    :type match_parameters: dict
    :param match_parameters: if*generation*match parameters to add.

    :raises: :exc:`ValueError` if ``parameters`` is not a ``list()``
             or a ``dict()``.
    Nz5`parameters` argument should be a dict() or a list().)_GENERATION_MATCH_PARAMETERSr    ry   listappenddictr.   )
parametersr|   r}   camelcase_namerS   r#   r#   r$   rL     s   



rL   c                  K   sb   t dd |  D dkr/dd |  D }d|dd }|d }d	| d
| }t|dS )zRaise ``ValueError`` exception if more than one parameter was set.

    :type error: :exc:`ValueError`
    :param error: Description of which fields were set

    :raises: :class:`~ValueError` containing the fields that were set
    c                 s   s    | ]}|d uV  qd S r   r#   )rW   argr#   r#   r$   	<genexpr>	  s    z._raise_if_more_than_one_set.<locals>.<genexpr>   c                 S   s   g | ]}d | d qS )'r#   )rW   r/   r#   r#   r$   
<listcomp>
  rZ   z/_raise_if_more_than_one_set.<locals>.<listcomp>rw   Nr+   zPass at most one of z and )sumvalueskeysr{   r.   )kwargsescaped_keyskeys_but_lastlast_keymsgr#   r#   r$   _raise_if_more_than_one_set  s   r   c                 C   s(   t | }|jr|jr| S | d|  dS )a!  Helper to build bucket bound hostname URL.

    :type host: str
    :param host: Host name.

    :type scheme: str
    :param scheme: (Optional) Web scheme. If passed, use it
                   as a scheme in the result URL.

    :rtype: str
    :returns: A bucket bound hostname URL.
    z:///)r   schemenetloc)hostr   	url_partsr#   r#   r$   _bucket_bound_hostname_url  s   r   c                 C   sZ   | dur|durt d| durtj| j| j| j| jdS |dur'tj|dS tjddS )a~  Convert google.api.core.Retry to google.resumable_media.RetryStrategy.

    Custom predicates are not translated.

    :type retry: google.api_core.Retry
    :param retry: (Optional) The google.api_core.Retry object to translate.

    :type num_retries: int
    :param num_retries: (Optional) The number of retries desired. This is
        supported for backwards compatibility and is mutually exclusive with
        `retry`.

    :rtype: google.resumable_media.RetryStrategy
    :returns: A RetryStrategy with all applicable attributes copied from input,
              or a RetryStrategy with max_retries set to 0 if None was input.
    Nz6num_retries and retry arguments are mutually exclusive)	max_sleepmax_cumulative_retryinitial_delay
multiplier)max_retriesr   )r.   r   RetryStrategy_maximum	_deadline_initial_multiplier)rJ   num_retriesr#   r#   r$   (_api_core_retry_to_resumable_media_retry(  s   r   c                   C   s   dt t  S )Nzgccl-invocation-id/)rz   r   r#   r#   r#   r$   _get_invocation_idJ  r&   r   application/json; charset=UTF-8c                 C   s"   dd| |  dt   ||p|dS )zGet the headers for a request.

    Args:
        user_agent (str): The user-agent for requests.
    Returns:
        Dict: The headers to be used for the request.
    zapplication/jsonzgzip, deflate )AcceptzAccept-Encodingz
User-AgentzX-Goog-API-Clientzcontent-typezx-upload-content-type)r   )
user_agentcontent_typex_upload_content_typer#   r#   r$   _get_default_headersN  s   r   )rj   r   )r   N)'rc   rs   hashlibr   r   urllib.parser   uuidr   googler   google.authr   google.cloud.storage.constantsr   google.cloud.storage.retryr   r	   r!   r"   _BASE_STORAGE_URIrx   r   _NUM_RETRIES_MESSAGEr%   r*   r0   objectr1   ri   rq   rv   rM   rL   r   r   r   r   r   r#   r#   r#   r$   <module>   sN     B


"