o
    tBhv.                     @   s   d 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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 G dd deZG dd deZG dd dejZG dd deZdd Zdd ZdS )zyBatch updates / deletes of storage buckets / blobs.

See https://cloud.google.com/storage/docs/json_api/v1/how-tos/batch
    )encode_noop)	Generator)MIMEApplication)MIMEMultipart)ParserN)_helpers)
exceptions)
Connection)_DEFAULT_TIMEOUTc                       s    e Zd ZdZ fddZ  ZS )MIMEApplicationHTTPa?  MIME type for ``application/http``.

    Constructs payload from headers and body

    :type method: str
    :param method: HTTP method

    :type uri: str
    :param uri: URI for HTTP request

    :type headers:  dict
    :param headers: HTTP headers

    :type body: str
    :param body: (Optional) HTTP payload

    c                    s   t |trt|}d|d< t||d< |d u rd}d||f g}|dd t| D  |d || d	|}t
jrKt| |d	t d S tt| j}||d	t d S )
Nzapplication/jsonzContent-TypezContent-Length z%s %s HTTP/1.1c                 S   s   g | ]
\}}d ||f qS )z%s: %s ).0keyvaluer   r   q/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/google/cloud/storage/batch.py
<listcomp>?   s    z0MIMEApplicationHTTP.__init__.<locals>.<listcomp>z
http)
isinstancedictjsondumpslenextendsorteditemsappendjoinsixPY2r   __init__r   superr   )selfmethoduriheadersbodylinespayload
super_init	__class__r   r   r    6   s"   




zMIMEApplicationHTTP.__init__)__name__
__module____qualname____doc__r    __classcell__r   r   r*   r   r   #   s    r   c                   @   s.   e Zd ZdZed	ddZdd Zdd ZdS )
_FutureDictzvClass to hold a future value for a deferred request.

    Used by for requests that get sent in a :class:`Batch`.
    Nc                 C   s   t d| |f )a,  Stand-in for dict.get.

        :type key: object
        :param key: Hashable dictionary key.

        :type default: object
        :param default: Fallback value to dict.get.

        :raises: :class:`KeyError` always since the future is intended to fail
                 as a dictionary.
        z&Cannot get(%r, default=%r) on a futureKeyError)r   defaultr   r   r   getS   s   z_FutureDict.getc                 C   s   t d|f )zStand-in for dict[key].

        :type key: object
        :param key: Hashable dictionary key.

        :raises: :class:`KeyError` always since the future is intended to fail
                 as a dictionary.
        z Cannot get item %r from a futurer2   )r"   r   r   r   r   __getitem__b   s   	z_FutureDict.__getitem__c                 C   s   t d||f )a'  Stand-in for dict[key] = value.

        :type key: object
        :param key: Hashable dictionary key.

        :type value: object
        :param value: Dictionary value.

        :raises: :class:`KeyError` always since the future is intended to fail
                 as a dictionary.
        zCannot set %r -> %r on a futurer2   )r"   r   r   r   r   r   __setitem__m   s   z_FutureDict.__setitem__N)r,   r-   r.   r/   staticmethodr5   r6   r7   r   r   r   r   r1   M   s    r1   c                       s4   e Zd ZdZ fddZdd Zedd Z  ZS )_FutureResponsezEReponse that returns a placeholder dictionary for a batched requests.c                    s   t t|   || _d| _d S )N   )r!   r:   r    _future_dictstatus_code)r"   future_dictr*   r   r   r       s   
z_FutureResponse.__init__c                 C      | j S r8   r<   r"   r   r   r   r      s   z_FutureResponse.jsonc                 C   r?   r8   r@   rA   r   r   r   content   s   z_FutureResponse.content)	r,   r-   r.   r/   r    r   propertyrB   r0   r   r   r*   r   r:   |   s    r:   c                       s`   e Zd ZdZdZ fddZefddZdd Zd	d
 Z	dd Z
dd Zdd Zdd Z  ZS )BatchzProxy an underlying connection, batching up change operations.

    :type client: :class:`google.cloud.storage.client.Client`
    :param client: The client to use for making connections.
    i  c                    s6   |j j}|j j}tt| j|||d g | _g | _d S )N)client_infoapi_endpoint)_connectionAPI_BASE_URL_client_infor!   rD   r    	_requests_target_objects)r"   clientrF   rE   r*   r   r   r       s   

zBatch.__init__c                 C   s\   t | j| jkrtd| j | j|||||f t }| j| |dur*||_t|S )au  Override Connection:  defer actual HTTP request.

        Only allow up to ``_MAX_BATCH_SIZE`` requests to be deferred.

        :type method: str
        :param method: The HTTP method to use in the request.

        :type url: str
        :param url: The URL to send the request to.

        :type headers: dict
        :param headers: A dictionary of HTTP headers to send with the request.

        :type data: str
        :param data: The data to send as the body of the request.

        :type target_object: object
        :param target_object:
            (Optional) This allows us to enable custom behavior in our batch
            connection. Here we defer an HTTP request and complete
            initialization of the object at a later time.

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

        :rtype: tuple of ``response`` (a dictionary of sorts)
                and ``content`` (a string).
        :returns: The HTTP response object and the content of the response.
        z#Too many deferred requests (max %d)N)	r   rJ   _MAX_BATCH_SIZE
ValueErrorr   r1   rK   _propertiesr:   )r"   r#   urlr%   datatarget_objecttimeoutresultr   r   r   _do_request   s   "zBatch._do_requestc                 C   s   t | jdkrtdt }t}| jD ]\}}}}}t||||}|| |}qtjr1t	
 }	nt	 }	t|	dd}
|
| |	 }|dd\}}t|j||fS )zPrepares headers and body for a batch request.

        :rtype: tuple (dict, str)
        :returns: The pair of headers and body of the batch request to be sent.
        :raises: :class:`ValueError` if no requests have been deferred.
        r   zNo deferred requestsFz

   )r   rJ   rN   r   r
   r   attachr   r   ioBytesIOStringIOr   flattengetvaluesplitr   _headers)r"   multirS   r#   r$   r%   r&   _timeout
subrequestbuf	generatorr(   _r   r   r   _prepare_batch_request   s    


zBatch._prepare_batch_requestc              	   C   s   d}t | jt |krtdt| j|D ].\}}d|j  kr$dk s*n |p(|}q|durCz| |_W q tyB   |j|_Y qw q|durMt	|dS )a6  Apply all the batch responses to the futures created.

        :type responses: list of (headers, payload) tuples.
        :param responses: List of headers and payloads from each response in
                          the batch.

        :raises: :class:`ValueError` if no requests have been deferred.
        Nz&Expected a response for every request.   i,  )
r   rK   rN   zipr=   r   rO   rB   r   from_http_response)r"   	responsesexception_argsrR   subresponser   r   r   _finish_futures   s    

zBatch._finish_futuresc                 C   sJ   |   \}}}d| j }| jjjd||||d}tt|}| | |S )zSubmit a single `multipart/mixed` request with deferred requests.

        :rtype: list of tuples
        :returns: one ``(headers, payload)`` tuple per deferred request.
        z%s/batch/storage/v1POST)rQ   r%   rS   )re   rH   _client_base_connection_make_requestlist_unpack_batch_responserl   )r"   r%   r&   rS   rP   responseri   r   r   r   finish  s   


zBatch.finishc                 C   s   | j jS )z"Return the topmost batch, or None.)rn   current_batchrA   r   r   r   current  s   zBatch.currentc                 C   s   | j |  | S r8   )rn   _push_batchrA   r   r   r   	__enter__  s   zBatch.__enter__c                 C   s>   z|d u r|    W | j  d S W | j  d S | j  w r8   )rt   rn   
_pop_batch)r"   exc_typeexc_valexc_tbr   r   r   __exit__#  s   
zBatch.__exit__)r,   r-   r.   r/   rM   r    r
   rU   re   rl   rt   rv   rx   r}   r0   r   r   r*   r   rD      s    

- rD   c                 C   sH   t |jdd}dd|d|jg}tjr| |S | |	dS )zdConvert response, content -> (multipart) email.message.

    Helper for _unpack_batch_response.
    zcontent-typer       s   Content-Type: s   
MIME-Version: 1.0

utf-8)
r   	_to_bytesr%   r5   r   rB   r   r   parsestrdecode)parserrs   content_typefaux_messager   r   r   _generate_faux_mime_message+  s   
r   c                 c   s    t  }t|| }t|jtstd|jD ]K}|jdd\}}|dd\}}}||}|j}	t|j	}
|

d}t }tjdd|d	 |_t||_|j|
 |	d
|_|V  qdS )a  Convert requests.Response -> [(headers, payload)].

    Creates a generator of tuples of emulating the responses to
    :meth:`requests.Session.request`.

    :type response: :class:`requests.Response`
    :param response: HTTP response / headers from a request.
    zBad response:  not multi-part
rV       z
Content-IDBATCHzcontentid://{})r#   rP   r   N)r   r   r   _payloadrq   rN   r]   r   r   r^   r5   requestsResponseRequestformatpreparerequestintr=   r%   updateencode_content)rs   r   messagera   status_linerestrd   statussub_messager(   msg_headers
content_idrk   r   r   r   rr   ?  s.   	






rr   )r/   email.encodersr   email.generatorr   email.mime.applicationr   email.mime.multipartr   email.parserr   rX   r   r   r   google.cloudr   r   google.cloud.storage._httpr	   google.cloud.storage.constantsr
   r   objectr1   r   r:   rD   r   rr   r   r   r   r   <module>   s*   */  