Ë
    T¼SfÙ‘  ã                   ó<  — d 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dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ  G d„ d	e «      Z! G d
„ de!«      Z" G d„ de!«      Z# G d„ de!ejH                  «      Z$d„ Z%d„ Z&d„ Z'd„ Z(d„ Z)y)záVirtual bases classes for uploading media via Google APIs.

Supported here are:

* simple (media) uploads
* multipart uploads that contain both metadata and a small file as payload
* resumable uploads (with metadata as well)
é    N)Ú_async_resumable_media)Ú_helpers)Ú_upload)Úcommon)Ú_CONTENT_TYPE_HEADERÚ_CONTENT_RANGE_TEMPLATEÚ_RANGE_UNKNOWN_TEMPLATEÚ_EMPTY_RANGE_TEMPLATEÚ_BOUNDARY_FORMATÚ_MULTIPART_SEPÚ_CRLFÚ_MULTIPART_BEGINÚ_RELATED_HEADERÚ_BYTES_RANGE_REÚ_STREAM_ERROR_TEMPLATEÚ_POSTÚ_PUTÚ!_UPLOAD_CHECKSUM_MISMATCH_MESSAGEÚ0_UPLOAD_METADATA_NO_APPROPRIATE_CHECKSUM_MESSAGEc                   ó^   — e Zd ZdZd	d„Zed„ «       Zd„ Zed„ «       Z	ed„ «       Z
ed„ «       Zy)
Ú
UploadBaseaœ  Base class for upload helpers.

    Defines core shared behavior across different upload types.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    Nc                 óh   — || _         |€i }|| _        d| _        t        j                  «       | _        y )NF)Ú
upload_urlÚ_headersÚ	_finishedr   ÚRetryStrategyÚ_retry_strategy)Úselfr   Úheaderss      údC:\Users\user\Documents\project_loop\venv\Lib\site-packages\google/_async_resumable_media/_upload.pyÚ__init__zUploadBase.__init__F   s2   € Ø$ˆŒØˆ?ØˆGØˆŒØˆŒÜ%×3Ñ3Ó5ˆÕó    c                 ó   — | j                   S )z2bool: Flag indicating if the upload has completed.)r   ©r   s    r    ÚfinishedzUploadBase.finishedN   s   € ð �~‰~Ðr"   c                 ó†   — d| _         t        j                  |t        j                  j
                  f| j                  «       y)aÚ  Process the response from an HTTP request.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 200.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        TN)r   r   Úrequire_status_codeÚhttpÚclientÚOKÚ_get_status_code©r   Úresponses     r    Ú_process_responsezUploadBase._process_responseS   s.   € ð$ ˆŒÜ×$Ñ$ X´·±·±Ð/@À$×BWÑBWÕXr"   c                 ó   — t        d«      ‚)zÇAccess the status code from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        úThis implementation is virtual.©ÚNotImplementedError©r-   s    r    r+   zUploadBase._get_status_codeh   ó   € ô "Ð"CÓDÐDr"   c                 ó   — t        d«      ‚)zÃAccess the headers from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   r3   s    r    Ú_get_headerszUploadBase._get_headerst   r4   r"   c                 ó   — t        d«      ‚)zÉAccess the response body from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   r3   s    r    Ú	_get_bodyzUploadBase._get_body€   r4   r"   ©N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r!   Úpropertyr%   r.   Ústaticmethodr+   r6   r8   © r"   r    r   r   8   sh   „ ñó6ð ñó ðòYð* ñ	Eó ð	Eð ñ	Eó ð	Eð ñ	Eó ñ	Er"   r   c                   ó   — e Zd ZdZd„ Zdd„Zy)ÚSimpleUploadaÂ  Upload a resource to a Google API.

    A **simple** media upload sends no metadata and completes the upload
    in a single request.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    c                 óÜ   — | j                   rt        d«      ‚t        |t        «      st	        dt        |«      «      ‚|| j                  t        <   t        | j                  || j                  fS )aÁ  Prepare the contents of an HTTP request.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        .. note:

            This method will be used only once, so ``headers`` will be
            mutated by having a new key added to it.

        Args:
            data (bytes): The resource content to be uploaded.
            content_type (str): The content type for the request.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already finished.
            TypeError: If ``data`` isn't bytes.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        ú An upload can only be used once.ú`data` must be bytes, received)
r%   Ú
ValueErrorÚ
isinstanceÚbytesÚ	TypeErrorÚtyper   r   r   r   )r   ÚdataÚcontent_types      r    Ú_prepare_requestzSimpleUpload._prepare_requestœ   sY   € ð< �=Š=ÜÐ?Ó@Ð@ä˜$¤Ô&ÜÐ<¼dÀ4»jÓIÐIØ.:ˆ�‰Ô*Ñ+Ü�d—o‘o t¨T¯]©]Ð:Ð:r"   Nc                 ó   — t        d«      ‚)a  Transmit the resource to be uploaded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            data (bytes): The resource content to be uploaded.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   Ú	transportrK   rL   Útimeouts        r    ÚtransmitzSimpleUpload.transmitÂ   s   € ô$ "Ð"CÓDÐDr"   r9   )r:   r;   r<   r=   rM   rQ   r@   r"   r    rB   rB   �   s   „ ñò$;ôLEr"   rB   c                   ó2   ‡ — e Zd ZdZdˆ fd„	Zd„ Zdd„Zˆ xZS )ÚMultipartUploada3  Upload a resource with metadata to a Google API.

    A **multipart** upload sends both metadata and the resource in a single
    (multipart) request.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.
        checksum Optional([str]): The type of checksum to compute to verify
            the integrity of the object. The request metadata will be amended
            to include the computed value. Using this option will override a
            manually-set checksum value. Supported values are "md5", "crc32c"
            and None. The default is None.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    c                 ó>   •— t         t        | �  ||¬«       || _        y )N©r   )ÚsuperrS   r!   Ú_checksum_type)r   r   r   ÚchecksumÚ	__class__s       €r    r!   zMultipartUpload.__init__ë   s   ø€ ÜŒo˜tÑ-¨jÀ'Ð-ÔJØ&ˆÕr"   c                 ó  — | j                   rt        d«      ‚t        |t        «      st	        dt        |«      «      ‚t        j                  | j                  «      }|�X|j                  |«       t        j                  |j                  «       «      }t        j                  | j                  «      }|||<   t        |||«      \  }}t        |z   dz   }	|	| j                  t         <   t"        | j$                  || j                  fS )aj  Prepare the contents of an HTTP request.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        .. note:

            This method will be used only once, so ``headers`` will be
            mutated by having a new key added to it.

        Args:
            data (bytes): The resource content to be uploaded.
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already finished.
            TypeError: If ``data`` isn't bytes.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        rD   rE   ó   ")r%   rF   rG   rH   rI   rJ   Úsync_helpersÚ_get_checksum_objectrW   ÚupdateÚprepare_checksum_digestÚdigestÚ_get_metadata_keyÚconstruct_multipart_requestr   r   r   r   r   )
r   rK   ÚmetadatarL   Úchecksum_objectÚactual_checksumÚmetadata_keyÚcontentÚmultipart_boundaryÚmultipart_content_types
             r    rM   z MultipartUpload._prepare_requestï   sì   € ðB �=Š=ÜÐ?Ó@Ð@ä˜$¤Ô&ÜÐ<¼dÀ4»jÓIÐIä&×;Ñ;¸D×<OÑ<OÓPˆàÐ&Ø×"Ñ" 4Ô(Ü*×BÑBØ×&Ñ&Ó(óˆOô (×9Ñ9¸$×:MÑ:MÓNˆLØ%4ˆH�\Ñ"ä&AØ�(˜Ló'
Ñ#ˆÐ#ô "1Ð3EÑ!EÈÑ!LÐà.Dˆ�‰Ô*Ñ+ä�d—o‘o w°·±Ð=Ð=r"   c                 ó   — t        d«      ‚)aq  Transmit the resource to be uploaded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            data (bytes): The resource content to be uploaded.
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   rK   rc   rL   rP   s         r    rQ   zMultipartUpload.transmit)  ó   € ô( "Ð"CÓDÐDr"   ©NNr9   )r:   r;   r<   r=   r!   rM   rQ   Ú__classcell__©rY   s   @r    rS   rS   ×   s   ø„ ñõ&'ò8>÷tEr"   rS   c                   óÄ   ‡ — e Zd ZdZdˆ fd„	Zed„ «       Zed„ «       Zed„ «       Zed„ «       Z	ed„ «       Z
	 dd„Zd	„ Z	 	 	 dd
„Zd„ Zd„ Zd„ Zd„ Zdd„Zd„ Zd„ Zd„ Zˆ xZS )ÚResumableUploadaÂ  Initiate and fulfill a resumable upload to a Google API.

    A **resumable** upload sends an initial request with the resource metadata
    and then gets assigned an upload ID / upload URL to send bytes to.
    Using the upload URL, the upload is then done in chunks (determined by
    the user) until all bytes have been uploaded.

    Args:
        upload_url (str): The URL where the resumable upload will be initiated.
        chunk_size (int): The size of each chunk used to upload the resource.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the :meth:`initiate` request, e.g. headers for
            encrypted data. These **will not** be sent with
            :meth:`transmit_next_chunk` or :meth:`recover` requests.
        checksum Optional([str]): The type of checksum to compute to verify
            the integrity of the object. After the upload is complete, the
            server-computed checksum of the resulting object will be read
            and google.resumable_media.common.DataCorruption will be raised on
            a mismatch. The corrupted file will not be deleted from the remote
            host automatically. Supported values are "md5", "crc32c" and None.
            The default is None.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.

    Raises:
        ValueError: If ``chunk_size`` is not a multiple of
            :data:`.UPLOAD_CHUNK_SIZE`.
    c                 ó>  •— t         t        | �  ||¬«       |t        j                  z  dk7  r+t        dj                  t        j                  dz  «      «      ‚|| _        d | _        d | _	        d| _
        d| _        || _        d | _        d | _        d | _        d| _        y )NrU   r   z{} KB must divide chunk sizei   F)rV   rp   r!   r   ÚUPLOAD_CHUNK_SIZErF   ÚformatÚ_chunk_sizeÚ_streamÚ_content_typeÚ_bytes_uploadedÚ_bytes_checksummedrW   Ú_checksum_objectÚ_total_bytesÚ_resumable_urlÚ_invalid)r   r   Ú
chunk_sizerX   r   rY   s        €r    r!   zResumableUpload.__init___  s¤   ø€ ÜŒo˜tÑ-¨jÀ'Ð-ÔJØÔ.×@Ñ@Ñ@ÀAÒEÜØ.×5Ñ5Ü*×<Ñ<¸tÑCóóð ð
 &ˆÔØˆŒØ!ˆÔØ ˆÔØ"#ˆÔØ&ˆÔØ $ˆÔØ ˆÔØ"ˆÔØˆ�r"   c                 ó   — | j                   S )zÅbool: Indicates if the upload is in an invalid state.

        This will occur if a call to :meth:`transmit_next_chunk` fails.
        To recover from such a failure, call :meth:`recover`.
        ©r|   r$   s    r    ÚinvalidzResumableUpload.invalidr  s   € ð �}‰}Ðr"   c                 ó   — | j                   S )z8int: The size of each chunk used to upload the resource.)rt   r$   s    r    r}   zResumableUpload.chunk_size{  s   € ð ×ÑÐr"   c                 ó   — | j                   S )z;Optional[str]: The URL of the in-progress resumable upload.)r{   r$   s    r    Úresumable_urlzResumableUpload.resumable_url€  s   € ð ×"Ñ"Ð"r"   c                 ó   — | j                   S )z-int: Number of bytes that have been uploaded.)rw   r$   s    r    Úbytes_uploadedzResumableUpload.bytes_uploaded…  s   € ð ×#Ñ#Ð#r"   c                 ó   — | j                   S )aÈ  Optional[int]: The total number of bytes to be uploaded.

        If this upload is initiated (via :meth:`initiate`) with
        ``stream_final=True``, this value will be populated based on the size
        of the ``stream`` being uploaded. (By default ``stream_final=True``.)

        If this upload is initiated with ``stream_final=False``,
        :attr:`total_bytes` will be :data:`None` since it cannot be
        determined from the stream.
        )rz   r$   s    r    Útotal_byteszResumableUpload.total_bytesŠ  s   € ð × Ñ Ð r"   c                 óÒ  — | j                   �t        d«      ‚|j                  «       dk7  rt        d«      ‚|| _        || _        t
        dd|i}|�|| _        n|rt        |«      | _        | j                  � dj                  | j                  «      }||d<   |j                  | j                  «       t        j                  |«      j                  d«      }t        | j                  ||fS )	a�  Prepare the contents of HTTP request to initiate upload.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            stream (IO[bytes]): The stream (i.e. file-like object) that will
                be uploaded. The stream **must** be at the beginning (i.e.
                ``stream.tell() == 0``).
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            total_bytes (Optional[int]): The total number of bytes to be
                uploaded. If specified, the upload size **will not** be
                determined from the stream (even if ``stream_final=True``).
            stream_final (Optional[bool]): Indicates if the ``stream`` is
                "final" (i.e. no more bytes will be added to it). In this case
                we determine the upload size from the size of the stream. If
                ``total_bytes`` is passed, this argument will be ignored.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already been initiated.
            ValueError: If ``stream`` is not at the beginning.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        z'This upload has already been initiated.r   zStream must be at beginning.zapplication/json; charset=UTF-8zx-upload-content-typez{:d}zx-upload-content-lengthúutf-8)rƒ   rF   Útellru   rv   r   rz   Úget_total_bytesrs   r^   r   ÚjsonÚdumpsÚencoder   r   )	r   Ústreamrc   rL   r‡   Ústream_finalr   Úcontent_lengthÚpayloads	            r    Ú_prepare_initiate_requestz)ResumableUpload._prepare_initiate_request˜  sß   € ðN ×ÑÐ)ÜÐFÓGÐGØ�;‰;‹=˜AÒÜÐ;Ó<Ð<àˆŒØ)ˆÔä Ð"CØ# \ð
ˆð
 Ð"Ø +ˆDÕÙÜ /°Ó 7ˆDÔà×ÑÐ(Ø#Ÿ]™]¨4×+<Ñ+<Ó=ˆNØ1?ˆGÐ-Ñ.à�‰�t—}‘}Ô%Ü—*‘*˜XÓ&×-Ñ-¨gÓ6ˆÜ�d—o‘o w°Ð7Ð7r"   c                 óÜ   — t        j                  |t        j                  j                  f| j
                  | j                  ¬«       t        j                  |d| j                  «      | _	        y)aV  Process the response from an HTTP request that initiated upload.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        This method takes the URL from the ``Location`` header and stores it
        for future use. Within that URL, we assume the ``upload_id`` query
        parameter has been included, but we do not check.

        Args:
            response (object): The HTTP response object (need headers).

        .. _sans-I/O: https://sans-io.readthedocs.io/
        ©ÚcallbackÚlocationN)
r   r'   r(   r)   r*   r+   Ú_make_invalidÚheader_requiredr6   r{   r,   s     r    Ú_process_initiate_responsez*ResumableUpload._process_initiate_responseØ  sW   € ô  	×$Ñ$ØÜ�[‰[�^‰^ÐØ×!Ñ!Ø×'Ñ'õ		
ô '×6Ñ6Ø�j $×"3Ñ"3ó
ˆÕr"   c                 ó   — t        d«      ‚)ah  Initiate a resumable upload.

        By default, this method assumes your ``stream`` is in a "final"
        state ready to transmit. However, ``stream_final=False`` can be used
        to indicate that the size of the resource is not known. This can happen
        if bytes are being dynamically fed into ``stream``, e.g. if the stream
        is attached to application logs.

        If ``stream_final=False`` is used, :attr:`chunk_size` bytes will be
        read from the stream every time :meth:`transmit_next_chunk` is called.
        If one of those reads produces strictly fewer bites than the chunk
        size, the upload will be concluded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            stream (IO[bytes]): The stream (i.e. file-like object) that will
                be uploaded. The stream **must** be at the beginning (i.e.
                ``stream.tell() == 0``).
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            total_bytes (Optional[int]): The total number of bytes to be
                uploaded. If specified, the upload size **will not** be
                determined from the stream (even if ``stream_final=True``).
            stream_final (Optional[bool]): Indicates if the ``stream`` is
                "final" (i.e. no more bytes will be added to it). In this case
                we determine the upload size from the size of the stream. If
                ``total_bytes`` is passed, this argument will be ignored.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   r�   rc   rL   r‡   r�   rP   s           r    ÚinitiatezResumableUpload.initiateò  s   € ôb "Ð"CÓDÐDr"   c                 óî  — | j                   rt        d«      ‚| j                  rt        d«      ‚| j                  €t        d«      ‚t	        | j
                  | j                  | j                  «      \  }}}|| j                  k7  r+t        j                  || j                  «      }t        |«      ‚| j                  ||«       t        | j                  t        j                  |i}t         | j                  ||fS )a¦  Prepare the contents of HTTP request to upload a chunk.

        This is everything that must be done before a request that doesn't
        require network I/O. This is based on the `sans-I/O`_ philosophy.

        For the time being, this **does require** some form of I/O to read
        a chunk from ``stream`` (via :func:`get_next_chunk`). However, this
        will (almost) certainly not be network I/O.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always PUT)
              * the URL for the request
              * the body of the request
              * headers for the request

            The headers **do not** incorporate the ``_headers`` on the
            current instance.

        Raises:
            ValueError: If the current upload has finished.
            ValueError: If the current upload is in an invalid state.
            ValueError: If the current upload has not been initiated.
            ValueError: If the location in the stream (i.e. ``stream.tell()``)
                does not agree with ``bytes_uploaded``.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        zUpload has finished.z;Upload is in an invalid state. To recover call `recover()`.z_This upload has not been initiated. Please call initiate() before beginning to transmit chunks.)r%   rF   r€   rƒ   Úget_next_chunkru   rt   rz   r…   r   rs   Ú_update_checksumr   rv   r   ÚCONTENT_RANGE_HEADERr   )r   Ú
start_byter’   Úcontent_rangeÚmsgr   s         r    rM   z ResumableUpload._prepare_request%  sñ   € ð< �=Š=ÜÐ3Ó4Ð4Ø�<Š<ÜØMóð ð ×ÑÐ%ÜðBóð ô
 .<Ø�L‰L˜$×*Ñ*¨D×,=Ñ,=ó.
Ñ*ˆ
�G˜]ð ˜×,Ñ,Ò,Ü(×/Ñ/°
¸D×<OÑ<OÓPˆCÜ˜S“/Ð!à×Ñ˜j¨'Ô2ô ! $×"4Ñ"4Ü×)Ñ)¨=ð
ˆô �T×'Ñ'¨°'Ð9Ð9r"   c                 ó   — d| _         y)zÏSimple setter for ``invalid``.

        This is intended to be passed along as a callback to helpers that
        raise an exception so they can mark this instance as invalid before
        raising.
        TNr   r$   s    r    r˜   zResumableUpload._make_invalid^  s   € ð ˆ�r"   c              ƒ   óª  K  — t        j                  |t        j                  j                  t        j                  j
                  f| j                  | j                  ¬«      }|t        j                  j                  k(  r5| j                  |z   | _        d| _	        | j                  |«      ƒ d{  –—†  yt        j                  |t         j                  | j                  | j                  ¬«      }t        j                  |«      }|€(| j                  «        t!        j"                  |d|d«      ‚t%        |j'                  d«      «      dz   | _        y7 Œ¢­w)a  Process the response from an HTTP request.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.
            bytes_sent (int): The number of bytes sent in the request that
                ``response`` was returned for.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is 308 and the ``range`` header is not of the form
                ``bytes 0-{end}``.
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 200 or 308.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        r•   TNúUnexpected "range" headerú*Expected to be of the form "bytes=0-{end}"Úend_byteé   )r   r'   r(   r)   r*   ÚPERMANENT_REDIRECTr+   r˜   rw   r   Ú_validate_checksumr™   ÚRANGE_HEADERr6   r   Úmatchr   ÚInvalidResponseÚintÚgroup)r   r-   Ú
bytes_sentÚstatus_codeÚbytes_ranger­   s         r    Ú_process_resumable_responsez+ResumableUpload._process_resumable_responseg  s  è ø€ ô* ×2Ñ2ØÜ�[‰[�^‰^œTŸ[™[×;Ñ;Ð<Ø×!Ñ!Ø×'Ñ'ô	
ˆð œ$Ÿ+™+Ÿ.™.Ò(ð $(×#7Ñ#7¸*Ñ#DˆDÔ à!ˆDŒNà×)Ñ)¨(Ó3×3Ñ3ä"×2Ñ2ØÜ×%Ñ%Ø×!Ñ!Ø×+Ñ+ô	ˆKô $×)Ñ)¨+Ó6ˆEØˆ}Ø×"Ñ"Ô$Ü×,Ñ,ØØ/ØØ@ó	ð ô $' u§{¡{°:Ó'>Ó#?À!Ñ#CˆDÕ ð# 4ús   ‚B,EÂ.EÂ/B#Ec              ƒ   ó  K  — | j                   €yt        j                  | j                   «      }|j                  «       ƒ d{  –—† }|j	                  |«      }|€9t        j                  |t        j                  |«      | j                  |«      «      ‚t        j                  | j                  j                  «       «      }||k7  rCt        j                  |t        j                  | j                   j                  «       ||«      «      ‚y7 ŒÆ­w)aQ  Check the computed checksum, if any, against the response headers.
        Args:
            response (object): The HTTP response object.
        Raises:
            ~google.resumable_media.common.DataCorruption: If the checksum
            computed locally and the checksum reported by the remote host do
            not match.
        N)rW   r\   ra   rŒ   Úgetr   r®   r   rs   r6   r_   ry   r`   ÚDataCorruptionr   Úupper)r   r-   rf   rc   Úremote_checksumÚlocal_checksums         r    r«   z"ResumableUpload._validate_checksum¢  só   è ø€ ð ×ÑÐ&ØÜ#×5Ñ5°d×6IÑ6IÓJˆØ!Ÿ™›×(ˆØ"Ÿ,™, |Ó4ˆØÐ"Ü×(Ñ(ØÜ@×GÑGÈÓUØ×!Ñ! (Ó+óð ô
 &×=Ñ=Ø×!Ñ!×(Ñ(Ó*ó
ˆð ˜_Ò,Ü×'Ñ'ØÜ1×8Ñ8Ø×'Ñ'×-Ñ-Ó/°Àóóð ð -ð )ús   ‚A DÁD	ÁCDc                 ó   — t        d«      ‚)a  Transmit the next chunk of the resource to be uploaded.

        If the current upload was initiated with ``stream_final=False``,
        this method will dynamically determine if the upload has completed.
        The upload will be considered complete if the stream produces
        fewer than :attr:`chunk_size` bytes when a chunk is read from it.

        Args:
            transport (object): An object which can make authenticated
                requests.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   rP   s      r    Útransmit_next_chunkz#ResumableUpload.transmit_next_chunkÁ  rk   r"   c                 ó|   — | j                   st        d«      ‚t        j                  di}t        | j
                  d|fS )a‹  Prepare the contents of HTTP request to recover from failure.

        This is everything that must be done before a request that doesn't
        require network I/O. This is based on the `sans-I/O`_ philosophy.

        We assume that the :attr:`resumable_url` is set (i.e. the only way
        the upload can end up :attr:`invalid` is if it has been initiated.

        Returns:
            Tuple[str, str, NoneType, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always PUT)
              * the URL for the request
              * the body of the request (always :data:`None`)
              * headers for the request

            The headers **do not** incorporate the ``_headers`` on the
            current instance.

        Raises:
            ValueError: If the current upload is not in an invalid state.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        z3Upload is not in invalid state, no need to recover.z	bytes */*N)r€   rF   r   r    r   rƒ   )r   r   s     r    Ú_prepare_recover_requestz(ResumableUpload._prepare_recover_request×  s<   € ð2 �|Š|ÜÐRÓSÐSä×0Ñ0°+Ð>ˆÜ�T×'Ñ'¨¨wÐ6Ð6r"   c                 óî  — t        j                  |t        j                  j                  f| j
                  «       | j                  |«      }t         j                  |v re|t         j                     }t        j                  |«      }|€t        j                  |d|d«      ‚t        |j                  d«      «      dz   | _        nd| _        | j                  j!                  | j                  «       d| _        y)a§  Process the response from an HTTP request to recover from failure.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 308.
            ~google.resumable_media.common.InvalidResponse: If the status
                code is 308 and the ``range`` header is not of the form
                ``bytes 0-{end}``.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        Nr¦   r§   r¨   r©   r   F)r   r'   r(   r)   rª   r+   r6   r¬   r   r­   r   r®   r¯   r°   rw   ru   Úseekr|   )r   r-   r   r³   r­   s        r    Ú_process_recover_responsez)ResumableUpload._process_recover_responseö  sØ   € ô& 	×$Ñ$ØÜ�[‰[×+Ñ+Ð-Ø×!Ñ!ô	
ð
 ×#Ñ# HÓ-ˆÜ× Ñ  GÑ+Ø!¤(×"7Ñ"7Ñ8ˆKÜ#×)Ñ)¨+Ó6ˆEØˆ}Ü×,Ñ,ØØ/ØØ@ó	ð ô $' u§{¡{°:Ó'>Ó#?À!Ñ#CˆDÕ ð $%ˆDÔ à�‰×Ñ˜$×.Ñ.Ô/Øˆ�r"   c                 ó   — t        d«      ‚)a!  Recover from a failure.

        This method should be used when a :class:`ResumableUpload` is in an
        :attr:`~ResumableUpload.invalid` state due to a request failure.

        This will verify the progress with the server and make sure the
        current upload is in a valid state before :meth:`transmit_next_chunk`
        can be used again.

        Args:
            transport (object): An object which can make authenticated
                requests.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   s     r    ÚrecoverzResumableUpload.recover!  s   € ô" "Ð"CÓDÐDr"   rl   )NT)NTNr9   )r:   r;   r<   r=   r!   r>   r€   r}   rƒ   r…   r‡   r“   rš   rœ   rM   r˜   r´   r«   r¼   r¾   rÁ   rÃ   rm   rn   s   @r    rp   rp   @  sÄ   ø„ ñõ<ð& ñó ðð ñ ó ð ð ñ#ó ð#ð ñ$ó ð$ð ñ!ó ð!ð NRó>8ò@
ð@ ØØó1Eòf7:òrò9Dòvó>Eò,7ò>)öVEr"   rp   c                  ó”   — t        j                  t        j                  «      } t	        j
                  | «      }|j                  d«      S )zŒGet a random boundary for a multipart request.

    Returns:
        bytes: The boundary used to separate parts of a multipart request.
    r‰   )ÚrandomÚ	randrangeÚsysÚmaxsizer   rs   rŽ   )Ú
random_intÚboundarys     r    Úget_boundaryrË   5  s9   € ô ×!Ñ!¤#§+¡+Ó.€JÜ×&Ñ& zÓ2€Hð �?‰?˜7Ó#Ð#r"   c                 ó$  — t        «       }t        j                  |«      j                  d«      }|j                  d«      }t        |z   }|t
        z   |z   t        z   |z   t        z   dz   |z   t        z   t        z   | z   t        z   |z   t        z   }||fS )aå  Construct a multipart request body.

    Args:
        data (bytes): The resource content (UTF-8 encoded as bytes)
            to be uploaded.
        metadata (Mapping[str, str]): The resource metadata, such as an
            ACL list.
        content_type (str): The content type of the resource, e.g. a JPEG
            image has content type ``image/jpeg``.

    Returns:
        Tuple[bytes, bytes]: The multipart request body and the boundary used
        between each part.
    r‰   s   content-type: )rË   rŒ   r�   rŽ   r   r   r   )rK   rc   rL   rh   Ú
json_bytesÚboundary_seprg   s          r    rb   rb   B  sÖ   € ô &›ÐÜ—‘˜HÓ%×,Ñ,¨WÓ5€JØ×&Ñ& wÓ/€Lô "Ð$6Ñ6€LàÜ
ñ	à
ñ	ô ñ	ð ñ		ô
 ñ	ð ñ	ð ñ	ô ñ	ô ñ		ð ñ
	ô ñ	ð ñ	ô ñ	ð ð" Ð&Ð&Ð&r"   c                 ó¨   — | j                  «       }| j                  dt        j                  «       | j                  «       }| j                  |«       |S )z¯Determine the total number of bytes in a stream.

    Args:
       stream (IO[bytes]): The stream (i.e. file-like object).

    Returns:
        int: The number of bytes.
    r   )rŠ   rÀ   ÚosÚSEEK_END)r�   Úcurrent_positionÚend_positions      r    r‹   r‹   k  sB   € ð —{‘{“}Ðð ‡K�K�”2—;‘;ÔØ—;‘;“=€Là
‡K�KÐ Ô!àÐr"   c                 óX  — | j                  «       }|�&||z   |cxk\  rdkD  rn n| j                  ||z
  «      }n| j                  |«      }| j                  «       dz
  }t        |«      }|€||k  r+|dz   }n%|dk(  r|dk7  rt        d«      ‚|dk(  rt        d«      ‚t	        |||«      }|||fS )aô  Get a chunk from an I/O stream.

    The ``stream`` may have fewer bytes remaining than ``chunk_size``
    so it may not always be the case that
    ``end_byte == start_byte + chunk_size - 1``.

    Args:
        stream (IO[bytes]): The stream (i.e. file-like object).
        chunk_size (int): The size of the chunk to be read from the ``stream``.
        total_bytes (Optional[int]): The (expected) total number of bytes
            in the ``stream``.

    Returns:
        Tuple[int, bytes, str]: Triple of:

          * the start byte index
          * the content in between the start and end bytes (inclusive)
          * content range header for the chunk (slice) that has been read

    Raises:
        ValueError: If ``total_bytes == 0`` but ``stream.read()`` yields
            non-empty content.
        ValueError: If there is no data left to consume. This corresponds
            exactly to the case ``end_byte < start_byte``, which can only
            occur if ``end_byte == start_byte - 1``.
    r   r©   z:Stream specified as empty, but produced non-empty content.z;Stream is already exhausted. There is no content remaining.)rŠ   ÚreadÚlenrF   Úget_content_range)r�   r}   r‡   r¡   r’   r¨   Únum_bytes_readr¢   s           r    rž   rž     sÐ   € ð6 —‘“€JØÐ :°
Ñ#:¸kÔ#MÈAÕ#MØ—+‘+˜k¨JÑ6Ó7‰à—+‘+˜jÓ)ˆØ�{‰{‹}˜qÑ €Hä˜“\€NØÐØ˜JÒ&à" Q™,‰KØ	˜Ò	ð ˜QÒÜØLóð ð ˜QÒÜØMóð ô & j°(¸KÓH€MØ�w Ð-Ð-r"   c                 ó”   — |€t        j                  | |«      S || k  rt        j                  |«      S t        j                  | ||«      S )a„  Convert start, end and total into content range header.

    If ``total_bytes`` is not known, uses "bytes {start}-{end}/*".
    If we are dealing with an empty range (i.e. ``end_byte < start_byte``)
    then "bytes */{total}" is used.

    This function **ASSUMES** that if the size is not known, the caller will
    not also pass an empty range.

    Args:
        start_byte (int): The start (inclusive) of the byte range.
        end_byte (int): The end (inclusive) of the byte range.
        total_bytes (Optional[int]): The number of bytes in the byte
            range (if known).

    Returns:
        str: The content range header.
    )r	   rs   r
   r   )r¡   r¨   r‡   s      r    r×   r×   ¸  sK   € ð& ÐÜ&×-Ñ-¨j¸(ÓCÐCØ	�JÒ	Ü$×+Ñ+¨KÓ8Ð8ä&×-Ñ-¨j¸(ÀKÓPÐPr"   )*r=   Úhttp.clientr(   rŒ   rÐ   rÅ   rÇ   Úgoogler   Úgoogle._async_resumable_mediar   Úgoogle.resumable_mediar\   r   Úsync_uploadr   Úgoogle.resumable_media._uploadr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   Úobjectr   rB   rS   rp   rË   rb   r‹   rž   r×   r@   r"   r    ú<module>rá      s«   ðñó Û Û 	Û Û 
å )Ý 2Ý ;Ý 9Ý )÷÷ ÷ ÷ ñ ô&RE�ô REôjGE�:ô GEôTfE�jô fEôRrE�j +×"=Ñ"=ô rEòj
$ò&'òRò(6.órQr"   