U
    #FZh9                     @   s<  d Z ddlmZ ddlZddlZ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	Zd
ZdZdZdZdZdZdZeeZdd ZefddZefddZd4d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(d0d1 Z)G d2d3 d3e*Z+dS )5z4Shared utilities used by both downloads and uploads.    )absolute_importN)parse_qs)	urlencode)urlsplit)
urlunsplit)commonrangezcontent-rangezcontent-encodingzCurrently using crcmod in pure python form. This is a slow implementation. Python 3 has a faster implementation, `google-crc32c`, which will be used if it is installed.zx-goog-generationzx-goog-hashzx-goog-stored-content-encodingzNo {checksum_type} checksum was returned from the service while downloading {}
(which happens for composite objects), so client-side content integrity
checking is not being performed.c                   C   s   dS )zSimple default callback.N r	   r	   r	   f/home/aprabhat/apps/x.techxrdev.in/venv/lib/python3.8/site-packages/google/resumable_media/_helpers.py
do_nothing5   s    r   c                 C   s,   || }||kr$|  t | d||| S )a  Checks that a specific header is in a headers dictionary.

    Args:
        response (object): An HTTP response object, expected to have a
            ``headers`` attribute that is a ``Mapping[str, str]``.
        name (str): The name of a required header.
        get_headers (Callable[Any, Mapping[str, str]]): Helper to get headers
            from an HTTP response.
        callback (Optional[Callable]): A callback that takes no arguments,
            to be executed when an exception is being raised.

    Returns:
        str: The desired header.

    Raises:
        ~google.resumable_media.common.InvalidResponse: If the header
            is missing.
    z$Response headers must contain header)r   InvalidResponse)responsenameget_headerscallbackheadersr	   r	   r
   header_required9   s      r   c                 C   s:   || }||kr6|t jkr |  t j| d|df| |S )a`  Require a response has a status code among a list.

    Args:
        response (object): The HTTP response object.
        status_codes (tuple): The acceptable status codes.
        get_status_code (Callable[Any, int]): Helper to get a status code
            from a response.
        callback (Optional[Callable]): A callback that takes no arguments,
            to be executed when an exception is being raised.

    Returns:
        int: The status code.

    Raises:
        ~google.resumable_media.common.InvalidResponse: If the status code
            is not one of the values in ``status_codes``.
    zRequest failed with status codezExpected one of)r   Z	RETRYABLEr   )r   status_codesZget_status_coder   status_coder	   r	   r
   require_status_codeV   s    
r          @c                 C   s0   ||  }||kr|}t dd}||d|  fS )a  Calculate the amount of time to wait before a retry attempt.

    Wait time grows exponentially with the number of attempts, until
    ``max_sleep``.

    A random amount of jitter (between 0 and 1 seconds) is added to spread out
    retry attempts from different clients.

    Args:
        base_wait (float): The "base" wait time (i.e. without any jitter)
            that will be multiplied until it reaches the maximum sleep.
        max_sleep (float): Maximum value that a sleep time is allowed to be.
        multiplier (float): Multiplier to apply to the base wait.

    Returns:
        Tuple[float, float]: The new base wait time as well as the wait time
        to be applied (with a random amount of jitter between 0 and 1 seconds
        added).
    r   i  gMbP?)randomrandint)Z	base_waitZ	max_sleepZ
multiplierZnew_base_waitZ	jitter_msr	   r	   r
   calculate_retry_waitv   s
    r   c                  C   sj   zddl } |  }W nP tk
rd   zddl}|jd}t  W n tk
r^   tdY nX Y nX |S )zGet crc32c object
    Attempt to use the Google-CRC32c package. If it isn't available, try
    to use CRCMod. CRCMod might be using a 'slow' varietal. If so, warn...
    r   Nzcrc-32cz3Failed to import either `google-crc32c` or `crcmod`)google_crc32cZChecksumImportErrorcrcmodZ
predefinedZCrc_is_fast_crcmod)r   Zcrc_objr   r	   r	   r
   _get_crc32c_object   s    
r   c                  C   s:   t dt t dgd} t| dd}|s6tjttdd |S )Nzcrcmod.crcmodZ_usingExtensionr   F   )
stacklevel)
__import__globalslocalsgetattrwarningswarn_SLOW_CRC32C_WARNINGRuntimeWarning)Znested_crcmodZfast_crcr	   r	   r
   r      s    r   c                 C   s   | dkrdS | S d S )Nmd5Zmd5Hashr	   checksum_typer	   r	   r
   _get_metadata_key   s    r,   c                 C   s   t | }|dS )zConvert a checksum object into a digest encoded for an HTTP header.

    Args:
        bytes: A checksum digest bytestring.

    Returns:
        str: A base64 string representation of the input.
    zutf-8)base64	b64encodedecode)Zdigest_bytestringZencoded_digestr	   r	   r
   prepare_checksum_digest   s    	
r0   c                 C   s   |dkrt dnt|dkr||| }t|t| |d}|dkrbtj|| d}t| t	 }q|dkrtt
 }qt }n
d}t	 }||fS )a  Get the expected checksum and checksum object for the download response.

    Args:
        response (~requests.Response): The HTTP response object.
        get_headers (callable: response->dict): returns response headers.
        media_url (str): The URL containing the media to be downloaded.
        checksum_type Optional(str): The checksum type to read from the headers,
            exactly as it will appear in the headers (case-sensitive). Must be
            "md5", "crc32c" or None.

    Returns:
        Tuple (Optional[str], object): The expected checksum of the response,
        if it can be detected from the ``X-Goog-Hash`` header, and the
        appropriate checksum object for the expected checksum.
    r)   crc32cN4checksum must be ``'md5'``, ``'crc32c'`` or ``None``r)   r2   checksum_labelNr*   r)   )
ValueError_parse_checksum_headerget_HASH_HEADER_MISSING_CHECKSUMformatupper_LOGGERinfo_DoNothingHashhashlibr)   r   )r   r   	media_urlr+   r   Zexpected_checksummsgZchecksum_objectr	   r	   r
   _get_expected_checksum   s,    
   

rD   c                 C   s@   |dkrt dn*|dkr8|| }t|t| |d}nd}|S )a  Get the computed checksum and checksum object from the response headers.

    Args:
        response (~requests.Response): The HTTP response object.
        get_headers (callable: response->dict): returns response headers.
        checksum_type Optional(str): The checksum type to read from the headers,
            exactly as it will appear in the headers (case-sensitive). Must be
            "md5", "crc32c" or None.

    Returns:
        Tuple (Optional[str], object): The checksum of the response,
        if it can be detected from the ``X-Goog-Hash`` header, and the
        appropriate checksum object for the expected checksum.
    r1   r3   r4   r5   N)r7   r8   r9   r:   )r   r   r+   r   Zremote_checksumr	   r	   r
   #_get_uploaded_checksum_from_headers   s    
  rE   c                 C   s   | dkrdS g }|  dD ]*}| dd\}}| |kr|| qt|dkrVdS t|dkrj|d S t|d|| |dS )aD  Parses the checksum header from an ``X-Goog-Hash`` value.

    .. _header reference: https://cloud.google.com/storage/docs/                          xml-api/reference-headers#xgooghash

    Expects ``header_value`` (if not :data:`None`) to be in one of the three
    following formats:

    * ``crc32c=n03x6A==``
    * ``md5=Ojk9c3dhfxgoKVVHYwFbHQ==``
    * ``crc32c=n03x6A==,md5=Ojk9c3dhfxgoKVVHYwFbHQ==``

    See the `header reference`_ for more information.

    Args:
        header_value (Optional[str]): The ``X-Goog-Hash`` header from
            a download response.
        response (~requests.Response): The HTTP response object.
        checksum_label (str): The label of the header value to read, as in the
            examples above. Typically "md5" or "crc32c"

    Returns:
        Optional[str]: The expected checksum of the response, if it
        can be detected from the ``X-Goog-Hash`` header; otherwise, None.

    Raises:
        ~google.resumable_media.common.InvalidResponse: If there are
            multiple checksums of the requested type in ``header_value``.
    N,=   r   z.X-Goog-Hash header had multiple ``{}`` values.)splitlstripappendlenr   r   r<   )header_valuer   r6   matchesZchecksumr   valuer	   r	   r
   r8     s"    r8   c                 C   s6   | dkrt  S | dkrt S | dkr*dS tddS )z~Respond with a checksum object for a supported type, if not None.

    Raises ValueError if checksum_type is unsupported.
    r)   r2   Nr3   )rA   r)   r   r7   r*   r	   r	   r
   _get_checksum_objectG  s    rP   c                 C   s,   || }| td}|dkr dS t|S dS )a  Parses the generation header from an ``X-Goog-Generation`` value.

    Args:
        response (~requests.Response): The HTTP response object.
        get_headers (callable: response->dict): returns response headers.

    Returns:
        Optional[long]: The object generation from the response, if it
        can be detected from the ``X-Goog-Generation`` header; otherwise, None.
    N)r9   _GENERATION_HEADERint)r   r   r   object_generationr	   r	   r
   _parse_generation_headerV  s
    rT   c                 C   sB   t | \}}}}}t|}|dd}|dkr2dS t|d S dS )zRetrieve the object generation query param specified in the media url.

    Args:
        media_url (str): The URL containing the media to be downloaded.

    Returns:
        long: The object generation from the media url if exists; otherwise, None.
    Z
generationNr   )r   r   r9   rR   )rB   _queryquery_paramsrS   r	   r	   r
   _get_generation_from_urlj  s    
rX   c           	      C   sP   t |dkr| S t| \}}}}}t|}||}t|dd}t|||||fS )a  Add query parameters to a base url.

    Args:
        media_url (str): The URL containing the media to be downloaded.
        query_params (dict): Names and values of the query parameters to add.

    Returns:
        str: URL with additional query strings appended.
    r   T)doseq)rL   r   r   r   r   )	rB   rW   schemenetlocpathrV   fragparams
new_paramsr	   r	   r
   add_query_parameters~  s    r`   c                 C   s$   || }| tdko"| tdkS )a  Returns True if the object was served decompressed. This happens when the
    "x-goog-stored-content-encoding" header is "gzip" and "content-encoding" header
    is not "gzip". See more at: https://cloud.google.com/storage/docs/transcoding#transcoding_and_gzip
    Args:
        response (~requests.Response): The HTTP response object.
        get_headers (callable: response->dict): returns response headers.
    Returns:
        bool: Returns True if decompressive transcoding has occurred; otherwise, False.
    gzip)r9   _STORED_CONTENT_ENCODING_HEADERCONTENT_ENCODING_HEADER)r   r   r   r	   r	   r
   _is_decompressive_transcoding  s    
rd   c                   @   s   e Zd ZdZdd ZdS )r@   zDo-nothing hash object.

    Intended as a stand-in for ``hashlib.md5`` or a crc32c checksum
    implementation in cases where it isn't necessary to compute the hash.
    c                 C   s   dS )zDo-nothing ``update`` method.

        Intended to match the interface of ``hashlib.md5`` and other checksums.

        Args:
            unused_chunk (bytes): A chunk of data.
        Nr	   )selfZunused_chunkr	   r	   r
   update  s    z_DoNothingHash.updateN)__name__
__module____qualname____doc__rf   r	   r	   r	   r
   r@     s   r@   )r   ),rj   
__future__r   r-   rA   loggingr   r%   urllib.parser   r   r   r   Zgoogle.resumable_mediar   ZRANGE_HEADERZCONTENT_RANGE_HEADERrc   r'   rQ   r:   rb   r;   	getLoggerrg   r>   r   r   r   r   r   r   r,   r0   rD   rE   r8   rP   rT   rX   r`   rd   objectr@   r	   r	   r	   r
   <module>   sL   
 
*5