
                            S r SSKJr  SSKJr  SSKJs  Jr	  SSK
Js  Jr  SSKrSSKrSSKrSSKrSSKrSSKrSSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  / SQrSrSrSrS r S r!S r"S r# " S S\$5      r% " S S\%5      r&\RN                  (       a   " S S\RP                  5      r) " S S\%5      r*g)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                     SU R                   ;   a  [        SU R                   S   -  5        g[        SU R                  -  5        g)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                     [        S5        g)z-Print information about a completed download.zDownload completeNr   )unused_responser   s     r   r   r   ?   s    	
r   c                 :    [        SU R                  S   -  5        g)z(Print upload progress based on response.zSent %srangeN)r   r   )r   unused_uploads     r   r   r   D   s    	)hmmG,
,-r   c                     [        S5        g)z+Print information about a completed upload.zUpload completeNr   )r    r#   s     r   r   r   I   s    	
r   c                      \ rS rSrSr  SS jrS r\S 5       r\S 5       r	\S 5       r
\
R                  S	 5       r
\S
 5       r\R                  S 5       r\S 5       r\S 5       rS r\S 5       r\S 5       rS rS rS rS rSrg)	_TransferN   z-Generic bits common to Uploads and Downloads.Nc                     S U l         X l        XPl        Xl        S U l        SU l        X`l        [        R                  U l	        X@l
        U=(       d    SU l        g )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_streamr4   r3   httpr0   s          r   __init___Transfer.__init__R   sS     *
& BB 	*"-gr   c                     [        U 5      $ N)strr5   s    r   __repr___Transfer.__repr__c   s    4yr   c                     U R                   $ r<   )r+   r>   s    r   r7   _Transfer.close_streamf   s    """r   c                     U R                   $ r<   )r,   r>   s    r   r8   _Transfer.httpj   s    {{r   c                 @    U R                   =(       d    U R                  $ r<   )r*   r8   r>   s    r   
bytes_http_Transfer.bytes_httpn   s      -DII-r   c                     Xl         g r<   )r*   r5   values     r   rF   rG   r   s    !r   c                     U R                   $ r<   )r/   r>   s    r   r0   _Transfer.num_retriesv   s    !!!r   c                     [         R                  " U[        R                  5        US:  a  [        R
                  " S5      eXl        g )Nr   z*Cannot have negative value for num_retries)r
   	Typechecksixinteger_typesr   InvalidDataErrorr/   rI   s     r   r0   rL   z   s9    uc//019--<> >"r   c                     U R                   $ r<   )r-   r>   s    r   r6   _Transfer.stream   s    }}r   c                     U R                   $ r<   )r.   r>   s    r   url_Transfer.url   s    zzr   c                     U R                  5         U R                  c#  U=(       d    [        R                  " 5       U l        X l        g)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)EnsureUninitializedr8   r   GetHttpr,   r.   )r5   r8   rU   s      r   _Initialize_Transfer._Initialize   s4     	  "998,"6"6"8DK
r   c                 H    U R                   S L=(       a    U R                  S L$ r<   )rU   r8   r>   s    r   initialized_Transfer.initialized   s    xxt#=		(==r   c                 ,    [        U 5      R                  $ r<   )type__name__r>   s    r   
_type_name_Transfer._type_name   s    Dz"""r   c                 l    U R                   (       d#  [        R                  " SU R                  -  5      eg )NzCannot use uninitialized %sr]   r   TransferInvalidErrorrb   r>   s    r   EnsureInitialized_Transfer.EnsureInitialized   s1    11-?A A  r   c                 l    U R                   (       a#  [        R                  " SU R                  -  5      eg )NzCannot re-initialize %sre   r>   s    r   rX   _Transfer.EnsureUninitialized   s/    11)DOO;= = r   c                 \    U R                   (       a  U R                  R                  5         g g r<   )r+   r-   closer>   s    r   __del___Transfer.__del__   s     MM! r   c                 T    Ub%  [         R                  " XU 4S9R                  5         g g )N)targetargs)	threadingThreadstart)r5   callbackr   s      r   _ExecuteCallback_Transfer._ExecuteCallback   s)    Hd3CDJJL  r   )
__bytes_http__close_stream__http__num_retries__stream__urlr3   r4   r0   r2   )FNTNr)   )ra   
__module____qualname____firstlineno____doc__r9   r?   propertyr7   r8   rF   setterr0   r6   rU   rZ   r]   rb   rg   rX   rm   rv   __static_attributes__ r   r   r&   r&   N   s   7=A<=." # #   . . " " " " # #    & > > # #A
=
"Mr   r&   c                     ^  \ rS rSrSr\" \R                  \R                  \R                  \R                  45      r\" S5      rSU 4S jjr\S 5       r\S 5       r\SS j5       r\SS j5       r\  SS	 j5       r\S
 5       r\S 5       rS rS rS rSS jrSS jrSS jrSS jrSS jrS r  SS jr   SS jr!  S S jr"Sr#U =r$$ )!r      zeData for a single download.

Public attributes:
  chunksize: default chunksize to use for transfers.
r3   progress
total_sizerU   c                    > UR                  SS 5      n[        [        U ]  " U40 UD6  S U l        SU l        XPl        S U l        X l        X0l	        g )Nr   r   )
popsuperr   r9   _Download__initial_response_Download__progress_Download__total_size_Download__encodingprogress_callbackfinish_callback)r5   r6   r   r   kwdsr   	__class__s         r   r9   Download.__init__   sO    XXlD1
h&v66"&&!2.r   c                     U R                   $ r<   )r   r>   s    r   r   Download.progress       r   c                     U R                   $ r<   )r   r>   s    r   encodingDownload.encoding   r   r   c                     [         R                  R                  U5      n[         R                  R                  U5      (       a   U(       d  [        R
                  " SU-  5      eU " [        US5      4SUS.UD6$ )z-Create a new download object from a filename.z*File %s exists and overwrite not specifiedwbT)r7   r3   )ospath
expanduserexistsr   InvalidUserInputErroropen)clsfilename	overwriter3   r   r   s         r   FromFileDownload.FromFile   sr     ww!!(+77>>$	22<tCE E4d# 8$!.8268 	8r   c                     U " U4X#S.UD6$ )z+Create a new Download object from a stream.)r3   r   r   )r   r6   r3   r   r   s        r   
FromStreamDownload.FromStream   s"     6   	r   c                    [         R                  " U5      nU R                  [        UR	                  5       5      -
  nU(       a(  [
        R                  " SSR                  U5      -  5      eU R                  " U40 UD6n	Ub  XIl	        O
US   U	l	        Ub  UR                  US   5      n
OUS   n
[        U	SUS   5        [        U	SUS   5        U	R                  X:5        U	$ )	z?Create a new Download object from a stream and serialized data.,Invalid serialization data, missing keys: %s, r3   rU   r   r   r   r   )jsonloads_REQUIRED_SERIALIZATION_KEYSsetkeysr   rQ   joinr   r3   FinalizeTransferUrlsetattrrZ   )r   r6   	json_datar8   r3   clientr   r   missing_keysdownloadrU   s              r   FromDataDownload.FromData   s     zz)$77#diik:JJ-->IIl+-. . >>&1D1$%2"%)/%:H",,T%[9Cu+C/j1AB143EF	r   c                     U R                  5         U R                  U R                  U R                  U R                  S.$ )Nr   )rg   r3   r   r   rU   r>   s    r   serialization_dataDownload.serialization_data  s6     !////88	
 	
r   c                     U R                   $ r<   )r   r>   s    r   r   Download.total_size         r   c                 r    U R                   (       d  gSU R                  U R                  U R                  4-  $ )NzDownload (uninitialized)z1Download with %d/%s bytes transferred from url %sr]   r   r   rU   r>   s    r   __str__Download.__str__  s4    -BMM4??DHHF6 6 	6r   c                 b    SUR                   S'   SU R                  S-
  4-  UR                  S'   g )Nmediaaltz
bytes=0-%d   Range)query_paramsr4   headers)r5   http_requesturl_builders      r   ConfigureRequestDownload.ConfigureRequest  s5    *1  '
 )58J7L(LW%r   c                     SU;   a-  US   R                  S5      u    p#US:w  a  [        U5      U l        U R                  c  SU l        gg)z;Sets the total size based off info if possible otherwise 0.r   /*Nr   )
rpartitionintr   r   )r5   r   _totals       r   
__SetTotalDownload.__SetTotal#  sO    d"/::3?KAq|$'J!
 ??" !D #r   c                 0   U R                  5         Uc  Uc  [        R                  " S5      eU=(       d    UR                  nUb   UR	                  UR
                  5      Ul        UR
                  nU R                  (       a  U R                  S5      nU R                  USU5        [        R                  " U R                  =(       d    UU5      nUR                  U R                  ;  a  [        R                  R                  U5      eX`l        U R#                  UR$                  5        UR$                  R'                  SUR(                  5      nUb  UR	                  U5      nU R+                  X$5        U R                  (       a  U R-                  5         gg)ah  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)rX   r   	UserErrorr8   r   rU   r3   _Download__ComputeEndByte_Download__SetRangeHeaderr   MakeRequestrF   status_code_ACCEPTABLE_STATUSES	HttpErrorFromResponser   _Download__SetTotalr   getrequest_urlrZ   StreamInChunks)r5   r   r8   r   rU   end_byter   s          r   InitializeDownloadDownload.InitializeDownload0  sJ    	  "<FN&&'EFF"v{{%99,:J:JKL,,Q/H!!,8<#//'47H##4+D+DD **77AA&.#OOHMM*--##$68L8LMC,,S1C# ! r   c                    Ub  US:  a  [         R                  " SSX4-  -   5      eXR                  :  a'  [         R                  " SSXR                  4-  -   5      e[        X R                  S-
  5      nX!:  a  [         R                  " SU< SU< S	35      eX4$ US:  a  [	        SXR                  -   5      nXR                  S-
  4$ )
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   rf   r   minmax)r5   rt   ends      r   __NormalizeStartEndDownload.__NormalizeStartEndS  s    ?qy 55F(E<789 9 //) 55F/5//2JJKL L c??Q./C{ 55BEuMO O:qyAu67//A---r   c                     US:  a  SU-  UR                   S'   g Ub  X2:  a  SU-  UR                   S'   g SX#4-  UR                   S'   g )Nr   zbytes=%dr"   z	bytes=%d-zbytes=%d-%d)r   )r5   requestrt   r   s       r   __SetRangeHeaderDownload.__SetRangeHeaderh  sM    19'1E'9GOOG$[CK'2U':GOOG$'4|'CGOOG$r   c                     UnUS:  a  U R                   (       d  U$ U(       a"  XR                  -   S-
  nUb  [        XE5      nOUnU R                   (       a!  U R                   S-
  nUb  [        XE5      nU$ UnU$ )ay  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   )r   r4   r   )r5   rt   r   
use_chunksr   	alternates         r   __ComputeEndByteDownload.__ComputeEndBytep  s|    , 19T__O.2I#x3$??!+I#x3  %r   c                 "   U R                  5         [        R                  " U R                  S9nU R	                  XAUS9  Ub  UR
                  R                  U5        [        R                  " U R                  X@R                  U R                  S9$ )z/Retrieve a chunk, and return the full response.)rU   )r   )r2   retries)rg   r   RequestrU   r   r   updater   rF   r2   r0   )r5   rt   r   additional_headersr   s        r   
__GetChunkDownload.__GetChunk  sw     &&4884g#6)OO""#56''OOW$$& 	&r   c                    UR                   U R                  ;  am  UR                   [        R                  [        R                  4;   a  [
        R                  R                  U5      e[
        R                  " UR                  5      eUR                   [        R                  [        R                  4;   a   U R                  R                  [        R                  " UR                  5      5        U =R$                  UR&                  -  sl        UR(                  (       a$  SUR(                  ;   a  UR(                  S   U l        U$ UR                   [        R,                  :X  a  U R                  R                  S5        U$ ! [          a<    U R                  R                  [        R"                  " UR                  5      5         Nf = f)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_CONTENTr6   writerO   ensure_binary	TypeErrorensure_textr   r   r   r   
NO_CONTENTr5   r   s     r   __ProcessResponse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   79F AGGc                 6   U R                  5         SnU R                  b  U R                  X5      u  pgSnOUnUnU(       a  Ub  Xg::  a  U R                  XgUS9nU R	                  XgUS9nU(       d0  U R                  UR                  5        U R                  X5      u  pgSnU R                  U5      nXhR                  -  nUR                  S:X  a5  UR                  [        R                  :X  a  g[        R                  " S5      eU(       d  M  Uc  M  Xg::  a  M  gg)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)rg   r   _Download__NormalizeStartEndr   _Download__GetChunkr   r   _Download__ProcessResponser   r   r   r
  r   r  )	r5   rt   r   r  r   progress_end_normalizedr   r   r   s	            r   GetRangeDownload.GetRange  s   . 	 "'??&!%!9!9%!EH&*#HH*h.>#,,X8B - DHx:L ' NH*.%)%=%=e%I"*.'--h7H'H!#'';>>9  33KM M) +*h.>#r   c                 &    U R                  XUSS9  g)z%Stream the entire download in chunks.Tru   r   r  r   N)StreamMediar5   ru   r   r  s       r   r   Download.StreamInChunks  s     	(,>$( 	 	*r   c                 R   U=(       d    U R                   nU=(       d    U R                  nU R                  5          U R                  b  U R                  nSU l        O5U R	                  U R
                  US9nU R                  U R
                  UUS9nU R                  c  U R                  UR                  5        U R                  U5      nU R                  X5        UR                  [        R                  :X  d  U R
                  U R                  :  a  OM  U R                  X%5        g)a  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  )r   r   rg   r   r   r   r  r   r   r   r  rv   r   r   r
  )r5   ru   r   r  r   r   r   s          r   r  Download.StreamMedia  s   " 5t55)AT-A-A &&222*.'00<F 1 H??MM8'9 + ; &.--h7H!!(5$$6MMT__4! " 	o8r   )
__encoding__initial_response
__progress__total_sizer   r   NN)FT)TNNNNr<   )NT)NNTNNNT)%ra   r~   r   r   r   r   r   r
  r  r  REQUESTED_RANGE_NOT_SATISFIABLEr   r   r9   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r  r   r   r  r  r  r   r  r   __classcell__r   s   @r   r   r      sF   
 ##33	   $' (: $; 
/     8 8  
 BF 2 
 
 ! !6M"!"F.*D)V	&8 <@ 4Ml =A*.* :>8<&9 &9r   r   c                   (    \ rS rSrSrS rS r\rSrg)MultipartBytesGeneratori)  aG  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                 V    UR                   c  g U R                  UR                   5        g r<   )_payloadr  )r5   msgs     r   _handle_text$MultipartBytesGenerator._handle_text1  s!     ||#JJs||$r   c                 &    UR                  SS5      $ )Nasciisurrogateescape)encode)r5   ss     r   _encodeMultipartBytesGenerator._encode8  s    88G%677r   r   N)	ra   r~   r   r   r   r3  r:  
_writeBodyr   r   r   r   r/  r/  )  s    		%	8 "
r   r/  c                     ^  \ rS rSrSr\" S5      r    S#U 4S jjr\S 5       r	\
  S$S j5       r\
  S$S j5       r\
  S%S j5       r\S	 5       r\S
 5       r\S 5       rS r\S 5       r\R&                  S 5       r\S 5       r\R&                  S 5       rS rS rS rS rS rS rS rS&S jrS rS'S jrS r  S(S jr   S)S jr!  S)S jr"S r#S'S  jr$S'S! jr%S"r&U =r'$ )*r   i?  aw  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.
r3   	mime_typer   rU   c                    > [         [        U ]
  " U4XVXtS.UD6  SU l        S U l        X l        SU l        S U l        S U l        S U l	        Xl
        Xl        Xl        X0l        g )N)r7   r4   r3   r8   Fr   )r   r   r9   _Upload__complete_Upload__final_response_Upload__mime_type_Upload__progress!_Upload__server_chunk_granularity_Upload__strategy_Upload__total_size_Upload__gzip_encodedr   r   r   )r5   r6   r?  r   r8   r7   r4   r3   r   r   gzip_encodedr   r   s               r   r9   Upload.__init__O  sv     	fd$	<!-'	<6:	<   $$*.' *!2.$r   c                     U R                   $ r<   )rD  r>   s    r   r   Upload.progressc  r   r   c                    [         R                  R                  U5      n[         R                  R                  U5      (       d  [        R
                  " SU-  5      eU(       d4  [        R                  " U5      u  p'Uc  [        R                  " SU-  5      e[         R                  " U5      R                  nU " [        US5      U4USUUS.UD6$ )z+Create a new Upload object from a filename.zCould not find file %sz Could not guess mime type for %srbTr   r7   r3   rI  )r   r   r   r   r   NotFoundError	mimetypes
guess_typer   statst_sizer   )	r   r   r?  r3   rI  r   r   r   sizes	            r   r   Upload.FromFileg  s     ww!!(+ww~~d##**+Cd+JKK$//5LI  666=? ?wwt}$$4d#Y 64 $M ,6046 	6r   c                 P    Uc  [         R                  " S5      eU " X4USUUS.UD6$ )z)Create a new Upload object from a stream.z!No mime_type specified for streamFrO  )r   r   )r   r6   r?  r   r3   rI  r   s          r   r   Upload.FromStreamx  sF     2235 56 6 %] ,6046 	6r   c                    [         R                  " U5      nU R                  [        UR	                  5       5      -
  n	U	(       a(  [
        R                  " SSR                  U	5      -  5      eSU;   a  [
        R                  " S5      eU R                  " XS   4UR                  S5      US.UD6n
[        U[        R                  5      (       a+  UR                  5       (       d  [
        R                  " S5      eUb  XJl        O
US   U
l        Ub  UR!                  US	   5      nOUS	   n["        U
l        U
R'                  X;5        U
R)                  5         U
R+                  5         U
R                  (       a  U
R-                  5         U
$ )
zACreate a new Upload of stream from serialized json_data and http.r   r   r   z/Cannot override total_size on serialized Uploadr?  )r   rI  z6Cannot restart resumable upload on non-seekable streamr3   rU   )r   r   r   r   r   r   rQ   r   r   r   r   
isinstanceioIOBaseseekabler3   r   r   strategyrZ   RefreshResumableUploadStaterg   r   )r   r6   r   r8   r3   rI  r   r   r   r   uploadrU   s               r   r   Upload.FromData  sj    zz)$77#diik:JJ-->IIl+-. . 422AC C[(9 C+/88L+A-9C=AC fbii((1B1B22HJ J$#0 #'#8F **4;7#U#*	**,  "!!#r   c                     U R                  5         U R                  [        :w  a  [        R                  " S5      eU R
                  U R                  U R                  U R                  S.$ )Nz2Serialization only supported for resumable uploadsr>  )	rg   r^  r   r   rQ   r3   r?  r   rU   r>   s    r   r   Upload.serialization_data  s]     ==,,--DF F "////88	
 	
r   c                     U R                   $ r<   )rA  r>   s    r   completeUpload.complete  r   r   c                     U R                   $ r<   )rC  r>   s    r   r?  Upload.mime_type  s    r   c                     U R                   (       d  gSU R                  U R                  =(       d    SU R                  4-  $ )NzUpload (uninitialized)z.Upload with %d/%s bytes transferred for url %sz???r   r>   s    r   r   Upload.__str__  s9    +?MM4??3eTXXC? ? 	?r   c                     U R                   $ r<   )rF  r>   s    r   r^  Upload.strategy  r   r   c                 b    U[         [        4;  a  [        R                  " SU-  5      eXl        g )NzOInvalid value "%s" for upload strategy, must be one of "simple" or "resumable".)r   r   r   r   rF  rI   s     r   r^  rl    s7    (899&&+.3(4 5 5  r   c                     U R                   $ r<   )rG  r>   s    r   r   Upload.total_size  r   r   c                 0    U R                  5         Xl        g r<   )rX   rG  rI   s     r   r   ro    s      "!r   c                 4   UR                   c  [        U l        U R                  b  g[        nU R                  b  U R                  [        :  a  [
        nUR                  (       a  UR                  (       d  [
        nUR                  (       d  [
        nX0l        g)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^  r   _RESUMABLE_UPLOAD_THRESHOLDr   bodysimple_multipartsimple_path)r5   upload_configr   r^  s       r   __SetDefaultUploadStrategy!Upload.__SetDefaultUploadStrategy  sn     ''/)DM==$ OO'"=='H]%C%C'H(('H r   c                    U R                   (       a]  UR                  (       aL  U R                   UR                  :  a2  [        R                  " SU R                   < SUR                  < 35      e[        R
                  " UR                  U R                  5      (       d2  [        R                  " SU R                  < SUR                  < 35      eU R                  X5        U R                  [        :X  a  UR                  Ul        UR                  (       a!  SUR                  S'   U R                  U5        O SUR                  S'   U R!                  U5        U R"                  (       aZ  SUR$                  S	'   [&        R(                  " [*        R,                  " UR                  5      5      S
   R/                  5       Ul        ggUR0                  Ul        SUR                  S'   U R3                  U5        g)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)r   max_sizer   r   r
   AcceptableMimeTypeacceptr?  !_Upload__SetDefaultUploadStrategyr^  r   rv  relative_pathrt  r   "_Upload__ConfigureMultipartRequest_Upload__ConfigureMediaRequestrH  r   r   CompressStreamrO   BytesIOreadrr  "_Upload__ConfigureResumableRequest)r5   rw  r   r   s       r   r   Upload.ConfigureRequest  s    OO 6 6-"8"8822OO]%;%;=> > &&}';';T^^L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                     U R                   UR                  S'   U R                  R                  5       Ul        SUl        g)z;Configure http_request as a simple request for this upload.content-type<media body>N)r?  r   r6   r  rt  loggable_bodyr5   r   s     r   __ConfigureMediaRequestUpload.__ConfigureMediaRequest"  s3    /3~~^, KK,,.%3"r   c                    [         R                  " S5      n[        USS 5        [        R                  " UR
                  S   R                  S5      6 nUR                  UR                  5        UR                  U5        [        R                  " U R                  R                  S5      6 nSUS'   UR                  U R                  R                  5       5        UR                  U5        [        R                  " 5       n[        R                  (       a  [         nO["        R$                  nU" USS	9nUR'                  USS
9  UR)                  5       Ul        UR+                  5       nSU-  UR
                  S'   [-        U[        R.                  5      (       a  UR1                  S5      nUR                  R                  U5      nUS   R3                  S5      u  n	  n
SR5                  U	S/5      US'   UR5                  U5      Ul        g)z>Configure http_request as a multipart request for this upload.related_write_headersc                     g r<   r   r>   s    r   <lambda>4Upload.__ConfigureMultipartRequest.<locals>.<lambda>-  s    r   r  r   binaryzContent-Transfer-EncodingF)mangle_from_)unixfromzmultipart/related; boundary=%rr6  s   

s   <media body>

--N)mime_multipartMIMEMultipartr   mime_nonmultipartMIMENonMultipartr   splitset_payloadrt  attachr?  r6   r  rO   r  PY3r/  email_generator	Generatorflattengetvalueget_boundaryrZ  	text_typer8  	partitionr   r  )r5   r   msg_rootr2  fpgenerator_classgmultipart_boundarybody_componentsr   r   s              r   __ConfigureMultipartRequest"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8!3!:!:7!C&++112DE'+55g>A%llG5J+KL%7%<%<_%M"r   c                     U R                   UR                  S'   U R                  b#  [        U R                  5      UR                  S'   g g )NzX-Upload-Content-TypezX-Upload-Content-Length)r?  r   r   r=   r  s     r   __ConfigureResumableRequest"Upload.__ConfigureResumableRequestR  sE    8<45??&-0-A   )+ 'r   c                    U R                   [        :w  a  gU R                  5         [        R                  " U R
                  SSS0S9n[        R                  " U R                  USU R                  S9nU R                  U5      nUR                  [        R                  [        R                  4;   aD  SU l        U R                  U l        U R"                  R%                  U R&                  5        X l        gUR                  [        R*                  :X  aJ  Uc  SU l        OU R-                  U5      S	-   U l        U R"                  R%                  U R&                  5        g[.        R0                  R3                  U5      e)
zsTalk to the server and refresh the state of this resumable upload.

Returns:
  Response if the upload is complete.
NPUTContent-Rangez	bytes */*)rU   http_methodr   r   )redirectionsr   Tr   )r^  r   rg   r   r   rU   r   r8   r0   _GetRangeHeaderFromResponser   r   r
  CREATEDrA  r   rD  r6   seekr   rB  RESUME_INCOMPLETE_Upload__GetLastByter   r   r   )r5   refresh_requestrefresh_responserange_headers       r   r_  "Upload.RefreshResumableUploadStateX  s5    ==,, &..e$k24 (33IIQ$$& 778HI''KNN,7,?,?,A A"DO"ooDOKKT]]+ %5!))\-K-KK#"#"&"4"4\"BQ"FKKT]]+&&334DEEr   c                 l    UR                   R                  SUR                   R                  S5      5      $ )Nr   r"   )r   r   r  s     r   r  "Upload._GetRangeHeaderFromResponsez  s(    }}  (--*;*;G*DEEr   c                    U R                   c  [        R                  " S5      eUc  Uc  [        R                  " S5      eU R                   [        :w  a  gU=(       d    UR                  nUb   UR                  UR                  5      Ul        U R                  5         [        R                  " X!U R                  S9nUR                  [        R                  :w  a  [        R                  R                  U5      eUR                   R#                  S5      U l        UR                   S   nUb  UR                  U5      nU R'                  X%5        U R(                  (       a  U R+                  5       $ U$ )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   r8   r   rU   rX   r   r   r0   r   r   r
  r   r   r   r   rE  rZ   r3   r   )r5   r   r8   r   http_responserU   s         r   InitializeUploadUpload.InitializeUpload}  s=   == &&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# &&((r   c                 @    UR                  S5      u    p#[        U5      $ )N-)r  r   )r5   r  r   r   s       r   __GetLastByteUpload.__GetLastByte  s     **3/	13xr   c                     U R                   c  g U=(       d    U R                  nXR                   -  (       a#  [        R                  " SU R                   -  5      eg )Nz0Server requires chunksize to be a multiple of %d)rE  r4   r   ConfigurationValueError)r5   r4   s     r   __ValidateChunksizeUpload.__ValidateChunksize  sT    **2/	66644B//01 1 7r   c                     UR                   S:  =(       d0    UR                   [        R                  :H  =(       d    UR                  $ )Ni  )r   r   TOO_MANY_REQUESTSretry_afterr  s     r   __IsRetryableUpload.__IsRetryable  s<    $$+ %$$(F(FF%$$	&r   c                   ^ ^ T R                   [        :w  a  [        R                  " S5      eU=(       d    T R                  nU=(       d    T R
                  nT R                  nUU 4S jnUU 4S jnU(       a  UOUnU(       d'  T R                  (       a  [        R                  " S5      eU(       a  T R                  T R                  5        T R                  5         T R                  (       Gd  U" T R                  R                  5       5      nUR                  [        R                   [        R"                  4;   a	  ST l        GOBUR                  [        R                   [        R"                  [&        R(                  4;  am  T R                   [        :w  d  T R+                  U5      (       d  [        R,                  R/                  U5      eT R1                  5         T R3                  X5        GM  T R5                  T R7                  U5      5      T l        T R:                  S-   T R                  R                  5       :w  a#  [        R<                  " ST R:                  -  5      eT R3                  X5        T R                  (       d  GM  T R$                  (       a  [?        T R                  S5      (       a  T R                  R                  5       n	T R                  RA                  S	[B        RD                  5        T R                  R                  5       n
T R                  RA                  U	5        X:w  a.  [        RF                  " S
[I        U
5      [I        U	5      -
  -  5      eT R3                  X%5        U$ )z1Helper function for StreamMedia / StreamInChunks.z"Cannot stream non-resumable uploadc                 $   > TR                  U TS9$ Nr  )_Upload__SendChunkrt   r  r5   s    r   CallSendChunk+Upload.__StreamMedia.<locals>.CallSendChunk  s!    ##*< $ > >r   c                 $   > TR                  U TS9$ r  )_Upload__SendMediaBodyr  s    r   CallSendMediaBody/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 %dr  r   z7Upload complete with %s additional bytes left in stream)%r^  r   r   r   r   r   rB  rH  _Upload__ValidateChunksizer4   rg   re  r6   tellr   r   r
  r  rA  r   r  _Upload__IsRetryabler   r   r_  rv   r  r  rD  r   CommunicationErrorhasattrr  r   SEEK_ENDrf   r   )r5   ru   r   r  r   r   r  r  	send_funccurrent_posend_poss   `  `       r   __StreamMedia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8$..;;HEE 002%%h9"0000:<DO}}q DKK$4$4$66 33 $./ / !!(57 ---8 ??wt{{F;;++**,KKKQ,kk&&(GKK[)% 55M\C$4467 7 	o8r   c                 $    U R                  XUSS9$ )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  Upload.StreamMedia  s&     !!1e " E 	Er   c                 "    U R                  XUS9$ )z'Send this (resumable) upload in chunks.)ru   r   r  r  r  s       r   r   Upload.StreamInChunks  s"     !!1 " 3 	3r   c                 @   S n[         R                  " U R                  XR                  U R                  US9nUR
                  [         R                  :X  aG  U R                  U R                  U5      5      nUS-   U:w  a  U R                  R                  US-   5        U$ )z6Request helper function for SendMediaBody & SendChunk.c                 P    U c#  [         R                  " SU R                  -  5      eg )Nz,Request to url %s did not return a response.)r   RequestErrorr   )r   s    r   CheckResponse0Upload.__SendMediaRequest.<locals>.CheckResponse  s3     !--B(()* *  r   )r2   r   check_response_funcr   )r   r   rF   r2   r0   r   r  r  r  r6   r  )r5   r   r   r  r   	last_bytes         r   __SendMediaRequestUpload.__SendMediaRequest  s    	*  ++OOW$$-I <#A#AA**00:<I1}#  Q/r   c                 T   U R                  5         U R                  c  [        R                  " S5      e[        R
                  " U R                  U R                  U-
  5      n[        R                  " U R                  SUS9nU R                  UR                  S'   XR                  :X  a  SU R                  -  nO%SU< SU R                  S-
  < S	U R                  < 3nXTR                  S
'   U(       a  UR                  R                  U5        U R                  X@R                  5      $ )z1Send the entire media stream in a single request.z*Total size must be known for SendMediaBodyr  )rU   r  rt  Content-Type
bytes */%sbytes r  r   r   r  )rg   r   r   rf   r	   StreamSlicer6   r   r   rU   r?  r   r   _Upload__SendMediaRequest)r5   rt   r  body_streamr   range_strings         r   __SendMediaBodyUpload.__SendMediaBody  s     ??"11<> >"..KK502 &&488,79*...'OO#'$//9L $ 05doo6I/3@L ,8(OO""#56&&w@@r   c                 B   U R                  5         U R                  SL n[        R                  " U R                  SS9nU R
                  (       a\  SUR                  S'   [        R                  " U R                  U R                  5      u  pVnX-   nU R                  c  U(       a  Xl        OU R                  cj  [        R                  " U R                  XR                  5      nUR                  nUR                  (       a  Xl        UR!                  U R                  5      nOE[#        XR                  -   U R                  5      n[$        R&                  " U R                  X-
  5      nXTl        U R*                  UR                  S'   U(       a  SUl        U R                  c  SU< S	US
-
  < S3n	O0X:X  a  SU R                  -  n	OSU< S	US
-
  < SU R                  < 3n	XR                  S'   U(       a  UR                  R/                  U5        U R1                  XH5      $ )zSend the specified chunk.Nr  )rU   r  r}  r~  r  r  r   r  r   z/*r  r   r  )rg   r   r   r   rU   rH  r   r   r  r6   r4   rG  r   BufferedStreamstream_end_positionstream_exhaustedr  r   r	   r  rt  r?  r  r   r  )
r5   rt   r  no_log_bodyr   r  read_length	exhaustedr   r  s
             r   __SendChunkUpload.__SendChunk7  s    oo-&&488G28GOO./2=2L2LT^^3-/Ki%C &9$'!__$ *88UNN4K11C++$'! &**4>>:Kenn,doo>C&224;;LK #*...' %3G!??".3S1W=L\'$//9L 
 05cAgtOL+7(OO""#56&&w44r   )
__complete__final_response__gzip_encoded__mime_typer%  __server_chunk_granularity
__strategyr&  r   r   r^  r   )NNFNTNNF)NTF)NFNr'  r<   r)  r(  )(ra   r~   r   r   r   r   r   r9   r   r   r+  r   r   r   r   re  r?  r   r^  r   r   r  r   r  r  r  r_  r  r  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5 65r   r   )+r   
__future__r   email.generator	generatorr  email.mime.multipartmimer{  r  email.mime.nonmultipartnonmultipartr  r[  r   rQ  r   rr   rO   	six.movesr   apitools.base.pyr   r   r   r   r	   r
   __all__rs  r   r   r   r   r   r   objectr&   r   r  BytesGeneratorr/  r   r   r   r   <module>r"     s   " 0 % ) - - 3 3 	   	  
 ! , ( ' ) ) !	 &  5
.

hM hMVl9y l9^ 77"/"@"@ ",n5Y n5r   