
                         x   d Z ddlmZ ddlmZ ddlmc mZ	 ddl
mc 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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 g dZdZdZdZd Z d Z!d Z"d Z# G d de$      Z% G d de%      Z&ejN                  r G d dejP                        Z) G d de%      Z*y)z)Upload and download support for apitools.    )print_functionN)http_client)buffered_stream)compression)
exceptions)http_wrapper)stream_slice)util)DownloadUploadRESUMABLE_UPLOADSIMPLE_UPLOADDownloadProgressPrinterDownloadCompletePrinterUploadProgressPrinterUploadCompletePrinteri  P simple	resumablec                     d| j                   v rt        d| j                   d   z         yt        d| j                  z         y)z*Print download progress based on response.content-rangezReceived %szReceived %d bytesN)infoprintlength)responseunused_downloads     ,lib/third_party/apitools/base/py/transfer.pyr   r   7   s6    (--'mhmmO<<=!HOO34    c                     t        d       y)z-Print information about a completed download.zDownload completeNr   )unused_responser   s     r   r   r   ?   s    	
r   c                 :    t        d| j                  d   z         y)z(Print upload progress based on response.zSent %srangeN)r   r   )r   unused_uploads     r   r   r   D   s    	)hmmG,
,-r   c                     t        d       y)z+Print information about a completed upload.zUpload completeNr   )r    r#   s     r   r   r   I   s    	
r   c                      e Zd ZdZ	 	 ddZd Zed        Zed        Zed        Z	e	j                  d        Z	ed	        Zej                  d
        Zed        Zed        Zd Zed        Zed        Zd Zd Zd Zd Zy)	_Transferz-Generic bits common to Uploads and Downloads.Nc                     d | _         || _        || _        || _        d | _        d| _        || _        t        j                  | _	        || _
        |xs d| _        y )N   i   )_Transfer__bytes_http_Transfer__close_stream_Transfer__http_Transfer__stream_Transfer__url_Transfer__num_retriesnum_retriesr   )HandleExceptionsAndRebuildHttpConnections
retry_funcauto_transfer	chunksize)selfstreamclose_streamr3   r2   httpr/   s          r   __init__z_Transfer.__init__R   s]     *
& BB 	*"-gr   c                     t        |       S N)strr4   s    r   __repr__z_Transfer.__repr__c   s    4yr   c                     | j                   S r:   )r*   r<   s    r   r6   z_Transfer.close_streamf   s    """r   c                     | j                   S r:   )r+   r<   s    r   r7   z_Transfer.httpj   s    {{r   c                 6    | j                   xs | j                  S r:   )r)   r7   r<   s    r   
bytes_httpz_Transfer.bytes_httpn   s      -DII-r   c                     || _         y r:   )r)   r4   values     r   rA   z_Transfer.bytes_httpr   s
    !r   c                     | j                   S r:   )r.   r<   s    r   r/   z_Transfer.num_retriesv   s    !!!r   c                     t        j                  |t        j                         |dk  rt	        j
                  d      || _        y )Nr   z*Cannot have negative value for num_retries)r
   	Typechecksixinteger_typesr   InvalidDataErrorr.   rC   s     r   r/   z_Transfer.num_retriesz   s;    uc//019--<> >"r   c                     | j                   S r:   )r,   r<   s    r   r5   z_Transfer.stream   s    }}r   c                     | j                   S r:   )r-   r<   s    r   urlz_Transfer.url   s    zzr   c                     | j                          | j                  |xs t        j                         | _        || _        y)a  Initialize this download by setting self.http and self.url.

        We want the user to be able to override self.http by having set
        the value in the constructor; in that case, we ignore the provided
        http.

        Args:
          http: An httplib2.Http instance or None.
          url: The url for this transfer.

        Returns:
          None. Initializes self.
        N)EnsureUninitializedr7   r   GetHttpr+   r-   )r4   r7   rM   s      r   _Initializez_Transfer._Initialize   s6     	  "998,"6"6"8DK
r   c                 >    | j                   d uxr | j                  d uS r:   )rM   r7   r<   s    r   initializedz_Transfer.initialized   s    xxt#=		(==r   c                 ,    t        |       j                  S r:   )type__name__r<   s    r   
_type_namez_Transfer._type_name   s    Dz"""r   c                 `    | j                   s"t        j                  d| j                  z        y )NzCannot use uninitialized %srS   r   TransferInvalidErrorrW   r<   s    r   EnsureInitializedz_Transfer.EnsureInitialized   s1    11-?A A  r   c                 `    | j                   r"t        j                  d| j                  z        y )NzCannot re-initialize %srY   r<   s    r   rO   z_Transfer.EnsureUninitialized   s/    11)DOO;= = r   c                 R    | j                   r| j                  j                          y y r:   )r*   r,   closer<   s    r   __del__z_Transfer.__del__   s     MM! r   c                 X    |(t        j                  ||| f      j                          y y )N)targetargs)	threadingThreadstart)r4   callbackr   s      r   _ExecuteCallbackz_Transfer._ExecuteCallback   s+    HHd3CDJJL  r   )FNTNr(   )rV   
__module____qualname____doc__r8   r=   propertyr6   r7   rA   setterr/   r5   rM   rQ   rS   rW   r[   rO   r_   rg    r   r   r&   r&   N   s   7=A<=." # #   . . " " " " # #    & > > # #A
=
"Mr   r&   c                   z    e Zd ZdZ eej                  ej                  ej                  ej                  f      Z
 ed      Zd fd	Zed        Zed        Zedd       Zedd       Ze	 	 dd       Zed	        Zed
        Zd Zd Zd ZddZddZddZddZddZd Z	 	 ddZ	 	 ddZ 	 	 ddZ! xZ"S )r   zqData for a single download.

    Public attributes:
      chunksize: default chunksize to use for transfers.
    r2   progress
total_sizerM   c                     |j                  dd       }t        t        |   |fi | d | _        d| _        || _        d | _        || _        || _	        y )Nrq   r   )
popsuperr   r8   _Download__initial_response_Download__progress_Download__total_size_Download__encodingprogress_callbackfinish_callback)r4   r5   ry   rz   kwdsrq   	__class__s         r   r8   zDownload.__init__   sU    XXlD1
h&v66"&&!2.r   c                     | j                   S r:   )rv   r<   s    r   rp   zDownload.progress       r   c                     | j                   S r:   )rx   r<   s    r   encodingzDownload.encoding   r~   r   c                     t         j                  j                  |      }t         j                  j                  |      r|st	        j
                  d|z         | t        |d      fd|d|S )z-Create a new download object from a filename.z*File %s exists and overwrite not specifiedwbT)r6   r2   )ospath
expanduserexistsr   InvalidUserInputErroropen)clsfilename	overwriter2   r{   r   s         r   FromFilezDownload.FromFile   so     ww!!(+77>>$	22<tCE E4d# 8$!.8268 	8r   c                      | |f||d|S )z+Create a new Download object from a stream.)r2   rq   rm   )r   r5   r2   rq   r{   s        r   
FromStreamzDownload.FromStream   s$     6 :  	r   c                    t        j                  |      }| j                  t        |j	                               z
  }|r't        j                  ddj                  |      z         | j                  |fi |}	|||	_	        n
|d   |	_	        ||j                  |d         }
n|d   }
t        |	d|d          t        |	d|d          |	j                  ||
       |	S )	z?Create a new Download object from a stream and serialized data.,Invalid serialization data, missing keys: %s, r2   rM   rv   rp   rw   rq   )jsonloads_REQUIRED_SERIALIZATION_KEYSsetkeysr   rJ   joinr   r2   FinalizeTransferUrlsetattrrQ   )r   r5   	json_datar7   r2   clientr{   r   missing_keysdownloadrM   s              r   FromDatazDownload.FromData   s     zz)$77#diik:JJ-->IIl+-. . "3>>&1D1$%2H"%)/%:H",,T%[9Cu+C/j1AB143EF#	r   c                     | j                          | j                  | j                  | j                  | j                  dS )Nro   )r[   r2   rp   rq   rM   r<   s    r   serialization_datazDownload.serialization_data  s6     !////88	
 	
r   c                     | j                   S r:   )rw   r<   s    r   rq   zDownload.total_size         r   c                 h    | j                   syd| j                  | j                  | j                  fz  S )NzDownload (uninitialized)z1Download with %d/%s bytes transferred from url %srS   rp   rq   rM   r<   s    r   __str__zDownload.__str__  s4    -BMM4??DHHF6 6 	6r   c                 b    d|j                   d<   d| j                  dz
  fz  |j                  d<   y )Nmediaaltz
bytes=0-%d   Range)query_paramsr3   headers)r4   http_requesturl_builders      r   ConfigureRequestzDownload.ConfigureRequest  s5    *1  '
 )58J7L(LW%r   c                     d|v r-|d   j                  d      \  }}}|dk7  rt        |      | _        | j                  d| _        yy)z;Sets the total size based off info if possible otherwise 0.r   /*Nr   )
rpartitionintrw   rq   )r4   r   _totals       r   
__SetTotalzDownload.__SetTotal#  sQ    d"/::3?KAq%|$'J!
 ??" !D #r   c                    | j                          ||t        j                  d      |xs |j                  }| |j	                  |j
                        |_        |j
                  }| j                  r| j                  d      }| j                  |d|       t        j                  | j                  xs ||      }|j                  | j                  vrt        j                  j                  |      || _        | j#                  |j$                         |j$                  j'                  d|j(                        }||j	                  |      }| j+                  ||       | j                  r| j-                          yy)a  Initialize this download by making a request.

        Args:
          http_request: The HttpRequest to use to initialize this download.
          http: The httplib2.Http instance for this request.
          client: If provided, let this client process the final URL before
              sending any additional requests. If client is provided and
              http is not, client.http will be used instead.
        NMust provide client or http.r   zcontent-location)rO   r   	UserErrorr7   r   rM   r2   _Download__ComputeEndByte_Download__SetRangeHeaderr   MakeRequestrA   status_code_ACCEPTABLE_STATUSES	HttpErrorFromResponseru   _Download__SetTotalr   getrequest_urlrQ   StreamInChunks)r4   r   r7   r   rM   end_byter   s          r   InitializeDownloadzDownload.InitializeDownload0  sN    	  "<FN&&'EFF"v{{%99,:J:JKL,,Q/H!!,8<#//'47H##4+D+DD **77AA&.D#OOHMM*--##$68L8LMC,,S1Cs# ! r   c                    ||dk  rt        j                  dd||fz  z         || j                  k\  r't        j                  dd|| j                  fz  z         t        || j                  dz
        }||k  rt        j                  d|d|d	      ||fS |dk  rt	        d|| j                  z         }|| j                  dz
  fS )
z4Normalizes start and end values based on total size.r   z0Cannot have end index with negative start index z[start=%d, end=%d]z0Cannot have start index greater than total size z[start=%d, total_size=%d]r   zRange requested with end[z
] < start[])r   rZ   rq   minmax)r4   re   ends      r   __NormalizeStartEndzDownload.__NormalizeStartEndS  s    ?qy 55F(E3<789 9 $//) 55F/5$//2JJKL L c4??Q./CU{ 55BEuMO O#:qyAut67$//A---r   c                     |dk  rd|z  |j                   d<   y |||k  rd|z  |j                   d<   y d||fz  |j                   d<   y )Nr   zbytes=%dr"   z	bytes=%d-zbytes=%d-%d)r   )r4   requestre   r   s       r   __SetRangeHeaderzDownload.__SetRangeHeaderh  sQ    19'1E'9GOOG$[C%K'2U':GOOG$'4s|'CGOOG$r   c                     |}|dk  r| j                   s|S |r#|| j                  z   dz
  }|t        ||      }n|}| j                   r!| j                   dz
  }|t        ||      }|S |}|S )a  Compute the last byte to fetch for this request.

        This is all based on the HTTP spec for Range and
        Content-Range.

        Note that this is potentially confusing in several ways:
          * the value for the last byte is 0-based, eg "fetch 10 bytes
            from the beginning" would return 9 here.
          * if we have no information about size, and don't want to
            use the chunksize, we'll return None.
        See the tests for more examples.

        Args:
          start: byte to start at.
          end: (int or None, default: None) Suggested last byte.
          use_chunks: (bool, default: True) If False, ignore self.chunksize.

        Returns:
          Last byte to use in a Range header, or None.

        r   r   )rq   r3   r   )r4   re   r   
use_chunksr   	alternates         r   __ComputeEndBytezDownload.__ComputeEndBytep  s    , 19T__O.2I#x3$??!+I#x3  %r   c                 2   | j                          t        j                  | j                        }| j	                  |||       ||j
                  j                  |       t        j                  | j                  || j                  | j                        S )z/Retrieve a chunk, and return the full response.)rM   )r   )r1   retries)r[   r   RequestrM   r   r   updater   rA   r1   r/   )r4   re   r   additional_headersr   s        r   
__GetChunkzDownload.__GetChunk  s{     &&4884gu#6)OO""#56''OOW$$& 	&r   c                 p   |j                   | j                  vrj|j                   t        j                  t        j                  fv rt
        j                  j                  |      t        j                  |j                        |j                   t        j                  t        j                  fv r	 | j                  j                  t        j                  |j                               | xj$                  |j&                  z  c_        |j(                  r"d|j(                  v r|j(                  d   | _        |S |j                   t        j,                  k(  r| j                  j                  d       |S # t         $ r; | j                  j                  t        j"                  |j                               Y w xY w)z?Process response (by updating self and writing to self.stream).zcontent-encoding )r   r   r   	FORBIDDEN	NOT_FOUNDr   r   r   TransferRetryErrorcontentOKPARTIAL_CONTENTr5   writerH   ensure_binary	TypeErrorensure_textrv   r   r   rx   
NO_CONTENTr4   r   s     r   __ProcessResponsezDownload.__ProcessResponse  s[   t'@'@@ ##(=(=(3(=(=(? ? **77AA 33H4D4DEEKNN$/$?$?$A AE!!#"3"3H4D4D"EF OOx.O}}!3x}}!D #+--0B"C  !![%;%;; KKb!  E!!#//(2B2B"CDEs   08E1 1AF54F5c                     | j                          d}| j                  | j                  ||      \  }}d}n|}|}|r|||k  r| j                  |||      }| j	                  |||      }|s2| j                  |j                         | j                  ||      \  }}d}| j                  |      }||j                  z  }|j                  dk(  r3|j                  t        j                  k(  ryt        j                  d      |s|||k  ryy)a  Retrieve a given byte range from this download, inclusive.

        Range must be of one of these three forms:
        * 0 <= start, end = None: Fetch from start to the end of the file.
        * 0 <= start <= end: Fetch the bytes from start to end.
        * start < 0, end = None: Fetch the last -start bytes of the file.

        (These variations correspond to those described in the HTTP 1.1
        protocol for range headers in RFC 2616, sec. 14.35.1.)

        Args:
          start: (int) Where to start fetching bytes. (See above.)
          end: (int, optional) Where to stop fetching bytes. (See above.)
          additional_headers: (bool, optional) Any additional headers to
              pass with the request.
          use_chunks: (bool, default: True) If False, ignore self.chunksize
              and fetch this range in a single request.

        Returns:
          None. Streams bytes into self.stream.
        FNT)r   r   r   r   z5Zero bytes unexpectedly returned in download response)r[   rq   _Download__NormalizeStartEndr   _Download__GetChunkr   r   _Download__ProcessResponser   r   r   r   r   r   )	r4   re   r   r   r   progress_end_normalizedrp   r   r   s	            r   GetRangezDownload.GetRange  s*   . 	 "'??&!%!9!9%!EHh&*#HH*h.>8#,,X88B - DHx:L ' NH*.%)%=%=eS%I"(*.'--h7H'H!#'';>>9  33KM M) +h.>8#r   c                 .    | j                  |||d       y)z%Stream the entire download in chunks.Trf   rz   r   r   N)StreamMediar4   rf   rz   r   s       r   r   zDownload.StreamInChunks  s!     	(O,>$( 	 	*r   c                 D   |xs | j                   }|xs | j                  }| j                          	 | j                  | j                  }d| _        n;| j	                  | j
                  |      }| j                  | j
                  ||      }| j                  | j                  |j                         | j                  |      }| j                  ||       |j                  t        j                  k(  s| j
                  | j                  k\  rn| j                  ||       y)a4  Stream the entire download.

        Args:
          callback: (default: None) Callback to call as each chunk is
              completed.
          finish_callback: (default: None) Callback to call when the
              download is complete.
          additional_headers: (default: None) Additional headers to
              include in fetching bytes.
          use_chunks: (bool, default: True) If False, ignore self.chunksize
              and stream this download in a single request.

        Returns:
            None. Streams bytes into self.stream.
        N)r   r   )ry   rz   r[   ru   r   rp   r   rq   r   r   r   rg   r   r   r   )r4   rf   rz   r   r   r   r   s          r   r   zDownload.StreamMedia  s   " 5t55)AT-A-A &&222*.'00<F 1 H??MM8'9 + ; &.--h7H!!(H5$$6MMT__4! " 	ox8r   NN)FT)TNNNNr:   )NT)NNTNNNT)#rV   rh   ri   rj   r   r   r   r   r   REQUESTED_RANGE_NOT_SATISFIABLEr   r   r8   rk   rp   r   classmethodr   r   r   r   rq   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r|   s   @r   r   r      sA   
 ##33	   $' (: $; 
/     8 8  
 BF 2 
 
 ! !6M"!"F.*D)V	&8 <@ 4Ml =A*.* :>8<&9r   r   c                        e Zd ZdZd Zd ZeZy)MultipartBytesGeneratorao  Generates a bytes Message object tree for multipart messages

        This is a BytesGenerator that has been modified to not attempt line
        termination character modification in the bytes payload. Known to
        work with the compat32 policy only. It may work on others, but not
        tested. The outfp object must accept bytes in its write method.
        c                 T    |j                   y | j                  |j                          y r:   )_payloadr   )r4   msgs     r   _handle_textz$MultipartBytesGenerator._handle_text1  s!     ||#JJs||$r   c                 &    |j                  dd      S )Nasciisurrogateescape)encode)r4   ss     r   _encodezMultipartBytesGenerator._encode8  s    88G%677r   N)rV   rh   ri   rj   r  r  
_writeBodyrm   r   r   r   r   )  s    		%	8 "
r   r   c                       e Zd ZdZ ed      Z	 	 	 	 d! fd	Zed        Ze		 	 d"d       Z
e		 	 d"d       Ze		 	 d#d       Zed        Zed	        Zed
        Zd Zed        Zej$                  d        Zed        Zej$                  d        Zd Zd Zd Zd Zd Zd Zd Zd$dZd Zd%dZd Z	 	 d&dZ	 	 d'dZ 	 	 d'dZ!d Z"d%dZ#d%d Z$ xZ%S )(r   a  Data for a single Upload.

    Fields:
      stream: The stream to upload.
      mime_type: MIME type of the upload.
      total_size: (optional) Total upload size for the stream.
      close_stream: (default: False) Whether or not we should close the
          stream when finished with the upload.
      auto_transfer: (default: True) If True, stream all bytes as soon as
          the upload is created.
    r2   	mime_typerq   rM   c                     t        t        | 
  |f||||d| d| _        d | _        || _        d| _        d | _        d | _        d | _	        |
| _
        || _        |	| _        || _        y )N)r6   r3   r2   r7   Fr   )rt   r   r8   _Upload__complete_Upload__final_response_Upload__mime_type_Upload__progress!_Upload__server_chunk_granularity_Upload__strategy_Upload__total_size_Upload__gzip_encodedry   rz   rq   )r4   r5   r  rq   r7   r6   r3   r2   ry   rz   gzip_encodedr{   r|   s               r   r8   zUpload.__init__O  s     	fd$	<!-'d	<6:	<   $$*.' *!2.$r   c                     | j                   S r:   )r  r<   s    r   rp   zUpload.progressc  r~   r   c                    t         j                  j                  |      }t         j                  j                  |      st	        j
                  d|z        |s2t        j                  |      \  }}|t	        j                  d|z        t        j                  |      j                  } | t        |d      |f|d||d|S )z+Create a new Upload object from a filename.zCould not find file %sz Could not guess mime type for %srbTrq   r6   r2   r  )r   r   r   r   r   NotFoundError	mimetypes
guess_typer   statst_sizer   )	r   r   r  r2   r  r{   r   r   sizes	            r   r   zUpload.FromFileg  s     ww!!(+ww~~d#**+Cd+JKK$//5LIq  666=? ?wwt}$$4d#Y 64 $M ,6046 	6r   c                 N    |t        j                  d       | ||f|d||d|S )z)Create a new Upload object from a stream.z!No mime_type specified for streamFr  )r   r   )r   r5   r  rq   r2   r  r{   s          r   r   zUpload.FromStreamx  sH     2235 569 6 %] ,6046 	6r   c                    t        j                  |      }| j                  t        |j	                               z
  }	|	r't        j                  ddj                  |	      z        d|v rt        j                  d       | j                  ||d   f|j                  d      |d|}
t        |t        j                        r%|j                         st        j                  d      |||
_        n
|d   |
_        ||j!                  |d	         }n|d	   }t"        |
_        |
j'                  ||       |
j)                          |
j+                          |
j                  r|
j-                          |
S )
zACreate a new Upload of stream from serialized json_data and http.r   r   rq   z/Cannot override total_size on serialized Uploadr  )rq   r  z6Cannot restart resumable upload on non-seekable streamr2   rM   )r   r   r   r   r   r   rJ   r   r   r   r   
isinstanceioIOBaseseekabler2   r   r   strategyrQ   RefreshResumableUploadStater[   r   )r   r5   r   r7   r2   r  r   r{   r   r   uploadrM   s               r   r   zUpload.FromData  sl    zz)$77#diik:JJ-->IIl+-. . 422AC C[(9 C+/88L+A-9C=AC fbii(1B22HJ J$#0F #'#8F **4;7#U#*#	**,  "!!#r   c                     | j                          | j                  t        k7  rt        j                  d      | j
                  | j                  | j                  | j                  dS )Nz2Serialization only supported for resumable uploadsr  )	r[   r'  r   r   rJ   r2   r  rq   rM   r<   s    r   r   zUpload.serialization_data  s]     ==,,--DF F "////88	
 	
r   c                     | j                   S r:   )r  r<   s    r   completezUpload.complete  r~   r   c                     | j                   S r:   )r  r<   s    r   r  zUpload.mime_type  s    r   c                 p    | j                   syd| j                  | j                  xs d| j                  fz  S )NzUpload (uninitialized)z.Upload with %d/%s bytes transferred for url %sz???r   r<   s    r   r   zUpload.__str__  s9    +?MM4??3eTXXC? ? 	?r   c                     | j                   S r:   )r  r<   s    r   r'  zUpload.strategy  r~   r   c                 ^    |t         t        fvrt        j                  d|z        || _        y )NzOInvalid value "%s" for upload strategy, must be one of "simple" or "resumable".)r   r   r   r   r  rC   s     r   r'  zUpload.strategy  s9    (899&&+.3(4 5 5  r   c                     | j                   S r:   )r  r<   s    r   rq   zUpload.total_size  r   r   c                 2    | j                          || _        y r:   )rO   r  rC   s     r   rq   zUpload.total_size  s      "!r   c                    |j                   t        | _        | j                  yt        }| j                  | j                  t        kD  rt
        }|j                  r|j                  st
        }|j                  st
        }|| _        y)a  Determine and set the default upload strategy for this upload.

        We generally prefer simple or multipart, unless we're forced to
        use resumable. This happens when any of (1) the upload is too
        large, (2) the simple endpoint doesn't support multipart requests
        and we have metadata, or (3) there is no simple upload endpoint.

        Args:
          upload_config: Configuration for the upload endpoint.
          http_request: The associated http request.

        Returns:
          None.
        N)	resumable_pathr   r'  rq   _RESUMABLE_UPLOAD_THRESHOLDr   bodysimple_multipartsimple_path)r4   upload_configr   r'  s       r   __SetDefaultUploadStrategyz!Upload.__SetDefaultUploadStrategy  sp     ''/)DM==$ OO'"=='H]%C%C'H(('H r   c                    | j                   rT|j                  rH| j                   |j                  kD  r/t        j                  d| j                   d|j                        t	        j
                  |j                  | j                        s/t        j                  d| j                  d|j                        | j                  ||       | j                  t        k(  r|j                  |_        |j                  r!d|j                  d<   | j                  |       n d|j                  d<   | j!                  |       | j"                  rXd|j$                  d	<   t'        j(                  t+        j,                  |j                              d
   j/                         |_        yy|j0                  |_        d|j                  d<   | j3                  |       y)z.Configure the request and url for this upload.zUpload too big: z larger than max size z
MIME type z) does not match any accepted MIME ranges 	multipart
uploadTyper   gzipContent-Encodingr   r   N)rq   max_sizer   r   r
   AcceptableMimeTypeacceptr  !_Upload__SetDefaultUploadStrategyr'  r   r8  relative_pathr6  r   "_Upload__ConfigureMultipartRequest_Upload__ConfigureMediaRequestr  r   r   CompressStreamrH   BytesIOreadr4  "_Upload__ConfigureResumableRequest)r4   r9  r   r   s       r   r   zUpload.ConfigureRequest  s    OO 6 6-"8"8822OO]%;%;=> > &&}';';T^^L22NNM$8$8:; ; 	''|D==M)(5(A(AK%  9D((600>9@((6,,\: "";A$$%78  ..L$5$56889;;?46 ! # )6(D(DK%5@K$$\2,,\:r   c                     | j                   |j                  d<   | j                  j                         |_        d|_        y)z;Configure http_request as a simple request for this upload.content-type<media body>N)r  r   r5   rI  r6  loggable_bodyr4   r   s     r   __ConfigureMediaRequestzUpload.__ConfigureMediaRequest"  s3    /3~~^, KK,,.%3"r   c                    t        j                  d      }t        |dd        t        j                  |j
                  d   j                  d       }|j                  |j                         |j                  |       t        j                  | j                  j                  d       }d|d<   |j                  | j                  j                                |j                  |       t        j                         }t        j                  rt         }nt"        j$                  } ||d	      }|j'                  |d
       |j)                         |_        |j+                         }d|z  |j
                  d<   t-        |t        j.                        r|j1                  d      }|j                  j                  |      }|d   j3                  d      \  }	}
}
dj5                  |	dg      |d<   |j5                  |      |_        y)z>Configure http_request as a multipart request for this upload.related_write_headersc                      y r:   rm   r<   s    r   <lambda>z4Upload.__ConfigureMultipartRequest.<locals>.<lambda>-  s    r   rL  r   binaryzContent-Transfer-EncodingF)mangle_from_)unixfromzmultipart/related; boundary=%rr  s   

s   <media body>

--N)mime_multipartMIMEMultipartr   mime_nonmultipartMIMENonMultipartr   splitset_payloadr6  attachr  r5   rI  rH   rH  PY3r   email_generator	Generatorflattengetvalueget_boundaryr#  	text_typer  	partitionr   rN  )r4   r   msg_rootr  fpgenerator_classgmultipart_boundarybody_componentsr   r   s              r   __ConfigureMultipartRequestz"Upload.__ConfigureMultipartRequest(  s    "//	:*,=>  00!!.177<>))*  00$..2F2Fs2KL+3'(((*+
 [[]775O-77OBU3			(U	+KKM%224,/AA 	^,(#--8!3!:!:7!C&++112DE'+55g>A%llG5J+KL%7%<%<_%M"r   c                     | j                   |j                  d<   | j                  #t        | j                        |j                  d<   y y )NzX-Upload-Content-TypezX-Upload-Content-Length)r  r   rq   r;   rO  s     r   __ConfigureResumableRequestz"Upload.__ConfigureResumableRequestR  sE    8<45??&-0-A   )+ 'r   c                    | j                   t        k7  ry| j                          t        j                  | j
                  dddi      }t        j                  | j                  |d| j                        }| j                  |      }|j                  t        j                  t        j                  fv rEd| _        | j                  | _        | j"                  j%                  | j&                         || _        y|j                  t        j*                  k(  rI|d| _        n| j-                  |      d	z   | _        | j"                  j%                  | j&                         yt.        j0                  j3                  |      )
zTalk to the server and refresh the state of this resumable upload.

        Returns:
          Response if the upload is complete.
        NPUTContent-Rangez	bytes */*)rM   http_methodr   r   )redirectionsr   Tr   )r'  r   r[   r   r   rM   r   r7   r/   _GetRangeHeaderFromResponser   r   r   CREATEDr  rq   r  r5   seekrp   r  RESUME_INCOMPLETE_Upload__GetLastByter   r   r   )r4   refresh_requestrefresh_responserange_headers       r   r(  z"Upload.RefreshResumableUploadStateX  s7    ==,, &..e$k24 (33IIQ$$& 778HI''KNN,7,?,?,A A"DO"ooDOKKT]]+ %5D!))\-K-KK#"#"&"4"4\"BQ"FKKT]]+&&334DEEr   c                 l    |j                   j                  d|j                   j                  d            S )Nr   r"   )r   r   r   s     r   rw  z"Upload._GetRangeHeaderFromResponsez  s(    }}  (--*;*;G*DEEr   c                    | j                   t        j                  d      ||t        j                  d      | j                   t        k7  ry|xs |j                  }| |j                  |j                        |_        | j                          t        j                  ||| j                        }|j                  t        j                  k7  rt        j                  j                  |      |j                   j#                  d      | _        |j                   d   }||j                  |      }| j'                  ||       | j(                  r| j+                         S |S )z3Initialize this upload from the given http_request.Nz6No upload strategy set; did you call ConfigureRequest?r   )r   zX-Goog-Upload-Chunk-Granularitylocation)r'  r   r   r   r7   r   rM   rO   r   r   r/   r   r   r   r   r   r   r   r  rQ   r2   r   )r4   r   r7   r   http_responserM   s         r   InitializeUploadzUpload.InitializeUpload}  sA   == &&HJ J<FN&&'EFF==,,"v{{%99,:J:JKL  "$00|9=9I9IK$$6&&33MBB*7*<*<*@*@-+/'  ,,,S1Cs# &&((r   c                 B    |j                  d      \  }}}t        |      S )N-)rh  r   )r4   r~  r   r   s       r   __GetLastBytezUpload.__GetLastByte  s!     **3/	1c3xr   c                     | j                   y |xs | j                  }|| j                   z  r"t        j                  d| j                   z        y )Nz0Server requires chunksize to be a multiple of %d)r  r3   r   ConfigurationValueError)r4   r3   s     r   __ValidateChunksizezUpload.__ValidateChunksize  sV    **2/	t66644B//01 1 7r   c                 z    |j                   dk\  xs+ |j                   t        j                  k(  xs |j                  S )Ni  )r   r   TOO_MANY_REQUESTSretry_afterr   s     r   __IsRetryablezUpload.__IsRetryable  s<    $$+ %$$(F(FF%$$	&r   c                 ^     j                   t        k7  rt        j                  d      |xs  j                  }|xs  j
                  } j                  } fd} fd}|r|n|}|s! j                  rt        j                  d      |r j                   j                          j                           j                  s | j                  j                               }|j                  t        j                   t        j"                  fv r	d _        n3|j                  t        j                   t        j"                  t&        j(                  fvrg j                   t        k7  s j+                  |      st        j,                  j/                  |       j1                           j3                  ||        j5                   j7                  |             _         j:                  dz    j                  j                         k7  r"t        j<                  d j:                  z         j3                  ||        j                  s j$                  rt?         j                  d      r j                  j                         }	 j                  jA                  d	tB        jD                          j                  j                         }
 j                  jA                  |	       |	|
k7  r-t        jF                  d
tI        |
      tI        |	      z
  z         j3                  ||       |S )z1Helper function for StreamMedia / StreamInChunks.z"Cannot stream non-resumable uploadc                 *    j                  |       S Nr   )_Upload__SendChunkre   r   r4   s    r   CallSendChunkz+Upload.__StreamMedia.<locals>.CallSendChunk  s!    ##*< $ > >r   c                 *    j                  |       S r  )_Upload__SendMediaBodyr  s    r   CallSendMediaBodyz/Upload.__StreamMedia.<locals>.CallSendMediaBody  s!    ''*< ( > >r   z%Cannot gzip encode non-chunked uploadTr   z?Failed to transfer all bytes in chunk, upload paused at byte %dry  r   z7Upload complete with %s additional bytes left in stream)%r'  r   r   r   ry   rz   r  r  _Upload__ValidateChunksizer3   r[   r,  r5   tellr   r   r   rx  r  r   rz  _Upload__IsRetryabler   r   r(  rg   r{  rw  r  rp   CommunicationErrorhasattrry  r   SEEK_ENDrZ   r   )r4   rf   rz   r   r   r   r  r  	send_funccurrent_posend_poss   `  `       r   __StreamMediazUpload.__StreamMedia  s    ==,,2246 65t55)AT-A-A((	>	> &0M5F	d112279 9$$T^^4 -- !1!1!34H##8K8K'LL"&##NNK$7$7 22,4 4
 MM%55 ..x8$..;;HEE 002%%h9"0000:<DO}}q DKK$4$4$66 33 $./ / !!(H57 --8 ??wt{{F;++**,KKKQ,kk&&(GKK[)g% 55M\C$4467 7 	ox8r   c                 ,    | j                  |||d      S )a  Send this resumable upload in a single request.

        Args:
          callback: Progress callback function with inputs
              (http_wrapper.Response, transfer.Upload)
          finish_callback: Final callback function with inputs
              (http_wrapper.Response, transfer.Upload)
          additional_headers: Dict of headers to include with the upload
              http_wrapper.Request.

        Returns:
          http_wrapper.Response of final response.
        Fr   _Upload__StreamMediar   s       r   r   zUpload.StreamMedia  s(     !!1e " E 	Er   c                 *    | j                  |||      S )z'Send this (resumable) upload in chunks.)rf   rz   r   r  r   s       r   r   zUpload.StreamInChunks  s$     !!1 " 3 	3r   c                 B   d }t        j                  | j                  || j                  | j                  |      }|j
                  t         j                  k(  rF| j                  | j                  |            }|dz   |k7  r| j                  j                  |dz          |S )z6Request helper function for SendMediaBody & SendChunk.c                 L    | "t        j                  d| j                  z        y )Nz,Request to url %s did not return a response.)r   RequestErrorr   )r   s    r   CheckResponsez0Upload.__SendMediaRequest.<locals>.CheckResponse  s3     !--B(()* *  r   )r1   r   check_response_funcr   )r   r   rA   r1   r/   r   rz  r{  rw  r5   ry  )r4   r   r   r  r   	last_bytes         r   __SendMediaRequestzUpload.__SendMediaRequest  s    	*  ++OOW$$-I <#A#AA**00:<I1}#  Q/r   c                 F   | j                          | j                  t        j                  d      t	        j
                  | j                  | j                  |z
        }t        j                  | j                  d|      }| j                  |j                  d<   || j                  k(  rd| j                  z  }n"d|d| j                  dz
  d	| j                  }||j                  d
<   |r|j                  j                  |       | j                  || j                        S )z1Send the entire media stream in a single request.z*Total size must be known for SendMediaBodyrs  )rM   ru  r6  Content-Type
bytes */%sbytes r  r   r   rt  )r[   rq   r   rZ   r	   StreamSlicer5   r   r   rM   r  r   r   _Upload__SendMediaRequest)r4   re   r   body_streamr   range_strings         r   __SendMediaBodyzUpload.__SendMediaBody  s     ??"11<> >"..KK502 &&488,79*...'DOO#'$//9L $ 05doo6I/3@L ,8(OO""#56&&w@@r   c                    | j                          | j                  du }t        j                  | j                  d      }| j
                  rXd|j                  d<   t        j                  | j                  | j                        \  }}}||z   }| j                  |r|| _        n| j                  ft        j                  | j                  || j                        }|j                  }|j                  r|| _        |j!                  | j                        }nFt#        || j                  z   | j                        }t%        j&                  | j                  ||z
        }||_        | j*                  |j                  d<   |rd|_        | j                  d|d	|d
z
  d}	n-||k(  rd| j                  z  }	nd|d	|d
z
  d| j                  }	|	|j                  d<   |r|j                  j/                  |       | j1                  ||      S )zSend the specified chunk.Nrs  )rM   ru  r>  r?  r  rM  r  r  r   z/*r  r   rt  )r[   rq   r   r   rM   r  r   r   rG  r5   r3   r  r   BufferedStreamstream_end_positionstream_exhaustedrI  r   r	   r  r6  r  rN  r   r  )
r4   re   r   no_log_bodyr   r  read_length	exhaustedr   r  s
             r   __SendChunkzUpload.__SendChunk7  s    oo-&&488G28GOO./2=2L2LT^^3-/Ki+%C &9$'!__$ *88UDNN4K11C++$'! &**4>>:Kednn,doo>C&224;;eLK #*...' %3G!??".3S1W=LE\'$//9L 
 05cAgtOL+7(OO""#56&&w44r   )NNFNTNNF)NTF)NFNr   r:   r   r   )&rV   rh   ri   rj   r   r   r8   rk   rp   r   r   r   r   r   r,  r  r   r'  rl   rq   rC  r   rF  rE  rJ  r(  rw  r  r{  r  r  r  r   r   r  r  r  r   r   s   @r   r   r   ?  s   
 $' (; $<  AECG9=#%(   >B#6 6  JN %6 6 =A,0" "H 

 

      ?   __    ! ! " "!:+;Z4(NTB FDF>
1&
 <@:>@D :>'+E& =A*.3&A265r   r   )+rj   
__future__r   email.generator	generatorrb  email.mime.multipartmimer<  rZ  email.mime.nonmultipartnonmultipartr\  r$  r   r  r   rc   rH   	six.movesr   apitools.base.pyr   r   r   r   r	   r
   __all__r5  r   r   r   r   r   r   objectr&   r   ra  BytesGeneratorr   r   rm   r   r   <module>r     s   " 0 % ) - - 3 3 	   	  
 ! , ( ' ) ) !	 &  5
.

hM hMVl9y l9^ 77"/"@"@ ",n5Y n5r   