
                        
   S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSK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rSSK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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rSS	KJ r   SS	KJ r   SS
K!J"r"  SSK#J$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SK'J/r/  SSK'J0r0  SSK'J1r1  SSK'J2r2  SSK'J3r3  SSK4J5r5  SSK6J7r7  SSK6J8r8  SSK6J9r9  SSK6J:r:  SSK6J;r;  SSK6J<r<  SSK=J>r>  SS K?J@r@  SS!KAJBrB  SS"KAJCrC  SS#KAJDrD  SS$KEJFrF  SS%KGJHrH  SS&KGJIrI  SS'KGJJrJ  SS(KGJKrK  SS)KGJLrL  SS*KMJNrN  SS+KMJOrO  SS,KPJQrQ  SS-K&JRrR  SS.KSJTrT  SS/KSJUrU  SS0KSJVrV  SS1KSJWrW  SS2KXJYrZ  SS3K[J\r\  SS4K[J]r]  SS5K^J_r_  SS6K^J`r`  SS7K^Jara  SS8K^Jbrb  SS9K^Jcrc  SS:K^Jdrd  SS;K^Jere  SS<K^Jfrf  SS=K^Jgrg  SS>K^Jhrh  SS?K^Jiri  SS@K^Jjrj  SSAKkJlrl  SSBKkJmrm  SSCKkJnrn  SSDKkJoro  SSEKpJqrq  SSFKpJrrr  SSGKpJsrs  SSHKpJtrt  SSIKpJuru  SSJKvJwrw  SSKKvJxrx  SSLKyJzrz  SSMKyJ{r{  SSNKyJ|r|  SSOK}J~r~  SSPK}Jr  SSQK}Jr  SSRK}Jr  SSSKJr  SSTKJr  SSUKJr  SSVKJr  SSWKJr  SSXKJr  SSYKJr  SSZKJr  SS[KJr  SS\KJr  SS]KJr  SS^KJr  SS_KJr  SS`KJr  SSaKJr  SSbKJr  SScKJr  SSdKJr  SSeKJr  SSfKJr  SSgKJr  SShKJr  SSiKJr  SSjKJr  SSkKJr  SSlKJr  SSmKJr  SSnKJr  SSoKJr  SSpKJr  SSqKJr  SSrKJr  SSsKJr  SStKJr  SSuKJr  SSvKJr  SSwKJr  \GR^                  (       a  \r\(       a  SSKr\" \" 5       GRf                  (       a  \lGRh                  OSSx9q\lGRl                  " 5       qSyrSzrS{rS|r/ S}Qr\" S~S5      r\" SS5      r\" SS5      rSrSr\rSrSr\" \" 5       GRf                  (       a  \lGRh                  OSSx9q\lGRl                  " 5       qSSS.r " S S\5      rS rS rSS jr\" S/ SQ5      r           SS jrS rS rS rS rS rS r SS jrS rS rS r SS jrS rS r  SS jrS r SS jr SS jr  SS jrS rS rS rS r SS jrS r SS jr  SS jr   SS jrS rS r    SS jrS rS rSS jrS r " S S\5      r SS jr  SS jr    SS jr SS jr     SS jr   SS jrSS jrS r SS jr    SS jrS\-  S\-  S\-  S.rS rS rS Gr          SS jGr " S S\5      Gr " S S\5      Gr " S S\5      Gr " S SG\5      GrS GrS GrS GrSS jGr	S Gr
g)z(Helper functions for copy functionality.    )absolute_import)print_function)division)unicode_literalsN)
namedtuple)
attrgetter)range)	protojson)config)AccessDeniedException)ArgumentException)CloudApi)EncryptionException)NotFoundException)PreconditionException)Preconditions)ResumableDownloadException)ResumableUploadAbortException)ResumableUploadException)!ResumableUploadStartOverException)ServiceException)MAX_COMPOSE_ARITY)0DEFAULT_PARALLEL_COMPOSITE_UPLOAD_COMPONENT_SIZE)+DEFAULT_PARALLEL_COMPOSITE_UPLOAD_THRESHOLD)-DEFAULT_SLICED_OBJECT_DOWNLOAD_COMPONENT_SIZE)-DEFAULT_SLICED_OBJECT_DOWNLOAD_MAX_COMPONENTS)(DEFAULT_SLICED_OBJECT_DOWNLOAD_THRESHOLD)DEFAULT_GZIP_COMPRESSION_LEVEL)ApiSelector)DaisyChainWrapper)CommandException)HashMismatchException)InvalidUrlError)FilePart)GenerateComponentObjectPrefix)ReadParallelUploadTrackerFile)$ValidateParallelCompositeTrackerData))WriteComponentToParallelUploadTrackerFile)WriteParallelUploadTrackerFile)FileProgressCallbackHandler)ProgressCallbackWithTimeout)#ResumableStreamingJsonUploadWrapper)storage_url)ContainsWildcard)GenerationFromUrlAndString)IsCloudSubdirPlaceholder)StorageUrlFromString)storage_v1_messages)FileMessage)RetryableErrorMessage)DeleteDownloadTrackerFiles)DeleteTrackerFile)ENCRYPTION_UPLOAD_TRACKER_ENTRY)GetDownloadStartByte)GetTrackerFilePath)GetUploadTrackerData)#RaiseUnwritableTrackerFileException)ReadOrCreateDownloadTrackerFile)"SERIALIZATION_UPLOAD_TRACKER_ENTRY)TrackerFileType)!WriteDownloadComponentTrackerFile)WriteJsonDataToTrackerFile)parallelism_framework_util)	stet_util)temporary_file_util)	text_util)GetJsonResumableChunkSize)GetMaxRetryDelay)GetNumRetries)ResumableThreshold)UsingCrcmodExtension)GetCloudApiInstance)GetDownloadSerializationData)DEFAULT_FILE_BUFFER_SIZE)MIN_SIZE_COMPUTE_LOGGING)UTF8)CryptoKeyType)CryptoKeyWrapperFromKey)FindMatchingCSEKInBotoConfig)GetEncryptionKeyWrapper)Base64EncodeHash)"CalculateB64EncodedMd5FromContents)CalculateHashesFromContents)CHECK_HASH_IF_FAST_ELSE_FAIL)CHECK_HASH_NEVER)ConcatCrc32c)GetDownloadHashAlgs)GetMd5)GetUploadHashAlgs)HashingFileUploadWrapper)ObjectIsGzipEncoded)
AtomicDict)$CheckMultiprocessingAvailableAndInit)PutToQueueWithTimeout)
ATIME_ATTR)ConvertDatetimeToPOSIX)GID_ATTR)	MODE_ATTR)
MTIME_ATTR)ParseAndSetPOSIXAttributes)UID_ATTR)CheckFreeSpace)GetFileSize)GetStreamFromFileUrl)
IS_WINDOWS)AddS3MarkerAclToObjectMetadata)CopyObjectMetadata)DEFAULT_CONTENT_TYPE)ObjectMetadataFromHeaders)PreconditionsFromHeaders)S3MarkerAclFromObjectMetadata)DivideAndCeil)HumanReadableToBytes)MakeHumanReadable)SECONDS_PER_DAY)TEN_MIB)CreateWildcardIterator)managerF_corruptzF/gsutil/tmp/parallel_composite_uploads/for_details_see/gsutil_help_cp/ad  
PARALLEL_UPLOAD_SALT_TO_PREVENT_COLLISIONS.
The theory is that no user will have prepended this to the front of
one of their object names and then done an MD5 hash of the name, and
then prepended PARALLEL_UPLOAD_TEMP_NAMESPACE to the front of their object
name. Note that there will be no problems with object name length since we
hash the original name.
)crc32ccustomerEncryptionetag
generationmd5Hashsize%PerformParallelUploadFileToObjectArgszfilename file_start file_length src_url dst_url canned_acl content_type storage_class tracker_file tracker_file_lock encryption_key_sha256 gzip_encoded%PerformSlicedDownloadObjectToFileArgszicomponent_num src_url src_obj_metadata_json dst_url download_file_name start_byte end_byte decryption_key!PerformSlicedDownloadReturnValueszKcomponent_num crc32c bytes_transferred component_total_size server_encodingi    GZIP_ALL_FILESi  `	l        ztext/markdownzapplication/gzip)mdtgzc                       \ rS rSrSrSrg)FileConcurrencySkipErrori+  z@Raised when skipping a file due to a concurrent, duplicate copy. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       *platform/gsutil/gslib/utils/copy_helper.pyr   r   +  s    Hr   r   c                 L    U R                   R                  [        U5      5        g)9Simple exception handler to allow post-completion status.N)loggererrorstrclses     r   _RmExceptionHandlerr   /  s    **3q6r   c                     U R                   R                  [        U5      5        U =R                  S-  sl        U R                   R	                  S[
        R                  " 5       5        g)r      z*

Encountered exception while copying:
%s
N)r   r   r   op_failure_countdebug	traceback
format_excr   s     r   _ParallelCopyExceptionHandlerr   4  sJ    **3q6!**C'')+r   c                 B   [        UR                  UR                  UR                  5      n[	        XS9nU   Sn[
        R                  " UR                  R                  UR                  R                  UR                  UR                  S9nUR                  n [        R                  (       a  [        R                   Ul        [#        UR$                  UUR                  UR                  UUUU R&                  U [(        SSSUR*                  S9n[        R                  (       a  Xtl        SSS5        WS   n	[-        UR.                  UR0                  U	U R&                  UR2                  S9  U$ ! [        R                  (       a  Xtl        f f = f! , (       d  f       Nk= f)	aA  Function argument to Apply for performing parallel composite uploads.

Args:
  cls: Calling Command class.
  args: PerformParallelUploadFileToObjectArgs tuple describing the target.
  thread_state: gsutil Cloud API instance to use for the operation.

Returns:
  StorageUrl representing a successfully uploaded component.
thread_stateN)namebucketcontentTypestorageClassFT)	gzip_extsallow_splittingis_componentgzip_encoded   encryption_key_sha256)r$   filename
file_startfile_lengthrJ   apitools_messagesObjectdst_urlobject_namebucket_namecontent_typestorage_class
prefer_apiglobal_copy_helper_opts
canned_aclr   XML_UploadFileToObjectsrc_urlr   r   r   r(   tracker_filetracker_file_lockr   )
r   argsr   fp
gsutil_apipreconditionsdst_object_metadataorig_prefer_apiret	components
             r   "_PerformParallelUploadFileToObjectr   <  s`    t0@0@A""3B*	 M ,22\\%%||''%%''	) !++O0	 	+	+ !,
 " $ 0 0 $ 3 - * #

 # =*.05-1-1->->@c 
!	+	+ /G 
J !f)+

	jj 668 
* 
!	+	+ / 
,E 
rs%   A"FA6E/F/FF
FCopyHelperOpts
perform_mv
no_clobberdaisy_chainread_args_from_stdin	print_veruse_manifestpreserve_aclr   skip_unsupported_objectstest_callback_filedest_storage_classc                 4    [        U UUUUUUUUU	U
S9q[        $ )z9Creates CopyHelperOpts for passing options to CopyHelper.r   )r   r   r   s              r   CreateCopyHelperOptsr     s8     +/7++- 
! r   c                      [         $ )z.Returns namedtuple holding CopyHelper options.)r   r   r   r   GetCopyHelperOptsr     s
     
! r   c                    SnU R                  5       (       ah  U R                  [        R                  :X  a  Sn [        R                  " U R                  5      R
                  n[        R                  " U5      (       a  SnU(       a  [        R                  R                  $ [        R                  R                  $ ! [         a     NGf = f)zGet download strategy based on the destination object.

Args:
  dst_url: Destination StorageUrl.

Returns:
  gsutil Cloud API DownloadStrategy.
FT)	IsFileUrlr   osdevnullstatst_modeS_ISCHROSErrorr   DownloadStrategyONE_SHOT	RESUMABLE)r   dst_is_specialmodes      r   _SelectDownloadStrategyr     s     .bjj(nWWW(()11d	d		 $$---$$...  
s   AB; ;
CCc                     U R                  5       (       a  U R                  5       (       a1  U R                  5       (       a,  U R                  5       (       a  U(       d  [	        SU-  5      eggg)am  Ensures the destination URL names a container.

Acceptable containers include directory, bucket, bucket
subdir, and non-existent bucket subdir.

Args:
  exp_dst_url: Wildcard-expanded destination StorageUrl.
  have_existing_dst_container: bool indicator of whether exp_dst_url
    names a container (directory, bucket, or existing bucket subdir).
  command_name: Name of command making call. May not be the same as the
      calling class's self.command_name in the case of commands implemented
      atop other commands (like mv command).

Raises:
  CommandException: if the URL being checked does not name a container.
zuDestination URL must name a directory, bucket, or bucket
subdirectory for the multiple source form of the %s command.N)r   IsDirectory
IsCloudUrlIsBucketr!   )exp_dst_urlhave_existing_dst_containercommand_names      r   InsistDstUrlNamesContainerr     sk    $ {'>'>'@'@K$8$8$:$:&
 <>JK L L ' %;r   c                 f    U(       a  gUR                  5       (       a  U =(       d    U=(       a    U$ g)a  Checks whether dst_url should be treated as a bucket "sub-directory".

The decision about whether something constitutes a bucket "sub-directory"
depends on whether there are multiple sources in this request and whether
there is an existing bucket subdirectory. For example, when running the
command:
  gsutil cp file gs://bucket/abc
if there's no existing gs://bucket/abc bucket subdirectory we should copy
file to the object gs://bucket/abc. In contrast, if
there's an existing gs://bucket/abc bucket subdirectory we should copy
file to gs://bucket/abc/file. And regardless of whether gs://bucket/abc
exists, when running the command:
  gsutil cp file1 file2 gs://bucket/abc
we should copy file1 to gs://bucket/abc/file1 (and similarly for file2).
Finally, for recursive copies, if the source is a container then we should
copy to a container as the target.  For example, when running the command:
  gsutil cp -r dir1 gs://bucket/dir2
we should copy the subtree of dir1 to gs://bucket/dir2.

Note that we don't disallow naming a bucket "sub-directory" where there's
already an object at that URL. For example it's legitimate (albeit
confusing) to have an object called gs://bucket/dir and
then run the command
gsutil cp file1 file2 gs://bucket/dir
Doing so will end up with objects gs://bucket/dir, gs://bucket/dir/file1,
and gs://bucket/dir/file2.

Args:
  have_multiple_srcs: Bool indicator of whether this is a multi-source
      operation.
  dst_url: StorageUrl to check.
  have_existing_dest_subdir: bool indicator whether dest is an existing
    subdirectory.
  src_url_names_container: bool indicator of whether the source URL
    is a container.
  recursion_requested: True if a recursive operation has been requested.

Returns:
  bool indicator.
TN)r   )have_multiple_srcsr   have_existing_dest_subdirsrc_url_names_containerrecursion_requesteds        r    _ShouldTreatDstUrlAsBucketSubDirr     s5    X  >$<)<? r   c                     U(       a  U (       a  gUR                  5       (       a  UR                  5       (       + $ U(       + =(       a    U(       + =(       a    UR                  5       $ )a\  Checks that dst_url names a single file/object after wildcard expansion.

It is possible that an object path might name a bucket sub-directory.

Args:
  src_url_names_container: Bool indicator of whether the source for the
      operation is a container (bucket, bucket subdir, or directory).
  have_multiple_srcs: Bool indicator of whether this is a multi-source
      operation.
  have_existing_dest_subdir: bool indicator whether dest is an existing
    subdirectory.
  dst_url: StorageUrl to check.
  recursion_requested: True if a recursive operation has been requested.

Returns:
  bool indicator.
F)r   r   IsObject)r   r   r   r   r   s        r   _ShouldTreatDstUrlAsSingletonr     sU    ( 4""$$$"" +D'D  r   c                 Z   U R                  5       (       d  gU R                  R                  U R                  5      nUR	                  U R                  5      u    p#U[
        R                  ;  =(       a4    U[
        R                   Vs/ s H  nU R                  S-   U-   PM     sn;  $ s  snf )a?  Returns True if not FileUrl ending in  relative path symbols.

A URL is invalid if it is a FileUrl and the parent directory of the file is a
relative path symbol. Unix will not allow a file itself to be named with a
relative path symbol, but one can be the parent. Notably, "../obj" can lead
to unexpected behavior at the copy destination. We examine the pre-recursion
"url", which might point to "..", to see if the parent is valid.

If the user does a recursive copy from a URL, it may not end up
the final parent of the copied object. For example, see: "dir/nested_dir/obj".

If you ran "cp -r dir gs://bucket" from the parent of "dir", then the "url"
arg would be "dir", but "nested_dir" would be the parent of "obj".
This actually doesn't matter since recursion won't add relative path symbols
to the path. However, we still return if "url" is valid because
there are cases where we need to copy every parent directory up to
"dir" to prevent file name conflicts.

Args:
  url: StorageUrl before recursion.

Returns:
  Boolean indicating if the "url" is valid as a parent directory.
Tz://)r   versionless_url_stringrstripdelim
rpartitionr-   RELATIVE_PATH_SYMBOLSscheme)url#url_string_minus_trailing_delimiter_after_last_delimitersymbols        r   _IsUrlValidParentDirr  3  s    2 
(+(B(B(I(I	ii)% C N N	ii!!Q 
[%F%F	F 
	#99#9f **u
v
%9# 	#s   B(c	                    UR                  5       (       a'  UR                  5       (       a  U(       a  [        S5      e[        X#XeU5      (       a  U$ UR                  5       (       aZ  UR                  5       (       d  UR	                  5       (       a0  U(       a'  UR                  5       (       a  SOSn	[        SU	-  5      eU$ U(       dp  U(       di  UR
                  R                  U R                  5      S   n
[        UR                  R                  UR                  5      < UR                  < U
< 35      $ U(       d1  U(       d*  UR                  5       (       ad  UR                  5       (       aO  UR                  R                  UR                  5      (       d%  [        UR                  < UR                  < 35      n[        U 5      nU(       d!  U(       a  [        SR                  U 5      5      eSU R                   ;  =(       a    U=(       a    U=(       d    UnU(       d1  U(       a  UR#                  5       (       d  UR                  5       (       ab  [%        X5      nUR                   ['        U5      S R)                  U R                  5      nU(       d  UR+                  U R                  5      S   nO(UR
                  R                  U R                  5      S   nUR                  5       (       d  [-        X5UX'5      (       a  UR
                  (       ac  UR
                  R                  UR                  5      (       a9  UR
                  R                  UR                  5      < UR                  < U< 3nO=UR
                  (       a  UR                  OS	nUR
                  =(       d    S	< U< U< 3nUR/                  5       nUR1                  U R                  UR                  5      Ul        U$ )
a  Constructs the destination URL for a given exp_src_url/exp_dst_url pair.

Uses context-dependent naming rules that mimic Linux cp and mv behavior.

Args:
  src_url: Source StorageUrl to be copied.
  exp_src_url: Single StorageUrl from wildcard expansion of src_url.
  src_url_names_container: True if src_url names a container (including the
      case of a wildcard-named bucket subdir (like gs://bucket/abc,
      where gs://bucket/abc/* matched some objects).
  have_multiple_srcs: True if this is a multi-source request. This can be
      true if src_url wildcard-expanded to multiple URLs or if there were
      multiple source URLs in the request.
  has_multiple_top_level_srcs: Same as have_multiple_srcs but measured
      before recursion.
  exp_dst_url: the expanded StorageUrl requested for the cp destination.
      Final written path is constructed from this plus a context-dependent
      variant of src_url.
  have_existing_dest_subdir: bool indicator whether dest is an existing
    subdirectory.
  recursion_requested: True if a recursive operation has been requested.
  preserve_posix: True if preservation of posix attributes has been requested.

Returns:
  StorageUrl to use for copy.

Raises:
  CommandException if destination object name not specified for
  source and source is a stream.
z/Cannot preserve POSIX attributes with a stream.stream
named pipez2Destination object name needed when source is a %szmPresence of multiple top-level sources and invalid expanded URL make file name conflicts possible for URL: {}z**N )r   IsStreamr!   r   IsFifor   r   r   r1   
url_stringr   r   endswithr  r#   formatr   r   GetPathBeforeFinalDirlenlstrip	partitionr   Clonereplace)r   exp_src_urlr   r   has_multiple_top_level_srcsr   r   r   preserve_posix	type_textsrc_final_compsrc_url_is_valid_parentpreserve_src_top_level_dirssrc_url_path_sans_final_dirdst_key_namer   new_exp_dst_urls                    r   ConstructDstUrlr!  [  sf   N +"6"6"8"8^
L
MM"#:#<#68 8 +"6"6"8"8"-"4"4"6"6 )2244(,i .09: ; ;	%7 !,,77FrJNK,B,B,I,I-'--~!? @ @ 4K$;$;$=$=

 
 
)
)+*;*;
<
<&((+*;*;<>K 19	 %@ 	99?J JR "&W-K-K!K "=!8"="= #<";  !%<&1&<&<&>&>&1&=&=&?&? #8"M55'()++16'--+@  '!++GMM:2>l **55gmmDRHL!A'@"4 "4 ;#:#:#C#C$ $!,!8!8!?!?


")//?l $/#:#:ke!,!8!8 "$!#"$%*L:l  %%'/ , 4 4W]]5@5F5F!H/	r   c                     0 nU (       aO  U  HI  n[         R                  " X   R                  5       5      R                  S5      R	                  S5      X'   MK     U$ )N   
ascii)base64	b64encodedigestr   decode)	digestersdigestsalgs      r   _CreateDigestsFromDigestersr,    sO    '%%
.


!##)6%= l  
.r   c                    0 nSU;   a  [        5       US'   SU;   a"  [        R                  R                  S5      US'   [	        US5       n[        UU[        UR                  [        U USS9R                  5      S9  SSS5        0 n[        R                  " U5       H   u  p[        U	R                  5       5      Xx'   M"     U$ ! , (       d  f       NL= f)	av  Creates a base64 CRC32C and/or MD5 digest from file_name.

Args:
  status_queue: Queue for posting progress messages for UI/Analytics.
  algs: List of algorithms to compute.
  file_name: File to digest.
  src_url: StorageUrl for local object. Used to track progress.
  src_obj_metadata: Metadata of source object.

Returns:
  Dict of algorithm name : base 64 encoded digest
md5rz   zcrc-32crbHashing)r   operation_name)callback_processorN)rZ   crcmod
predefinedCrcopenrU   r+   r   r*   callsix	iteritemsrS   	hexdigest)
status_queuealgs	file_namer   src_obj_metadata	hash_dictr   r*  alg_namer'  s
             r   _CreateDigestsFromLocalFilerA    s     )
d]xIe ++//	:IhIt )3N$4$9$9$?(4077@%B CG$4HI  '--	2h()9)9);<G 3	. s   
3C
Cc                 p   [         R                  " SS[        5      nU[        :X  a  gSn0 n0 nUR                  (       a$  [
        R                  " UR                  5      n	XS'   UR                  (       a$  [
        R                  " UR                  5      n
XS'   UR                  (       a$  [
        R                  " UR                  5      nXS'   UR                  (       a$  [
        R                  " UR                  5      nXS'   [
        R                  " U5       H  u  pX;  a  M  X}   n[
        R                  (       a&  [        U[        5      (       a  UR                  S5      nU R                  SXX5        X:w  a  [        U< S	U< S
U< SU< S35      eSnM     U(       d  U R                  SUU5        gg)a  Validates integrity of two cloud objects copied via daisy-chain.

Args:
  logger: for outputting log messages.
  src_url: CloudUrl for source cloud object.
  dst_url: CloudUrl for destination cloud object.
  src_obj_metadata: Cloud Object metadata for object being downloaded from.
  dst_obj_metadata: Cloud Object metadata for object being uploaded to.

Raises:
  CommandException: if cloud digests don't match local digests.
GSUtilcheck_hashesNFr.  rz   r$  z;Comparing source vs destination %s-checksum for %s. (%s/%s)z signature for source object (z+) doesn't match destination object digest (z). Object () will be deleted.Tz~WARNING: Found no hashes to validate object downloaded from %s and uploaded to %s. Integrity cannot be assured without hashes.)r   getrV   rW   r~   r8  ensure_binaryrz   r9  PY3
isinstancer   encoder   r"   warn)r   r   r   r>  dst_obj_metadatacheck_hashes_configchecked_onedownload_hashesupload_hashessrc_md5hashsrc_crc32c_hashdst_md5hashdst_crc32c_hashr+  upload_b64_digestdownload_b64_digests                   r   _CheckCloudHashesrW  .  s   & 

8^#?A,,
+/-##$4$<$<=K(E''(8(?(?@O /H##$4$<$<=K&%''(8(?(?@O-( #m <c
!).
ww:1377/66w?
LLN2G/! #%6AB B K != 
 KK	FGN 
r   c                 |   Un0 nUR                   (       a4  [        R                  " UR                   5      nUR                  S5      US'   UR                  (       a4  [        R                  " UR                  5      n	U	R                  S5      US'   Sn
U Hr  nX;  a  M
  [        R                  " Xk   5      nX{   nU R                  SUX<U5        X:w  a1  [        U< SU< SU< SU(       a  S	OS
< SU(       a  UOU< S3
5      eSn
Mt     U
(       d-  U(       a  U R                  SU5        gU R                  SU5        gg)a  Validates integrity by comparing cloud digest to local digest.

Args:
  logger: for outputting log messages.
  obj_url: CloudUrl for cloud object.
  obj_metadata: Cloud Object being downloaded from or uploaded to.
  file_name: Local file name on disk being downloaded to or uploaded from
             (used only for logging).
  digests: Computed Digests for the object.
  is_upload: If true, comparing for an uploaded object (controls logging).

Raises:
  CommandException: if cloud digests don't match local digests.
r#  r.  rz   Fz4Comparing local vs cloud %s-checksum for %s. (%s/%s)z$ signature computed for local file (z') doesn't match cloud-supplied digest (z). zCloud objectz
Local filez (rE  TzgWARNING: Found no hashes to validate object uploaded to %s. Integrity cannot be assured without hashes.ziWARNING: Found no hashes to validate object downloaded to %s. Integrity cannot be assured without hashes.N)r~   r8  rG  r   rz   r   r"   rK  )r   obj_urlobj_metadatar=  r*  	is_uploadlocal_hashescloud_hashesmd5_b64_digestcrc32c_b64_hashrN  r+  local_b64_digestcloud_b64_digests                 r   _CheckHashesrb  n  sD   : ,,&&|';';<N(//6L''(;(;<O,33E:L+c
(():;#(
LLG.>@+!  "2 5C)5*6?7Y+NPQ Q
 K  
kk89@B kk89BD 
r   c                 |    [        U [        5      =(       d&    [        U [        5      =(       a    SU R                  ;   $ )aB  Checks to see if the server attempted to clobber a file.

In this case we specified via a precondition that we didn't want the file
clobbered.

Args:
  e: The Exception that was generated by a failed copy operation

Returns:
  bool indicator - True indicates that the server did attempt to clobber
      an existing file.
412)rI  r   r   message)r   s    r   IsNoClobberServerExceptionrf    s4     a./ Ka12Iu		7ILr   c                    UR                  5       (       a  gUR                  n[        R                  R	                  U5      n[        R                  R                  U5      (       a  [        SU R                  < SU< S35      e[        R                  R                  U5      (       a  [        SU R                  < SU< S35      eg)a  Checks whether copying exp_src_url into dst_url is not possible.

   This happens if a directory exists in local file system where a file
   needs to go or vice versa. In that case we print an error message and
   exits. Example: if the file "./x" exists and you try to do:
     gsutil cp gs://mybucket/x/y .
   the request can't succeed because it requires a directory where
   the file x exists.

   Note that we don't enforce any corresponding restrictions for buckets,
   because the flat namespace semantics for buckets doesn't prohibit such
   cases the way hierarchical file systems do. For example, if a bucket
   contains an object called gs://bucket/dir and then you run the command:
     gsutil cp file1 file2 gs://bucket/dir
   you'll end up with objects gs://bucket/dir, gs://bucket/dir/file1, and
   gs://bucket/dir/file2.

Args:
  exp_src_url: Expanded source StorageUrl.
  dst_url: Destination StorageUrl.

Raises:
  CommandException: if errors encountered.
NzCannot retrieve z> because a file exists where a directory needs to be created (z).z because a directory exists (z%) where the file needs to be created.)	r   r   r   pathdirnameisfiler!   r  isdir)r  r   dst_path	final_dirs       r   CheckForDirFileConflictrn    s    2 
  (ggooh')WW^^I
'22I? @ @ WW]]8
'22H> ? ? r   c                 F   [        [        R                  " SS[        5      5      n[	        U[
        U5      u  p0 n/ n[        U5       H  n[        R                  " [        UR                  -   5      n[        5       nUR                  U5        UR                  5       nU[        -   U-   S-   [        U5      -   nUR!                  5       nUUl        UUS-
  :  a  UnO
X=S-
  U-  -
  nUU-  n[%        UR                  UUUUU XXX5      nUR'                  U5        UUU'   M     U$ )a  Partitions a file into FilePart objects to be uploaded and later composed.

These objects, when composed, will match the original file. This entails
splitting the file into parts, naming and forming a destination URL for each
part, and also providing the PerformParallelUploadFileToObjectArgs
corresponding to each part.

Args:
  canned_acl: The user-provided canned_acl, if applicable.
  content_type: content type for the component and final objects.
  dst_bucket_url: CloudUrl for the destination bucket.
  file_size: The size of fp, in bytes.
  fp: The file object to be partitioned.
  random_prefix: The randomly-generated prefix used to prevent collisions
                 among the temporary component names.
  src_url: Source FileUrl from the original command.
  storage_class: storage class for the component and final objects.
  tracker_file: The path to the parallel composite upload tracker file.
  tracker_file_lock: The lock protecting access to the tracker file.
  encryption_key_sha256: Encryption key SHA256 for use in this upload, if any.
  gzip_encoded: Whether to use gzip transport encoding for the upload.

Returns:
  dst_args: The destination URIs for the temporary component objects.
rC  (parallel_composite_upload_component_sizer  r   )rs   r   rF  r   _GetPartitionInfor   r	   r8  rG  PARALLEL_UPLOAD_STATIC_SALTr   rZ   updater:  PARALLEL_UPLOAD_TEMP_NAMESPACEr   r  r   r   append)r   r   dst_bucket_url	file_sizer   random_prefixr   r   r   r   r   r   rp  num_componentscomponent_sizedst_args
file_namesiencoded_namecontent_md5r'  temp_file_nametmp_dst_urlfile_part_lengthoffset	func_argss                             r   _PartitionFiler    sK   J .BjjEAC.D* &7"$L&N"> (* a $$%@277%JKL(K|$""$F#&DDvMF#N &&(K,KNQ' $(:n'LMF5
)7K\-I n%(H^7 !: 
/r   c                 j    [        U R                  U R                  R                  S5      S-   S 5      $ )zGets component number from component CloudUrl.

Used during parallel composite upload.

Args:
  component: CloudUrl representing component.

Returns:
  component number
r  r   N)intr   rfind)r   s    r   _GetComponentNumberr  7  s3     
Y""9#8#8#>#>s#Ca#G#HI	JJr   c                    [         R                   " 5       n[        UR                  5      nUR                  UR                  S9n[        [        5      nU(       a  UR                  OSn[        U[        R                  X5      n[        UU
5      u  nnn[        UUUUUXU
[        [        5
      u  nnUb  UR                  S5      OSnUb  UO[!        US9n[#        UUUUS9  [$        R&                  " 5       n0 n[)        UUR*                  UUU UUUR,                  UUUUS9n[/        UUX5      u  nnnU H  n[0        R2                  UR4                  4UUR6                  R8                  '   [;        UR<                  [1        UR>                  UR6                  [         R                   " 5       UR4                  S[A        UR6                  5      [0        R2                  S95        M     U H  nUS   RB                  n[0        RD                  US	   4UU'   [;        UR<                  [1        UUS   [         R                   " 5       SUS	   [A        US   5      [0        RD                  S
95        M     U HE  n[;        UR<                  [1        UU[         R                   " 5       S[0        RF                  S95        MG     URI                  [J        UU	S[L        RN                  RP                  URR                  RT                  SS9n/ nU H  nURW                  US   5        M     UU V s/ s H  n U S   PM
     sn -   n![Y        U!5      [Y        U5      :X  Ga  [[        U![@        S9n!/ n"U! Hj  n#[\        R^                  Ra                  U#Rb                  S9n$U#Re                  5       (       a  [g        U#Rh                  5      U$l4        U"RW                  U$5        Ml     URk                  U"UUUR                  / SQUS9n% U!U-   n&URI                  [        U&[        [L        RN                  RP                  URR                  RT                  S9  U! H[  nURB                  n [;        UR<                  [1        UU[         R                   " 5       S[A        U5      UU   S	   UU   S   S95        M]     U HE  n[;        UR<                  [1        UU[         R                   " 5       S[0        RF                  S95        MG     U   [u        U5        SSS5        O[w        S5      e[         R                   " 5       U-
  n'U'U%4$ s  sn f !   [;        UR<                  [1        UU[         R                   " 5       SS95         GM&  = f! [l         a4    U
Ro                  SSRq                  URs                  5       5      -   5         Nf = f! , (       d  f       N= f! U   [u        U5        SSS5        f ! , (       d  f       f = f= f)a  Uploads a local file to a cloud object using parallel composite upload.

The file is partitioned into parts, and then the parts are uploaded in
parallel, composed to form the original destination object, and deleted.

Args:
  fp: The file object to be uploaded.
  src_url: FileUrl representing the local file.
  dst_url: CloudUrl representing the destination file.
  dst_obj_metadata: apitools Object describing the destination object.
  canned_acl: The canned acl to apply to the object, if any.
  file_size: The size of the source file in bytes.
  preconditions: Cloud API Preconditions for the final object.
  gsutil_api: gsutil Cloud API instance to use.
  command_obj: Command object (for calling Apply).
  copy_exception_handler: Copy exception handler (for use in Apply).
  logger: logging.Logger for outputting log messages.
  gzip_encoded: Whether to use gzip transport encoding for the upload.

Returns:
  Elapsed upload time, uploaded Object with generation, crc32c, and size
  fields populated.
providerNr$  r   )r   r   Fr   finishedcomponent_nummessage_typer   r   )r  r   r  r  )r  r  )r   total_bytes_transferredTarg_checkerparallel_operations_overrideshould_return_resultsr   key)r   )rz   r}   r   )r   r  fieldsencryption_tuple)r  r  )r  r  r   r  )r  z:Failed to delete some of the following temporary objects:

zSSome temporary components were not uploaded successfully. Please retry this upload.)<timer1   bucket_url_stringGetApiSelectorr   rR   r   crypto_key_sha256r9   r>   PARALLEL_UPLOADr&   r'   _DeleteTempComponentObjectFnr   r(  r%   r)   rA   
CreateLockr  r   r   FilterExistingComponentsr3   COMPONENT_TO_UPLOADr   r   r  r`   r;  r   r  r   EXISTING_COMPONENTEXISTING_OBJECT_TO_DELETEApplyr   gslibcommandDummyArgCheckerParallelOverrideReasonSLICEru  r  sortedr   ComposeRequestSourceObjectsValueListEntryr   HasGenerationlongr}   ComposeObject	ExceptionrK  joinkeysr6   r!   )(r   r   r   rL  r   rw  r   r   command_objcopy_exception_handlerr   r   
start_timerv  api_selectorencryption_keywrapperr   tracker_file_nameexisting_enc_key_sha256existing_prefixexisting_componentsrx  r   components_infor{  components_to_uploadexisting_objects_to_deleter   component_str
cp_resultsuploaded_components	cp_resultr}  
componentsrequest_componentscomponent_urlr>  composed_objectobjects_to_deleteelapsed_times(                                           r   _DoParallelCompositeUploadr  E  s   F yy{*'(A(AB.**GNN*C,1&93 1BB9= 
 ))8)H)H)5@
 9&"O
 ,P0/0.*,?,A(?' 4? 177@EI &5&A?0-BD 
 !!2!.!47LN 1;;= /J,88*%)#,99--2G)57( #;$n#B, (i'')>)>5@OI%%001I%%%%IIK"..""5i6G6G"H!,!@!@	BC ( 'iaL77M&1&D&D&/l&4OM"GaLIIK""1"5il"C!,!?!?	AB	 ' .iGIIK"!,!F!F		HI .   (M--//#.#E#E#K#K  ! "* iy|, "4G%H4Gqad4G%HH*_H% 
(;<J#

*
*
F
F ,, G .  
	$	$	&	&&*=+C+C&D# 01 $ !..#/. / 0O0- %'AA
&

mm33'2'I'I'O'O  Q ")!88	K
%%'#))+#'(;I(F.}=a@'6}'Ea'HJK "" 2)##!		!%%0%J%J	L	M 2  +, 
 	$% % z),		&&c &Id	K
%%'9diikDIK K  & kk
G
))HMMO
$%&	& +, si   T *AU! AT%AU! $V"%5UU! !;VV3 VV3 "
V03W6W	W
WWc                 \   [        [        R                  " SS[        5      5      nU=(       aU    UR	                  5       (       + =(       a9    UR                  5       (       + =(       a    UR                  S:H  =(       a    U(       + nU(       ay  US:X  as  U[        :  ai  [           [        R                  S5      (       d@  U R                  SR                  [        R                  " S5      5      S-   5        S[        S'   S	S	S	5        U=(       a    US:  =(       a    XG:  $ ! , (       d  f       N'= f)
a  Determines whether parallel composite upload strategy should be used.

Args:
  logger: for outputting log messages.
  allow_splitting: If false, then this function returns false.
  src_url: FileUrl corresponding to a local file.
  dst_url: CloudUrl corresponding to destination cloud object.
  file_size: The size of the source file, in bytes.
  gsutil_api: CloudApi that may be used to check if the destination bucket
      has any metadata attributes set that would discourage us from using
      parallel composite uploads.
  canned_acl: Canned ACL to apply to destination object, if any.

Returns:
  True iff a parallel upload should be performed on the source file.
rC  #parallel_composite_upload_thresholdgsr   	suggestedr  a  ==> NOTE: You are uploading one or more large file(s), which would run significantly faster if you enable parallel composite uploads. This feature can be enabled by editing the "parallel_composite_upload_threshold" value in your .boto configuration file. However, note that if you do this large files will be uploaded as `composite objects <https://cloud.google.com/storage/docs/composite-objects>`_,which means that any user who downloads such objects will need to have a compiled crcmod installed (see "gsutil help crcmod"). This is because without a compiled crcmod, computing checksums on composite objects is so slow that gsutil disables downloads of composite objects.TN)rs   r   rF  r   r  r  r   'PARALLEL_COMPOSITE_SUGGESTION_THRESHOLDsuggested_sliced_transfers_locksuggested_sliced_transfersinfor  textwrapwrap)	r   r   r   r   rw  r   r   r  all_factors_but_sizes	            r    _ShouldDoParallelCompositeUploadr  (  s   2 )=jj@<>)?%
   
 nn
 ..D
  .  BaG::	('++K88DIIMM%&' *.. 	/ 37";/! 
)$  ;#F#J ;

:<% 
)	(s   !AD
D+c           	      V   U=(       d    [         R                  " 5       n[        U 5      (       aa  [        [	        U UUUS95      n[        U5      S:w  a  [        SU -  5      eUS   n[        UR                  5      UR                  5       (       + 4$ [        U 5      nUR                  " 5       (       a  XwR                  " 5       4$ UR                  " 5       (       a  US4$ [        U5      (       a  US4$ UR                  R                  S5      nUR!                  UR"                  USUR$                  SS/S	9n	U	 H  n
U
R&                  [(        R*                  R,                  :X  a  U
R.                  US-   :X  a  US4s  $ U
R&                  [(        R*                  R0                  :X  a-  U
R.                  R2                  UR                  S
-   :X  a  US4s  $ U
R&                  [(        R*                  R0                  :X  d  M  U
R.                  R2                  UR                  :X  d  M  US4s  $    Xs4$ )a	  Expands wildcard if present in url_str.

Args:
  url_str: String representation of requested url.
  gsutil_api: gsutil Cloud API instance to use.
  project_id: project ID to use (for iterators).
  treat_nonexistent_object_as_subdir: indicates if should treat a non-existent
      object as a subdir.
  logger: logging.Logger instance to use for output. If None, the root Logger
      will be used.

Returns:
    (exp_url, have_existing_dst_container)
    where exp_url is a StorageUrl
    and have_existing_dst_container is a bool indicating whether
    exp_url names an existing directory, bucket, or bucket subdirectory.
    In the case where we match a subdirectory AND an object, the
    object is returned.

Raises:
  CommandException: if url_str matched more than 1 URL.
)
project_idr   r   z)Destination (%s) must match exactly 1 URLr   T/prefixesz
items/name)prefix	delimiterr  r  z	_$folder$F)loggingLoggerr.   listrw   r  r!   r1   r  r   r   r   r   r0   r   r   ListObjectsr   r   datatyper   CsObjectOrPrefixTypePREFIXdataOBJECTr   )url_strr   r  "treat_nonexistent_object_as_subdirr   blr_expansionblrr-   r  list_iteratorobj_or_prefixs              r   ExpandUrlToSingleBlrr  h  s   6 %W^^%&gw)*4&,	./M
 =QH$% & &

C !0clln2DEE$W-+ 00233  k** ""))#.& (()@)@06362=2D2D1;\0J	 ) L-
 %m 	("?"?"F"FFfsl*4  

 
 H$A$A$H$H
H



!
![%<%<{%J
J 4  

 
 H$A$A$H$H
H



!
![%<%<
<5!!5 %< 	::r   c                    [         R                  " SSS5      (       d  gU R                  5       (       d  g[        U R                  5      (       a  gUS:X  a  g UR                  U R                  S/U R                  S9  g! [         a4  n[        U[        R                  R                  5      (       a  e  SnAgSnAff = f)aD  Makes a request to the destination API provider to trigger reauth.

Addresses https://github.com/GoogleCloudPlatform/gsutil/issues/1639.

If an API call occurs in a child process, the library that handles
reauth will fail. We need to make at least one API call in the main
process to allow a user to reauthorize.

For cloud source URLs this already happens because the plurality of
the source name expansion iterator is checked in the main thread. For
cloud destination URLs, only some situations result in a similar API
call. In these situations, this function exits without performing an
API call. In others, this function performs an API call to trigger
reauth.

Args:
  destination_url (StorageUrl): The destination of the transfer.
  gsutil_api (CloudApiDelegator): API to use for the GetBucket call.
  worker_count (int): If greater than 1, assume that parallel execution
    is used. Technically, reauth challenges can be answered in the main
    process, but they may be triggered multiple times if multithreading
    is used.

Returns:
  None, but performs an API call if necessary.
rC  0trigger_reauth_challenge_for_parallel_operationsFNr   location)r  r  )r   getboolr   r.   r  	GetBucketr   r   r  rI  pyu2ferrorsPluginError)destination_urlr   worker_countr   s       r   .TriggerReauthForDestinationProviderIfNecessaryr    s    : 
BE
K 
K
 
	#	#	%	%
 o0011
 Q
##| ''  ) 
 !U\\--.. /s   &A? ?
B=	*B88B=c                     U R                  5       (       aR  U R                  S:X  aB  UR                  5       (       a-  [        R                  " SSUR
                  5      n[        U5      nU$ )a  Translates Windows pathnames to cloud pathnames.

Rewrites the destination URL built by ConstructDstUrl().

Args:
  src_url: Source StorageUrl to be copied.
  dst_url: The destination StorageUrl built by ConstructDstUrl().

Returns:
  StorageUrl to use for copy.
\z\\r  )r   r   r   resubr  r1   )r   r   trans_url_strs      r   FixWindowsNamingr    sS     gmmt38J8J8L8LFF5#w'9'9:M"=1G	.r   c                 t   U R                  5       (       ak  UR                  5       (       aV  [        R                  R                  U R                  5      n[        R                  R                  UR                  5      nX#:H  $ U R
                  UR
                  :H  =(       a    U R                  UR                  :H  $ )zChecks if src_url and dst_url represent the same object or file.

We don't handle anything about hard or symbolic links.

Args:
  src_url: Source StorageUrl.
  dst_url: Destination StorageUrl.

Returns:
  Bool indicator.
)r   r   rh  normpathr   r  r}   )r   r   new_src_pathnew_dst_paths       r   
SrcDstSamer    s     W..0077##G$7$78L77##G$7$78L'''"4"44 5'"4"446r   c                    UR                  5       (       a(  U(       a!  UR                  (       a  SUR                  -  nOSnUR                  5       (       aV  UR                  5       (       d  UR	                  5       (       a,  UR                  5       (       a  SOSnU R                  SXT5        gU R                  SUR                  U5        g)a  Logs copy operation, including Content-Type if appropriate.

Args:
  logger: logger instance to use for output.
  src_url: Source StorageUrl.
  dst_url: Destination StorageUrl.
  dst_obj_metadata: Object-specific metadata that should be overidden during
                    the copy.
z [Content-Type=%s]r  z<STDIN>r	  zCopying from %s%s...zCopying %s%s...N)r   r   r   r  r  r  r  )r   r   r   rL  content_type_msgsrc_texts         r   _LogCopyOperationr  5  s     /""+.>.J.JJg..00GNN4D4D#,,..yLH
KK&C
KK!7#5#57GHr   c                 6   [        U5      n[        [        5      n[        R                  " 5       n	[	        UR
                  U USS9R                  n
[        R                  (       aQ  [        [        R                  S5       n[        R                  " UR                  5       5      R                  n
SSS5        UR                  UUU R                  [        R                  UU
UR                   ["        UUS9
n[        R                  " 5       nUR%                  5       n['        UUR                  5      Ul        [)        UR
                  [+        U UU[*        R,                  UR.                  SS95        X-
  UR.                  UUR0                  4$ ! , (       d  f       N= f)a  Performs copy-in-the cloud from specified src to dest object.

Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata for source object; must include etag and size.
  dst_url: Destination CloudUrl.
  dst_obj_metadata: Object-specific metadata that should be overidden during
                    the copy.
  preconditions: Preconditions to use for the copy.
  gsutil_api: gsutil Cloud API instance to use for the copy.
  decryption_key: Base64-encoded decryption key for the source object, if any.

Returns:
  (elapsed_time, bytes_transferred, dst_url with generation,
  md5 hash of destination) excluding overhead like initial GET.

Raises:
  CommandException: if errors encountered.
Copyingr   r   r1  r/  N)src_generationr   r   progress_callbackr  r  decryption_tupler  Tr  r   r  )rP   rR   r   r  r*   r;  r7  r   r   r6  pickleloadsread
CopyObjectr}   r   r   UPLOAD_RETURN_FIELDSr  r/   r`   r3   FILE_CLOUD_COPYr   r~   )r   r>  r   rL  r   r   decryption_keydecryption_keywrapperr  r  r  test_fpdst_objend_time
result_urls                  r   _CopyObjToObjInTheCloudr  L  sg   4 2.A1&9yy{*1*2I2I:A:AAJL MQD  //	%88$	?7 ,,w||~6;; 
@!!"2"2181C1C-D-O-O0=4E+2>>)=3H3H " 	J' YY[(}}*4Z5<5G5GI* '*::',,!" 
!1!6!6

//
 9 
@	?s   ?/F


Fc                    UR                   Gc  U R                  5       (       Ga  U R                  5       (       Gd  U R                  5       (       Gd  U R                  nSnUS:w  Ga\  [
        R                  R                  U5      n[        R                  " SSS5      (       a  [        (       d   [        R                  " SSSU/[        R                  [        R                  S	9nUR                  5       u  pgUR                  R!                  5         UR"                  R!                  5         UR$                  S
:w  d  U(       a  ['        SXER$                  U4-  5      eUR)                  5       n[*        R,                  " U5      nO@UR1                  S5      u    pU
[2        ;   a
  [2        U
   nO[4        R6                  " U5      u  p9U(       d  [8        nX1l         ggggg! [.         a  n['        SU< SU< 35      eSnAff = f)zDetects and sets Content-Type if src_url names a local file.

Args:
  src_url: Source StorageUrl.
  dst_obj_metadata: Object-specific metadata that should be overidden during
                   the copy.
N-rC  use_magicfileFfilez-bz--mime)stdoutstderrr   zAEncountered error running "file -b --mime %s" (returncode=%d).
%sz,Encountered OSError running "file -b --mime z"
.)r   r   r  r  r   r   rh  realpathr   r  rk   
subprocessPopenPIPEcommunicater   closer!  
returncoder!   r   r8  
ensure_strr   r   COMMON_EXTENSION_RULES	mimetypes
guess_typern   )r   rL  r   r   real_file_pathpoutputr   r   r  	extensions              r   _SetContentTypeFromFiler2    s    ""*w/@/@/B/B




W^^%5%5 %%KL cww''4n	/5	9	9**	#hG&0oo&0oo7! --/-&
((..

((..
\\Q%"'*8,,)NOP P  ,5, )33C81../	:,%00@/,)l#/ K &6
 0C*4  	# q"# #	#s   .CG 
G<$G77G<c                    [        UR                  U USS9R                  n[        R                  (       aQ  [        [        R                  S5       n	[        R                  " U	R                  5       5      R                  nSSS5        [        R                  " 5       n
[        [        5      nU R                  5       (       d  U R                  5       (       a4  UR                  UU[        R                  UUUUR                   ["        US9	nO4UR%                  UU[        R                  UUUUUR                   ["        US9
n[        R                  " 5       nX-
  nX4$ ! , (       d  f       N= f)a  Uploads the file using a non-resumable strategy.

This function does not support component transfers.

Args:
  src_url: Source StorageUrl to upload.
  src_obj_filestream: File pointer to uploadable bytes.
  src_obj_size (int or None): Size of the source object.
  dst_url: Destination StorageUrl for the upload.
  dst_obj_metadata: Metadata for the target object.
  preconditions: Preconditions for the upload, if any.
  gsutil_api: gsutil Cloud API instance to use for the upload.
  gzip_encoded: Whether to use gzip transport encoding for the upload.

Returns:
  Elapsed upload time, uploaded Object with generation, md5, and size fields
  populated.
	Uploadingr
  r/  N)object_metadatar   r   r  r  r  r  r   )	r5  r   r   r   r  r  r  r  r   )r*   r;  r7  r   r   r6  r  r  r  r  rR   r   r  r  UploadObjectStreamingr   r   r  UploadObject)r   src_obj_filestreamsrc_obj_sizer   rL  r   r   r   r  r  r  r  uploaded_objectr  r  s                  r   _UploadFileToObjectNonResumabler;    s<   4 2 	" #'$	  //	%88$	?7 ,,w||~6;; 
@yy{*1&97>>++ 66(*55#+.#! 7 	#O !--(*55#+.#! . 
#O YY[(&,		&&C 
@	?s   /E
E'c
                   ^^ [        U[        R                  UR                  UR                  S95      m[        [        5      n
U
(       a,  U
R                  (       a  U
R                  R                  S5      OSmUU4S jn[        TUTS9nU(       a  UR                  SU R                  5        SnU(       a  [        U5      OSn[        UR                  U UUSS	9R                  n[         R"                  (       aQ  [%        [         R"                  S
5       n[&        R(                  " UR+                  5       5      R                  nSSS5        [,        R,                  " 5       nSnU(       aT   UR/                  UU[         R0                  UUR                  UUU
[2        UUU	S9nSnU(       d  [A        T5        U(       a  MT  [,        R,                  " 5       nUU-
  nUW4$ ! , (       d  f       N= f! [4         Ga  nUR                  SU R                  -  5        US-  nU[7        5       :  nU(       d  e  UR                  SUR8                  -  5        UR;                  UR8                  UR                  S9  O! [<         a     O[>         a    e f = f[A        T5        UR                  ST< SU R                  < S35        O4! [A        T5        UR                  ST< SU R                  < S35        f = fUR                  SU R                  UU4-  5        SnURC                  S5        U(       a  [        U5      OSn[        UR                  U UUSS	9R                  n[E        UR                  [G        U[,        R,                  " 5       US95        [,        RH                  " [K        [L        RL                  " 5       SU-  -  [O        5       5      5         SnAGN1SnAf[P         a    Sne f = f! U(       d  [A        T5        f f = f)a  Uploads the file using a resumable strategy.

Args:
  src_url: Source FileUrl to upload.  Must not be a stream.
  src_obj_filestream: File pointer to uploadable bytes.
  src_obj_size (int or None): Size of the source object.
  dst_url: Destination StorageUrl for the upload.
  dst_obj_metadata: Metadata for the target object.
  preconditions: Preconditions for the upload, if any.
  gsutil_api: gsutil Cloud API instance to use for the upload.
  logger: for outputting log messages.
  is_component: indicates whether this is a single component or whole file.
  gzip_encoded: Whether to use gzip transport encoding for the upload.

Returns:
  Elapsed upload time, uploaded Object with generation, md5, and size fields
  populated.
r  r$  Nc                 L   > [         T[        [        U 5      0n[        TU5        g)a  Creates a new tracker file for starting an upload from scratch.

This function is called by the gsutil Cloud API implementation and the
the serialization data is implementation-specific.

Args:
  serialization_data: Serialization data used in resuming the upload.
N)r7   r=   r   r@   )serialization_datar  r   r  s     r   _UploadTrackerCallback<_UploadFileToObjectResumable.<locals>._UploadTrackerCallback/  s*     	()>*C0B,CD 0$7r   r   zResuming upload for %sTr4  )r   r  r   r1  r/  r   )r5  r   r   r  r   r>  r  r  tracker_callbackr  r   Fz:Caught ResumableUploadStartOverException for upload of %s.r   z8Checking that bucket %s exists before retrying upload...zDeleted tracker file z for resumable upload of z before retrying.zRestarting upload of %s from scratch (retry #%d) after exception indicating we need to start over with a new resumable upload ID: %s)num_retriesr   ))r9   r>   UPLOADr  r   rR   r   r  r(  r:   r  r  r  r*   r;  r7  r   r   r6  r  r  r  r  UploadObjectResumabler   r  r   rG   r   r  r   r   r6   seekr`   r4   sleepminrandomrF   r   )r   r8  r9  r   rL  r   r   r   r   r   r  r?  tracker_data	retryabler  r  r  r  num_startover_attemptsr:  r   r  r  r   r  s                          @@r   _UploadFileToObjectResumablerL  	  s   8 )%%8: 2&9 
#8#J#J --44W=
 
8" &7LN,
KK('*<*<=)2>%g.D-1! "
 #'$  //	%88$	?7 ,,w||~6;; 
@ yy{* 	H-"88
*,77%>>)0%1-# 9 %o ir +,S 		V YY[(J&,
	((u 
@	?8 - 3#kkN$$% &
 !)MO;iKN$++, 	--44w~~N"  	  	+,#4g6H6HJ 	K 	+,#4g6H6HJ 	K kkP!7;<= la 6B)'2m5

!
!%$&
 '+d  

!
!
 $		,BDE
 jj
fmmo$:!:; "# # ) i +, sn   /G*8G, 
G),O$78O0AI32J=3
J
=J=?J

J=0O=1K..COO' O$$O' 'O<c                     SnSnU R                  S5      nU(       a  U(       a  SnXE4$ U[        :X  d  U(       a!  [        U5      S:  a  US   U;   a	  U(       + nUnXE4$ )a  Selects how an upload should be compressed.

This is a helper function for _UploadFileToObject.

Args:
  object_name: The object name of the source FileUrl.
  is_component: indicates whether this is a single component or whole file.
  gzip_exts: List of file extensions to gzip prior to upload, if any.
             If gzip_exts is GZIP_ALL_FILES, gzip all files.
  gzip_encoded: Whether to use gzip transport encoding for the upload. Used
      in conjunction with gzip_exts for selecting which files will be
      encoded. Streaming files compressed is only supported on the JSON GCS
      API.

Returns:
  A tuple: (If the file should be gzipped locally, if the file should be gzip
  transport encoded).
Fr"  Tr   r
  )splitr   r  )r   r   r   r   zipped_filegzip_encoded_filefname_partss          r    _SelectUploadCompressionStrategyrR    sr    , +!!#&+
 l 
	'' 	^#	s;'!+B90L""K$		''r   c                    Ub  U[         :  a  UR                  SU 5        [        R                  " 5       u  pESn U R	                  5       (       d  U R                  5       (       a  [        S5      eUb)  [        U5      S[        U5      -  :  a  [        SU -  5      e[        R                  " SS[        5      n[        R                  " USUS	9nUR                  [        5      nU(       a/  UR!                  U5        UR                  [        5      nU(       a  M/  U(       a  UR#                  5         [$        R"                  " U5        UR#                  5         [$        R&                  R)                  U5      n	[        US
5      n
[+        U5      X4$ ! U(       a  UR#                  5         [$        R"                  " U5        UR#                  5         f = f)a  Compresses a to-be-uploaded local file to save bandwidth.

This is a helper function for _UploadFileToObject.

Args:
  src_url: Source FileUrl.
  src_obj_filestream: Read stream of the source file - will be consumed
    and closed.
  src_obj_size (int or None): Size of the source file.
  logger: for outputting log messages.

Returns:
  StorageUrl path to compressed file, read stream of the compressed file,
  compressed file size.
NzCompressing %s (to tmp)...zgzip compression is not currently supported on streaming uploads. Remove the compression flag or save the streamed output temporarily to a file before uploading.r   z|Inadequate temp space available to compress %s. See the CHANGING TEMP DIRECTORIES section of "gsutil help cp" for more info.rC  gzip_compression_levelwb)compresslevelr/  )rM   r  tempfilemkstempr  r  r!   rh   r  r   getintr   gzipr6  r  GZIP_CHUNK_SIZEwriter(  r   rh  getsizer1   )r   r8  r9  r   gzip_fh	gzip_pathgzip_fpcompression_levelr  	gzip_sizecompressed_filestreams              r   _ApplyZippedUploadCompressionrd    s   $ ,2J"J
KK,g6!))+7' W^^-- 45 5 ^I%>'(3|+<'<&= BDKL M M h0H&DFii	47HIG""?3D
mmD$$_5d $ mmoHHWggooi()y$/	i	(*?	JJ mmoHHWs   CF ?Gc                 d   SnSn U(       a4  U(       d-  [         R                  R                     U " 5       u  pxSSS5        O	U " 5       u  pxUR                  5         U(       a$   [        R
                  " UR                  5        Xx4$  Xx4$ ! , (       d  f       NM= f! [         a!    UR                  SUR                  5         Xx4$ f = f! UR                  5         U(       aN   [        R
                  " UR                  5        f ! [         a    UR                  SUR                  5         f f = ff = f)a  Handles setup and tear down logic for uploads.

This is a helper function for _UploadFileToObject.

Args:
  upload_delegate: Function that handles uploading the file.
  upload_url: StorageURL path to the file.
  upload_stream: Read stream of the file being uploaded. This will be closed
    after the upload.
  zipped_file: Flag for if the file is locally compressed prior to calling
    this function. If true, the local temporary file is deleted after the
    upload.
  gzip_encoded_file: Flag for if the file will be uploaded with the gzip
    transport encoding. If true, a lock is used to limit resource usage.
  parallel_composite_upload: Set to true if this upload represents a
    top-level parallel composite upload (not an upload of a component). If
    true, resource locking is skipped.
  logger: For outputting log messages.

Returns:
  The elapsed upload time, the uploaded object.
NzZCould not delete %s. This can occur in Windows because the temporary file is still locked.)	r  r  !concurrent_compressed_upload_lockr(  r   unlinkr   r  warning)	upload_delegate
upload_urlupload_streamrO  rP  parallel_composite_uploadr   r  r:  s	            r   _DelegateUploadFileToObjectrm    s+   2 ,/G !:==::(7(9% ;: '6&7#l G
		*(() 
	&&  
	&&) ;:   G./9/E/E	G 
	&&	G G
		*(()  G./9/E/E	GG sW   (C 
B	C " B 	
BC &CCD/! DD/&D+(D/*D++D/c                 v  ^^^^^^^	^^^^^ ^!^" T(       a  TR                   (       d%  [        R                  " SS5      nU(       a  UTl         U m!Um Um[        U R                  TX5      u  nmT(       a  T(       d  TR                  SU 5        OkU(       ad  [        XUT5      u  m!m mSTl        TR                  (       d  STl        O3STR                  R                  5       ;  a  T=R                  S-  sl        T(       dC  [        TR                  [        T!T[        R                  " 5       [        R                  TSS95        S	nS	n[        5       m[!        U4S
 jT=(       d    0  5       5      n[#        TUT!TUT[$        R&                  S9nTc  SOT[)        5       :  =(       d'    U R+                  5       =(       d    U R-                  5       nU R+                  5       (       d  U R-                  5       (       aA  TR/                  TR0                  S9[2        R4                  :X  a  T n[7        U[9        5       5      m U(       d   [;        T5      (       a  [=        T UTT!T5      m"OT m"UU	UUUUUUUU U!4S jnUUUUUUU!U"4S jnUUUUUUUUU!U"4
S jnU(       a  UnOU(       a  UnOUn[?        UT!T UTUT5      u  nnU(       d$   [A        U5      n[C        TTUU R                  USS9  TR]                  5       nURZ                  Ul-        [_        UURZ                  5      Ul-        T(       dC  [        TR                  [        T!T[        R                  " 5       [        R                  TSS95        UUR`                  UURb                  4$ ! [D         a    [F        (       ag  [H        RJ                  " TRL                  TRN                  URP                  S9nTR                  [R        -   Tl&        TRU                  UTTR0                  S9  TRW                  TRX                  TR                  URZ                  TR0                  S9  e f = f)aH  Uploads a local file to an object.

Args:
  src_url: Source FileUrl.
  src_obj_filestream: Read stream of the source file to be read and closed.
  src_obj_size (int or None): Size of the source file.
  dst_url: Destination CloudUrl.
  dst_obj_metadata: Metadata to be applied to the destination object.
  preconditions: Preconditions to use for the copy.
  gsutil_api: gsutil Cloud API to use for the copy.
  logger: for outputting log messages.
  command_obj: command object for use in Apply in parallel composite uploads.
  copy_exception_handler: For handling copy exceptions during Apply.
  gzip_exts: List of file extensions to gzip prior to upload, if any.
             If gzip_exts is GZIP_ALL_FILES, gzip all files.
  allow_splitting: Whether to allow the file to be split into component
                   pieces for an parallel composite upload.
  is_component: indicates whether this is a single component or whole file.
  gzip_encoded: Whether to use gzip transport encoding for the upload. Used
      in conjunction with gzip_exts for selecting which files will be
      encoded. Streaming files compressed is only supported on the JSON GCS
      API.

Returns:
  (elapsed_time, bytes_transferred, dst_url with generation,
  md5 hash of destination) excluding overhead like initial GET.

Raises:
  CommandException: if errors encountered.
rC  content_languagez+Using compressed transport encoding for %s.rZ  zno-transformz,no-transformFr  Nc              3   :   >#    U  H  oTU   " 5       4v   M     g 7fNr   .0r+  	hash_algss     r   	<genexpr>&_UploadFileToObject.<locals>.<genexpr>       Fos3)*o   )r   r   r  c                  H   > [        T	T
TT[        R                  TTTT TTTS9$ N)r   )r  r   r   )r  r  rL  r   r   rP  r   r   upload_sizerk  rj  s   r   CallParallelCompositeUpload8_UploadFileToObject.<locals>.CallParallelCompositeUpload  s;    %m&0&-&6&=&H&H&1&3&0&1&<&,3DF Fr   c                  $   > [        TTTTT TTTS9$ rz  )r;  )rL  r   r   rP  r   r{  rj  wrapped_filestreams   r   CallNonResumableUpload3_UploadFileToObject.<locals>.CallNonResumableUpload  s)    *:+=+6+2+;+8+58IK Kr   c                  (   >
 [        TT	TTT TTTTTS9
$ )N)r   r   )rL  )
rL  r   r   rP  r   r   r   r{  rj  r  s
   r   CallResumableUpload0_UploadFileToObject.<locals>.CallResumableUpload  s/    '
(:(3(/(8(5(2(.5A5F	H 	Hr   T)r[  r   r   r|   r}   r  )2contentLanguager   	get_valuerR  r   r   rd  contentEncodingcacheControllowerr`   r;  r3   r  FILE_UPLOADr[   dictr  r   r   rH   r  r  r  r   r   JSONr,   rE   r  r\   rm  r,  rb  r"   _RENAME_ON_HASH_MISMATCHr   r   r   r   r|   _RENAME_ON_HASH_MISMATCH_SUFFIXr  DeleteObjectr   r}   r  r/   r   r~   )#r   r8  r9  r   rL  r   r   r   r  r  r   r   r   r   ro  rO  r  r:  r)  rl  non_resumable_uploadorig_streamr|  r  r  delegater*  corrupted_obj_metadatar  rP  rt  r{  rk  rj  r  s#      ```````  `                @@@@@@r   r   r   E  s   X 
!1!A!A''2DE)9&*$-+#C<$B +  |
LL>H-J\6.;*J{'-$ ((&4#	/<<BBD	D##6#	JIIK!,!8!8$"	$% ,/!)Fio2oFF)>(335 !, 31.01 +4;4D4D4F+!..*  W^^--8K<L<LLK7.02M 
#s9~~ 2-2;ZQ 'F FK K
H 
H *H%H"H"=
M;8I#), 
#+I6g6"&&!#0 }}*)44*4Z5D5O5OQ* 
JIIK!,!8!8$!	#$ ,,j

!
!
# #E ! 	!	!!2!9!9!&&#** %%"' ")!4!4!@"A4.'.~~ 	 	7 g11%11)8)C)C'.~~  7 !s   =#N   B8P8c                    [         R                  R                  U R                  5      nU(       a;  [         R                  R	                  U5      (       d   [         R
                  " U5        Sn[        U5      (       a+  Sn[        R                  " U 5      nUR                  SU5        O[        R                  " U 5      n[         R                  R	                  U R                  5      (       a   [         R                  " U R                  5        [         R                  R	                  U5      (       d  [        US5      nUR!                  5         Xe4$ ! [         a*  nUR                  [        R                  :w  a  e  SnAGNSnAff = f)a  Creates a new download file, and deletes the file that will be replaced.

Names and creates a temporary file for this download. Also, if there is an
existing file at the path where this file will be placed after the download
is completed, that file will be deleted.

Args:
  dst_url: Destination FileUrl.
  src_obj_metadata: Metadata from the source object.
  logger: for outputting log messages.

Returns:
  (download_file_name, need_to_unzip)
  download_file_name: The name of the temporary file to which the object will
                      be downloaded.
  need_to_unzip: If true, a temporary zip file was used and must be
                 uncompressed as part of validation.
NFTz$Downloading to temp gzip filename %sw)r   rh  ri  r   existsmakedirsr   errnoEEXISTr]   rC   GetTempZipFileNamer  GetTempFileNamerg  r6  r(  )r   r>  r   dir_namer   need_to_unzipdownload_file_namer   s           r   _GetDownloadFiler  	  s   & WW__W001(bggnnX..kk(
 - )**M,??H
KK68JK,<<WE
 WW^^G''((IIg!!" 
*	+	+	 #	&BHHJ		**;  	
ELL	  
!s   E 
FE??Fc                 8   [        [        R                  " SS[        5      5      n[        R                  " SS[
        5      n[        R                  " SS[        5      nUR                  =(       a
    [        5       nU=(       d	    U[        :H  nU=(       aS    U [        R                  R                  L=(       a0    US:  =(       a$    U=(       a    US:  =(       a    UR                  U:  n	U	(       d  UR                  [        :  a  [        5       (       du  U[        :w  ak  [           [         R                  S5      (       d@  UR#                  SR%                  [&        R(                  " S	5      5      S-   5        S
[         S'   SSS5        U	$ U	$ ! , (       d  f       U	$ = f)al  Determines whether the sliced download strategy should be used.

Args:
  download_strategy: CloudApi download strategy.
  src_obj_metadata: Metadata from the source object.
  allow_splitting: If false, then this function returns false.
  logger: logging.Logger for log message output.

Returns:
  True iff a sliced download should be performed on the source file.
rC   sliced_object_download_threshold%sliced_object_download_max_componentsrD  r   r   r  r  z==> NOTE: You are downloading one or more large file(s), which would run significantly faster if you enabled sliced object downloads. This feature is enabled by default but requires that compiled crcmod be installed (see "gsutil help crcmod").TN)rs   r   rF  r   rY  r   rV   rz   rI   rW   r   r   r   r   r  r  r  r  r  r  r  )
download_strategyr>  r   r   r  max_componentsrM  parallel_hashinghashing_okay	use_slices
             r   _ShouldDoSlicedDownloadr  R	  sz    &:jj=9;&<" ==!H!NP. 

8^#?A%,,G1E1G!L%8<L%L, I (A(A(J(JJI!I&2I 0!3I  $$(HH	  FF

 
 %8<L%L	('++K88DIIMMKLM  	 37";/ 
) 
 
)	( 
s   #AF


Fc                 J  ^	 [        XS9n[        R                  " [        R                  UR
                  5      n[        U R                  UR                  S9m	[        U	4S jT	=(       d    0  5       5      n[        UR                  UUR                  UR                  UU R                  UUR                  UR                  UR                   UR"                  S9u  pgSnSU;   a  US   R$                  n['        UR                  UUUR                   UR                  -
  S-   U5      $ )a  Function argument to Apply for performing sliced downloads.

Args:
  cls: Calling Command class.
  args: PerformSlicedDownloadObjectToFileArgs tuple describing the target.
  thread_state: gsutil Cloud API instance to use for the operation.

Returns:
  PerformSlicedDownloadReturnValues named-tuple filled with:
  component_num: The component number for this download.
  crc32c: CRC32C hash value (integer) of the downloaded bytes.
  bytes_transferred: The number of bytes transferred, potentially less
                     than the component size if the download was resumed.
  component_total_size: The number of bytes corresponding to the whole
                     component size, potentially more than bytes_transferred
                     if the download was resumed.
r   )consider_crc32cc              3   :   >#    U  H  oTU   " 5       4v   M     g 7frq  r   rr  s     r   ru  5_PerformSlicedDownloadObjectToFile.<locals>.<genexpr>	  rw  rx  )r  
start_byteend_byter  Nrz   r   )rJ   r
   decode_messager   r   src_obj_metadata_jsonrY   r   rz   r  _DownloadObjectToFileResumabler   r   r  r  r  r  r  crcValuer   )
r   r   r   r   r>  r)  bytes_transferredserver_encoding
crc32c_valrt  s
            @r   "_PerformSlicedDownloadObjectToFiler  	  s	   $ #3B*--.?.F.F.2.H.HJ!#**2B2I2IK)Fio2oFF)*H
ll
ll
	jj&&}}((+*& *8$--J	*4+=+=z+<+/==4??+JQ+N+:
< <r   c           	      ,   U R                   (       d   eSnU R                  [        5       :  a  g[        U[        R
                  U5      nSn [        US5      n[        U5      n	XR                  :X  a  [        US5      n[        R                  " U5      n
U
S   U R                   :X  aM  U
S   U R                  :X  a:  U
S   U:X  a1   U(       a  UR                  5         U(       a  UR                  5         ggUR                  5         UR                  SUR                  -  5        U(       a  UR                  5         U(       a  UR                  5         [)        X5         [        US5       nU R                   U R                  US.n
UR+                  [        R,                  " U
5      5        SSS5        g! [        [        4 a`  n[!        U[        5      (       d  UR"                  ["        R$                  :w  a#  UR                  SU< S	['        U5      < S
35         SnANSnAff = f! U(       a  UR                  5         U(       a  UR                  5         f f = f! , (       d  f       g= f! [         a  n[/        X{R0                  5         SnAgSnAff = f)a  Maintains sliced download tracker files in order to permit resumability.

Reads or creates a sliced download tracker file representing this object
download. Upon an attempt at cross-process resumption, the contents of the
sliced download tracker file are verified to make sure a resumption is
possible and appropriate. In the case that a resumption should not be
attempted, existing component tracker files are deleted (to prevent child
processes from attempting resumption), and a new sliced download tracker
file is created.

Args:
  src_obj_metadata: Metadata from the source object. Must include etag and
                    generation.
  dst_url: Destination FileUrl.
  download_file_name: Temporary file name to be used for the download.
  logger: for outputting log messages.
  api_selector: The Cloud API implementation used.
  num_components: The number of components to perform this download with.
Nr/  rr|   r}   ry  z`Sliced download tracker file doesn't match for download of %s. Restarting download from scratch.z,Couldn't read sliced download tracker file (z): z#. Restarting download from scratch.r  )r|   r}   ry  )r|   r   rH   r9   r>   SLICED_DOWNLOADr6  ri   jsonloadr}   r(  rK  r   IOError
ValueErrorrI  r  ENOENTr   r5   r\  dumpsr;   strerror)r>  r   r  r   r  ry  r   r  r   existing_file_sizetracker_file_datar   s               r   #_MaintainSlicedDownloadTrackerFilesr  	  s6   , 
			, /11
()8)H)H)57 "	 $	'B$R 222+S1l))L1
F
#'7'<'<
<
L
)-=-H-H
H
,
-
? 
hhj  	 H''( 	) 
hhj W3	G		%"''(33*
 $567 
&	%% :	 / !Z  AGGu||$;kk$c!f. /	/ 
hhj  
&	% 
 G'(9::FFGsi   A7F2 5.F2 I* )A I)I* 2H"AHH% H""H% %1I
I'#I* 'I* *
J4JJc                   f    \ rS rSrSrS r\S 5       rS r\	R                  4S jrS rS rS	 rS
rg)SlicedDownloadFileWrapperi
  a  Wraps a file object to be used in GetObjectMedia for sliced downloads.

In order to allow resumability, the file object used by each thread in a
sliced object download should be wrapped using SlicedDownloadFileWrapper.
Passing a SlicedDownloadFileWrapper object to GetObjectMedia will allow the
download component tracker file for this component to be updated periodically,
while the downloaded bytes are normally written to file.
c                 N    Xl         X l        X0l        SU l        X@l        XPl        g)a  Initializes the SlicedDownloadFileWrapper.

Args:
  fp: The already-open file object to be used for writing in
      GetObjectMedia. Data will be written to file starting at the current
      seek position.
  tracker_file_name: The name of the tracker file for this component.
  src_obj_metadata: Metadata from the source object. Must include etag and
                    generation.
  start_byte: The first byte to be downloaded for this parallel component.
  end_byte: The last byte to be downloaded for this parallel component.
N)_orig_fp_tracker_file_name_src_obj_metadata_last_tracker_file_byte_start_byte	_end_byte)selfr   r  r>  r  r  s         r   __init__"SlicedDownloadFileWrapper.__init__
  s(     M/-#'D !Nr   c                 0    [        U R                  SS5      $ )z<Returns the mode of the underlying file descriptor, or None.r   N)getattrr  r  s    r   r   SlicedDownloadFileWrapper.mode'
  s     4==&$//r   c                    U R                   R                  5       nU R                  U::  a  U[        U5      -   U R                  S-   ::  d   e[
        R                  " U R                   U5        U R                   R                  5       n[        nU R                  b$  X R                  -
  U:  d  X R                  S-   :X  a(  [        U R                  U R                  U5        X l        g g Nr   )r  tellr  r  r  rD   write_to_fdTRACKERFILE_UPDATE_THRESHOLDr  r?   r  r  )r  r  current_file_pos	thresholds       r   r\  SlicedDownloadFileWrapper.write,
  s    }}))+ 00s4y(DNNQ,>>@ ? $--.}}))+,I$$,777)CNNQ..'(?(?(,(>(>(8: &6"	 	/r   c                 :   U[         R                  :X  a+  U R                  R                  XR                  -   S-   5        OU R                  R                  X5        U R
                  U R                  R                  5       s=::  a  U R                  S-   ::  d   e   eg r  )r   SEEK_ENDr  rE  r  r  r  )r  r  whences      r   rE  SlicedDownloadFileWrapper.seek=
  ss    
mm..0145
mm(t}}113It~~7IIIIIIr   c                 6    U R                   R                  5       $ rq  )r  r  r  s    r   r  SlicedDownloadFileWrapper.tellD
  s    ==r   c                 8    U R                   R                  5         g rq  )r  flushr  s    r   r  SlicedDownloadFileWrapper.flushG
  s    MMr   c                 \    U R                   (       a  U R                   R                  5         g g rq  )r  r(  r  s    r   r(  SlicedDownloadFileWrapper.closeJ
  s    }}
mm r   )r  r  r  r  r  r  N)r   r   r   r   r   r  propertyr   r\  r   SEEK_SETrE  r  r  r(  r   r   r   r   r  r  
  sC    * 0 06" !# J r   r  c                    [        [        R                  " SS[        5      5      n[        R                  " SS[
        5      n[        UR                  Xe5      u  px/ n	/ n
[        U5       Hs  nX-  n[        US-   U-  S-
  UR                  S-
  5      nU
R                  X-
  S-   5        [        R                  " U5      nU	R                  [        XUX#XU5      5        Mu     X4$ )a  Partitions an object into components to be downloaded.

Each component is a byte range of the object. The byte ranges
of the returned components are mutually exclusive and collectively
exhaustive. The byte ranges are inclusive at both end points.

Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata from the source object with non-pickleable
      fields removed.
  dst_url: Destination FileUrl.
  download_file_name: Temporary file name to be used for the download.
  decryption_key: Base64-encoded decryption key for the source object, if any.

Returns:
  components_to_download: A list of PerformSlicedDownloadObjectToFileArgs
                          to be used in Apply for the sliced download.
rC  %sliced_object_download_component_sizer  r   )rs   r   rF  r   rY  r   rq  r   r	   rG  ru  r
   encode_messager   )r   r>  r   r  r  sliced_download_component_sizer  ry  rz  components_to_downloadcomponent_lengthsr}  r  r  r  s                  r   _PartitionObjectr  O
  s    . $8jjB>@$A  ==!H!NP. $5^$M .  a#JAEn-13C3H3H13LMHX2Q67 &445EF!!-a:O.5.8.<	>? ! 
 	22r   c
                 >   SUl         [        XX#U5      u  p[        U
5      n[        XX5UU5        [	        US5       nUR                  UR                  5        SSS5        [        U
5       H  u  pUR                  UR                  -
  S-   n[        XUUR                  UU5      nUUR                  -
  n[        U	[        U U[        R                  " 5       USU[        R                  US95        M     UR                  [         U
U["        R$                  R&                  UR(                  R*                  SS9n[        U5      U:  a  [-        SUR.                  -  5      e[1        U[3        S	5      S
9nUS   R4                  nUb/  [7        SU5       H  n[9        UUU   R4                  X   5      nM!     Sn[;        U5      nU H  n[        U	[        U U[        R                  " 5       UR<                  SUR>                  [        R                  S95        UUR@                  -  nURB                  =(       a)    URB                  RE                  5       RG                  S5      nU(       d  M  U(       a  M  [-        SUR.                  -  5      e   UU4$ ! , (       d  f       GN<= f)a  Downloads a cloud object to a local file using sliced download.

Byte ranges are decided for each thread/process, and then the parts are
downloaded in parallel.

Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata from the source object.
  dst_url: Destination FileUrl.
  download_file_name: Temporary file name to be used for download.
  command_obj: command object for use in Apply in parallel composite uploads.
  logger: for outputting log messages.
  copy_exception_handler: For handling copy exceptions during Apply.
  api_selector: The Cloud API implementation used.
  decryption_key: Base64-encoded decryption key for the source object, if any.
  status_queue: Queue for posting file messages for UI/Analytics.

Returns:
  (bytes_transferred, crc32c)
  bytes_transferred: Number of bytes transferred from server this call.
  crc32c: a crc32c hash value (integer) for the downloaded bytes, or None if
          crc32c hashing wasn't performed.
Nr+br   F)r   r  r  r  bytes_already_downloadedTr  zSSome components of %s were not downloaded successfully. Please retry this download.r  r  r   r  rZ  zTDownload of %s failed because the server sent back data with an unexpected encoding.)$r{   r  r  r  r6  truncater   	enumerater  r  r8   r`   r3   r  COMPONENT_TO_DOWNLOADr  r  r  r  r  r  r  r!   r   r  r   rz   r	   rX   r]   component_total_sizer  r  r  r  r  )r   r>  r   r  r  r   r  r  r  r;  r  r  ry  r   r}  r   r   download_start_byter  r  rz   r  expect_gzipr  server_gzips                            r   _DoSlicedDownloadr  
  s   H )-%.>n/N+ -..%&6&8,&46
 &"KK %%& ' ""89nq	 4 44q8D./?/;/8/C/CT1N  3Y5I5IIGIIK""#!,!B!B-E	G	H :$   (--//#.#E#E#K#K  ! "* 	_~%
	&(/(;(;	<= =
 jj&AB*a=&1n%FJqM$8$8:K:NOf & #$45+iGIIK"77!"+"9"9!,!B!B	DE 444,, F,,224==fE  {;;!#*#6#678 8# * 
F	""C '&s   J
Jc                    U	c  UR                   S-
  n	X-
  S-   nUSLnUR                  U R                  S9nSnUR                  nU(       a  USU-  -  nSn [	        US5      nUR                  U5        UR                  U R                  S9n[        U5      n[        UUUUUUU5      u  nnUU:  d	  UU	S-   :  a  [        U5        [        SU-  5      eUX-   :H  nUU:g  =(       a    U(       + nU(       a  UR                  SU5        OU(       a  UR                  SU5        [        UUUR                  S	9nU(       d  U(       a  S
nUU-
  n[        U[        UR                  UU USS9R                   5      nUU:  a|  [#        [$        UU-
  5      nUR'                  U5      nUU-  nU H+  nUU   R)                  [*        R,                  " U5      5        M-     UR/                  [1        U5      5        UU:  a  M|  OU(       d  UR3                  S
5        S
n[        UR                  UUU UUSS9R                   n[4        R6                  (       aQ  [	        [4        R6                  S5       n[8        R:                  " UR'                  5       5      R                   nSSS5        U(       a&  UR                   [=        5       :  a  [?        UUUX5      n[A        U5      nU(       d  UR                  U5        URC                  U RD                  U R                  UUU	UU RF                  UR                   [H        RJ                  RL                  U R                  UUU[O        U
5      S9nU(       a  URW                  5         U	U-
  S-   n!U!U4$ ! , (       d  f       N= f! [P         a#  n URS                  SU RT                  U5        e Sn A ff = f! U(       a  URW                  5         f f = f)a5  Downloads an object to a local file using the resumable strategy.

Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata from the source object.
  dst_url: Destination FileUrl.
  download_file_name: Temporary file name to be used for download.
  gsutil_api: gsutil Cloud API instance to use for the download.
  logger: for outputting log messages.
  digesters: Digesters corresponding to the hash algorithms that will be used
             for validation.
  component_num: Which component of a sliced download this call is for, or
                 None if this is not a sliced download.
  start_byte: The first byte of a byte range for a sliced download.
  end_byte: The last byte of a byte range for a sliced download.
  decryption_key: Base64-encoded decryption key for the source object, if any.

Returns:
  (bytes_transferred, server_encoding)
  bytes_transferred: Number of bytes transferred from server this call.
  server_encoding: Content-encoding string if it was detected that the server
                   sent encoded bytes during transfer, None otherwise.
Nr   r  z component %dr  zResumable download start point for %s is not in the correct byte range. Deleting tracker file, so if you re-try this download it will start from scratchzResuming download for %szRDownload already complete for %s, skipping download but will run integrity checks.)progressuser_projectr   r0  )r  r   r   r1  Downloading)r  override_total_sizer   r   r  r1  r/  )r  r  compressed_encodingr}   object_sizer  r  r>  r)  r  r  z:Caught ResumableDownloadException (%s) for download of %s.),r   r  r   r   r6  rE  ri   r<   r6   r!   r  rK   r  r+   r*   r;  r7  rG  rL   r  rs  r8  rG  Progressr  r  r   r   r  r  rH   r  r]   GetObjectMediar   r}   r   r   r   rP   r   rh  reasonr(  )"r   r>  r   r  r   r   r)  r  r  r  r  download_size	is_slicedr  r  download_namer   r  r  r  download_completeresumingr>  bytes_digestedtotal_bytes_to_digesthash_callbackbytes_to_readr  r@  r  r  r  r   r  s"                                     r   r  r  
  s   D $$q(H'!+-4')**GNN*C,/ %%-_}44M"s	 %	(BGGJ,,gnn,EL$R-L.** Z'+>A+M)*$&345 5
 -
0JJ#z1L;L7LHkk,m<	kk'(57 6$,,.
 $n1J>1

%j&=&=4A.5.55>	@ AEFm 2241NBDww}%-'!H
H

$
$S%6%6t%<
= "s4y) 22 kk!n3)#$& '+d  11'::DAW"LL8== B %**.@.BB$R):<L%/;b ..>? gg!""11






(1''&++$55??>>/-2>B 2 Do* 
hhj!44q8	O	++U BAB 
$ 

NNO88],	

 
hhj 
sE   FN 8A-N %/M>CN >
NN 
N<N77N<<N? ?Oc                    Sn [        US5      n[        USUR                  S9n[        UR                  U USS9R
                  n	[        R                  (       aQ  [        [        R                  S5       n
[        R                  " U
R                  5       5      R
                  n	SSS5        UR                  U R                  U R                  UU R                  UR                  [         R"                  R$                  U R&                  UUU	[)        U5      S9nU(       a  UR+                  5         UR                  U4$ ! , (       d  f       N= f! U(       a  UR+                  5         f f = f)	a>  Downloads an object to a local file using the non-resumable strategy.

This function does not support component transfers.
Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata from the source object.
  dst_url: Destination FileUrl.
  download_file_name: Temporary file name to be used for download.
  gsutil_api: gsutil Cloud API instance to use for the download.
  digesters: Digesters corresponding to the hash algorithms that will be used
             for validation.
  decryption_key: Base64-encoded decryption key for the source object, if any.

Returns:
  (bytes_transferred, server_encoding)
  bytes_transferred: Number of bytes transferred from server this call.
  server_encoding: Content-encoding string if it was detected that the server
                   sent encoded bytes during transfer, None otherwise.
Nr  r   )r  r   r
  r/  )r}   r  r  r  r>  r)  r  r  )r6  rK   r  r*   r;  r7  r   r   r  r  r  r  r   r   r}   r   r   r   r   r   rP   r(  )r   r>  r   r  r   r)  r  r   r>  r  r  r  s               r   !_DownloadObjectToFileNonResumabler    s@   4 " 	 #	&B 6!**A*AC 4$	& '+d	  11'::DAW"LL8== B !//
%%$))"33<<-+0@ 0 BO 
hhj				//' BA  
hhj 
s%   A0E 4/D<#A4E <
E
E E'c                   ^ UR                   R                  UR                  5      (       aY  UR                  SR	                  [
        R                  " SUR                   -  5      5      5        [        SUR                   -  5      eUR                  U R                  S9n[        U5      n[        XXt5      n[        UX5      u  nn[           [        R                  US5      (       a  [         eS[        U'   SSS5        UR"                  =(       a    U(       + n[%        UUUR&                  S9m[)        U4S	 jT=(       d    0  5       5      nSnUR*                  S
:H  nS
n[,        R,                  " 5       nU(       d  U(       a0  [/        U UUUUUUUUUR0                  S9
u  nnSU;   a
  UUS   l        OtU[4        R6                  R8                  L a  [;        U UUUUUUS9u  nnODU[4        R6                  R<                  L a  [?        U UUUUUUUS9u  nnO[A        SU< SU< 35      e[,        R,                  " 5       nU=(       a    URC                  5       R                  S5      n[E        UU UUUUUTUUUUU	U
US9n[           [        RG                  U5        SSS5        [I        UR0                  [K        U UU[J        RL                  UR*                  SS95        UU-
  UUU4$ ! , (       d  f       GN= f! , (       d  f       Nc= f)a  Downloads an object to a local file.

Args:
  src_url: Source CloudUrl.
  src_obj_metadata: Metadata from the source object.
  dst_url: Destination FileUrl.
  gsutil_api: gsutil Cloud API instance to use for the download.
  logger: for outputting log messages.
  command_obj: command object for use in Apply in sliced downloads.
  copy_exception_handler: For handling copy exceptions during Apply.
  allow_splitting: Whether or not to allow sliced download.
  decryption_key: Base64-encoded decryption key for the source object, if any.
  is_rsync: Whether or not the caller is the rsync command.
  preserve_posix: Whether or not to preserve POSIX attributes.
  use_stet: Decrypt downloaded file with STET binary if available on system.

Returns:
  (elapsed_time, bytes_transferred, dst_url, md5), where time elapsed
  excludes initial GET.

Raises:
  FileConcurrencySkipError: if this download is already in progress.
  CommandException: if other errors encountered.
r  zSkipping attempt to download to filename ending with slash (%s). This typically happens when using gsutil to download from a subdirectory created by the Cloud Console (https://cloud.google.com/console)zInvalid destination path: %sr  FTN)consider_md5r  c              3   :   >#    U  H  oTU   " 5       4v   M     g 7frq  r   rr  s     r   ru  (_DownloadObjectToFile.<locals>.<genexpr>#  rw  rx  r   )r  r;  rz   r  zInvalid download strategy z chosen forfile rZ  )is_rsyncr  use_stet)message_timer  r   r  )'r   r  r   rK  r  r  r  r#   r  r   r   r  r  open_files_lockopen_files_maprF  r   r~   rY   rz   r  r   r  r  r;  r  r   r   r   r  r   r  r!   r  _ValidateAndCompleteDownloaddeleter`   r3   FILE_DOWNLOAD)r   r>  r   r   r   r  r  r   r  r  r  r  r  r  sliced_downloadr  r  r  r)  r  r
  r  r  rz   r  r  	local_md5rt  s                              @r   _DownloadObjectToFiler!    s    J !!'--00
KK		N  	!" # 87;N;NN
OO**GNN*C,-g6+,=,;E/ '7w7G'Q#m ,e44$$)-N%&  "))A/.A,!&/;2B2I2IK) Fio2oFF) /',,1yy{*	#G$4$+$6$/$*$:$03A1;1H1H	J 
Y	'-	($	h77@@	@+L





',( 
h77AA	A+I






'	,( /1CE F F YY[(LO$9$9$;$D$DV$L+*6+2+;+2+8+6+4+4+=+7+<+54<:H4<>)  ,-  ''*88',,!" Z
!2GY	GGs Z s   
+K>K1
K.1
K?c                    UR                   nSnU H  nUU   (       a  M  Sn  O   U(       a  [        U5      nO[        UR                  XxX5      nSnSn [	        XX/U5        [        X95        U(       d
  U(       d  UnO[        R                   " U5      nU
["        :  a  U R%                  SU5        Sn [&        R(                  " US5      n[)        US5       nUR+                  [,        5      nU(       a/  UR/                  U5        UR+                  [,        5      nU(       a  M/  SSS5        U(       a  UR5                  5         [        R                  " U5        U(       d1   [        UR                  UUX5      n[	        XX/U5        [        X95        U(       a  [6        R8                  " XUU 5        [        R                  " UU5        [;        UUUUS
9  SU;   a  US   $ g! [         a  nU(       a  U R                  S5        Sn SnAGNU	[        R                  :X  a  U R                  S5        UnSn SnAGN[        X95        [        (       a  [        R                  " UU[        -   5        e [        R                  " U5        e SnAff = f! , (       d  f       GNo= f! [0         a#  nS	[3        U5      ;   a	  U(       a  Ue SnAGNSnAff = f! U(       a  UR5                  5         f f = f! [         aM    [        X95        [        (       a  [        R                  " UU[        -   5        e [        R                  " U5        e f = f)a  Validates and performs necessary operations on a downloaded file.

Validates the integrity of the downloaded file using hash_algs. If the file
was compressed (temporarily), the file will be decompressed. Then, if the
integrity of the file was successfully validated, the file will be moved
from its temporary download location to its permanent location on disk.

Args:
  logger: For outputting log messages.
  src_url: StorageUrl for the source object.
  src_obj_metadata: Metadata for the source object, potentially containing
                    hash values.
  dst_url: StorageUrl describing the destination file.
  need_to_unzip: If true, a temporary zip file was used and must be
                 uncompressed as part of validation.
  server_gzip: If true, the server gzipped the bytes (regardless of whether
               the object metadata claimed it was gzipped).
  digesters: dict of {string, hash digester} that contains up-to-date digests
             computed during the download. If a digester for a particular
             algorithm is None, an up-to-date digest is not available and the
             hash must be recomputed from the local file.
  hash_algs: dict of {string, hash algorithm} that can be used if digesters
             don't have up-to-date digests.
  temporary_file_name: Temporary file name that was used for download.
  api_selector: The Cloud API implementation used (used tracker file naming).
  bytes_transferred: Number of bytes downloaded (used for logging).
  gsutil_api: Cloud API to use for service and status.
  is_rsync: Whether or not the caller is the rsync function. Used to determine
            if timeCreated should be used.
  preserve_posix: Whether or not to preserve the posix attributes.
  use_stet: If True, attempt to decrypt downloaded files with the STET
            binary if it's present on the system.

Returns:
  An MD5 of the local file, if one was calculated as part of the integrity
  check.
TFNzDHash did not match but server gzipped the content, will recalculate.zMHash did not match but server may have gzipped the content, will recalculate.z/Uncompressing temporarily gzipped file to %s...r/  rU  zNot a gzipped filer  r  r.  )r   r,  rA  r;  rb  r5   r"   r   r   r   r  r   renamer  rg  rC   r  rv   r  rZ  r6  r  r[  r\  r  r   r(  rB   decrypt_downloadrf   )r   r   r>  r   r  r  r)  rt  temporary_file_namer  r  r   r  r  r  final_file_namedigesters_succeededr+  r\  digest_verifiedhash_invalid_exceptionr   unzipped_temporary_file_namer`  f_outr  s                             r   r  r  u  s   h ''/c S>>!  .y9L.z/F/F/8/6JL /"2w52 ;#6  $7#F#Fw#O  7"kkC!# G 		-t4g,d3u||O,
++d
o.$ d 4 
II!"	01H1H1:1M18Ll 6$4! 7 w1M%' ))(/:_-&.,:<
 l u 
  ll " #o		(ll  !o 7	!	!
		%!$CC	E  			%&-R 43
  % 
Q	',B %$% 
 
 !  7	!	!
		((+JJ	L
  			./s   G 3#J A
J
"J 0K) 
J'J)J6AJJ

JJ K J 
K	&K>K K		K K&)AM c                    [        U 5      n[        R                  R                  UR                  5      nU(       a   [        R
                  " U5        [        UR                  S5       n[        R                  " 5       n[        R                  " XG5        SSS5        U R                  5       (       d  UR                  5         [        R                  " 5       n	[        U[!        U UU	[         R"                  U(       a  UR$                  OSSS95        U	W-
  [        R                  R'                  UR                  5      US4$ ! [         a*  nUR                  [        R                  :w  a  e  SnAGNSnAff = f! , (       d  f       N= f)ak  Copies a local file to a local file.

Args:
  src_url: Source FileUrl.
  dst_url: Destination FileUrl.
  status_queue: Queue for posting file messages for UI/Analytics.
  src_obj_metadata: An apitools Object that may contain file size, or None.

Returns:
  (elapsed_time, bytes_transferred, dst_url, md5=None).

Raises:
  CommandException: if errors encountered.
NrU  Tr  )rj   r   rh  ri  r   r  r   r  r  r6  r  shutilcopyfileobjr  r(  r`   r3   FILE_LOCAL_COPYr   r]  )
r   r   r;  r>  src_fpr  r   dst_fpr  r  s
             r   _CopyFileToFiler3    s'     (&WW__W001(kk(
 G&&J
v& ' 
				
LLNYY[('*::0@',,d!" Z
1D1D!Ew

 '  	
ELL	  
! '&s#   E  ),E7 
E4
E//E47
Fc                     g rq  r   )r  s    r   _DummyTrackerCallbackr5  K  s    r   c                 f   [         R                  (       a%  U R                  UR                  :w  a  [        S5      e[         R                  (       d  / Ul        Sn[         R
                  (       aQ  [        [         R
                  S5       n	[        R                  " U	R                  5       5      R                  nSSS5        [        U5      n
[        [        5      n[        R                  " 5       n[        U UR                   UU
UUS9nSnUR                   S:X  a=  UR#                  UU[         R$                  UUR                  [&        UR                   US9nO`UR)                  UU[         R$                  UUR                  [&        UR                   [+        UR,                  U USS9R                  [.        US	9
n[        R                  " 5       n [1        X`X!U5        URO                  5       n[Q        UURL                  5      Ul&        [S        UR,                  [U        U UU[T        RV                  UR                   SS95        X-
  UR                   UURX                  4$ ! , (       d  f       GN= f! [2         a    [4        (       at  [6        R8                  " UR:                  UR<                  UR>                  S
9nUR@                  [B        -   Ul        [E        U5      nURG                  UUUR                  UUS9  URI                  URJ                  UR@                  URL                  UR                  S9  e f = f)a  Copies from src_url to dst_url in "daisy chain" mode.

See -D OPTION documentation about what daisy chain mode is.

Args:
  src_url: Source CloudUrl
  src_obj_metadata: Metadata from source object
  dst_url: Destination CloudUrl
  dst_obj_metadata: Object-specific metadata that should be overidden during
                    the copy.
  preconditions: Preconditions to use for the copy.
  gsutil_api: gsutil Cloud API to use for the copy.
  logger: For outputting log messages.
  decryption_key: Base64-encoded decryption key for the source object, if any.

Returns:
  (elapsed_time, bytes_transferred, dst_url with generation,
  md5 hash of destination) excluding overhead like initial GET.

Raises:
  CommandException: if errors encountered.
z"Cross-provider cp -p not supportedNr/  )r  r  r  r   )r5  r   r   r  r  r   r  r4  r
  )	r5  r   r   r  r  r   r  rA  r  r  )r  r  r  r  Tr  )-r   r   r   NotImplementedErroraclr   r6  r  r  r  r7  r]   rR   r   r  r    r   r7  r   r  rD  r*   r;  r5  rW  r"   r  r   r   r   r   r|   r   r  rP   r  r  r   r}   r  r/   r`   r3   FILE_DAISY_COPYr~   )r   r>  r   rL  r   r   r   r  r  r  r  r  r  	upload_fpr:  r  r  r  r  s                      r   _CopyObjToObjDaisyChainModer;  P  s   @ **nn&
B
CC	 	-	- //	%88$	?7 ,,w||~6;; 
@ ,,<=1&9yy{* 0 5 5 *4G2C/=?) /a --(*55##"". . 0O !66(*55##""5##&	( )-.. 7 0O YY[(
fw%'. }}*4Z5D5O5OQ* '*::',,!" 
!1!6!6


!
!
# #i 
@	?d 
 
077$$!((## %  '22> ?5nE2,%,^^-B-B	  D G//#//'6'A'A%,^^  5 
'
s   /II+ 
I(+CL0c                    [        5       nU (       aF  UR                  / SQ5        U(       a  UR                  S/5        U(       d  UR                  S/5        OvUR                  / SQ5        U(       a  UR                  S[        -  S/5        U(       a;  S[        -  S[        -  S[        -  S[
        -  S[        -  /nUR                  U5        U(       a  UR                  SS/5        U(       a  UR                  S/5        [        U5      $ )a  Determines the metadata fields needed for a copy operation.

This function returns the fields we will need to successfully copy any
cloud objects that might be iterated. By determining this prior to iteration,
the cp command can request this metadata directly from the iterator's
get/list calls, avoiding the need for a separate get metadata HTTP call for
each iterated result. As a trade-off, filtering objects at the leaf nodes of
the iteration (based on a remaining wildcard) is more expensive. This is
because more metadata will be requested when object name is all that is
required for filtering.

The rsync command favors fast listing and comparison, and makes the opposite
trade-off, optimizing for the low-delta case by making per-object get
metadata HTTP call so that listing can return minimal metadata. It uses
this function to determine what is needed for get metadata HTTP calls.

Args:
  dst_is_cloud: if true, destination is a Cloud URL.
  skip_unsupported_objects: if true, get metadata for skipping unsupported
      object types.
  preserve_acl: if true, get object ACL.
  is_rsync: if true, the calling function is rsync. Determines if metadata is
            needed to verify download.
  preserve_posix: if true, retrieves POSIX attributes into user metadata.
  delete_source: if true, source object will be deleted after the copy
                 (mv command).
  file_size_will_change: if true, do not try to record file size.

Returns:
  List of necessary field metadata field names.

)r  componentCountcontentDispositionr  r  r   rz   r{   r|   r}   r~   	mediaLinkmetadatametagenerationr   timeCreatedr8  r   )	rz   r  r   r{   r|   r?  r~   r   r}   zmetadata/%srB  r   )setrs  re   ra   rc   rd   rg   r  )	dst_is_cloudr   r   r  r  delete_sourcefile_size_will_changesrc_obj_fields_setposix_fieldss	            r   GetSourceFieldsNeededForCopyrI    s    N u   & ( )  
 
 !;] KL
*
$
*
$
(
"
)
#
(
"l - 
 ~./	 	!!r      Z   im  )nearlinecoldlinearchivec                    U R                   S:X  a  U(       a  UR                  (       a  UR                  (       a  UR                  R                  5       n[        R                  US5      nU(       aW  U[        UR                  5      -   n[        R                  " 5       U:  a%  UR                  SX0R                  U[        -  5        ggggggg)a  Warns when deleting a gs:// object could incur an early deletion charge.

This function inspects metadata for Google Cloud Storage objects that are
subject to early deletion charges (such as Nearline), and warns when
performing operations like mv that would delete them.

Args:
  src_url: CloudUrl for the source object.
  src_obj_metadata: source object metadata with necessary fields
      (per GetSourceFieldsNeededForCopy).
  logger: logging.Logger for outputting warning.
r  NzWarning: moving %s object %s may incur an early deletion charge, because the original object is less than %s days old according to the local system time.)r   rB  r   r  EARLY_DELETION_MINIMUM_LIFETIMErF  rb   r  rK  r  ru   )r   r>  r   object_storage_classearly_deletion_cutoff_secondsminimum_delete_ages         r   "WarnIfMvEarlyDeletionChargeAppliesrT  I  s     nn!1""'7'D'D+88>>@$C$G$Gd%$!$
'
 !1!=!=
>?  
)	); !"4"4)_<	> 
*	 %	 (E" "2r   c                     U R                   S:X  a1  [        R                  (       a  UR                  S:X  a
  [	        5       eggg)a
  Skips unsupported object types if requested.

Args:
  src_url: CloudUrl for the source object.
  src_obj_metadata: source object metadata with storageClass field
      (per GetSourceFieldsNeededForCopy).

Raises:
  SkipGlacierError: if skipping a s3 Glacier object.
s3GLACIERN)r   r   r   r   SkipGlacierError)r   r>  s     r   MaybeSkipUnsupportedObjectrY  h  s?     nn66##y0

 1 7 r   c                     UR                   (       aT  [        UR                   R                  [        5      nU(       d'  [	        SUR                   R                  < SU < 35      eU$ g)a  Ensures a matching decryption key is available for the source object.

Args:
  src_url: CloudUrl for the source object.
  src_obj_metadata: source object metadata with optional customerEncryption
      field.

Raises:
  EncryptionException if the object is encrypted and no matching key is found.

Returns:
  Base64-encoded decryption key string if the object is encrypted and a
  matching key is found, or None if object is not encrypted.
z(Missing decryption key with SHA256 hash z#. No decryption key matches object N)r{   rQ   	keySha256r   r   )r   r>  r  s      r   GetDecryptionCSEKr\  y  s`     ((1++55v?N ..88'CD D  )r   c                    U(       a  UR                  5       nO0 n[        U5      nUR                  5       (       a  UR                  S:X  a  [	        U5      nO
[        5       nSnSnSnUR                  5       (       Ga3  UR                  5       (       a1  UR                  UR                  :X  a  [        R                  (       d  Sn[        R                  (       a  [        XU 5        [        X5        [        X5      nUR                  nUR                  Ul        [        R                  (       a  UR                  5       (       an  UR                  S:X  a  UR                  (       d  [!        SU-  5      eUR                  Ul        UR                  S:X  a  [#        U5      nU(       a  [%        UU5        OU(       a  [&        R(                  " XU 5      nOUn [+        U5      nUR7                  5       (       d  UR9                  5       (       a  SnOUU(       a%  UR                  (       a  U(       d  UR                  nO)[:        R<                  R?                  UR@                  5      n[        RB                  (       a  U	RE                  URF                  SU5        UR                  S:X  a4  US:w  a.  Ub+  U[H        :  a!  [!        SU< S[K        [H        5      < S35      e[L        (       af  URO                  5       (       aQ  UR7                  5       (       a<  [P        RR                  " [+        U5      RU                  5       [:        RV                  5        [        RX                  (       a  URZ                  (       a  []        S5      eSUl-        URO                  5       (       a8  [:        R<                  R_                  UR@                  5      (       a
  [a        5       eUR                  5       (       aA   URc                  URd                  UR@                  UR                  S9nU(       a
  [a        5       eUR                  5       (       a  UR@                  Ul4        URd                  Ul5        UR                  5       (       a#  UR@                  Ul4        URd                  Ul5        O[m        UU5        [o        [p        5      nU(       a?  URr                  [t        Rv                  :X  a!  UR                  S:X  a  URx                  Ul=        U(       a  [}        UUSS9  [        R~                  (       a  [        R~                  Ul@        [p        R                  " SS5      [        :X  a  SUlC        [        XUU5        UR                  5       (       Ga  URO                  5       (       aW  [        UR                  [        UU[        R                  " 5       [        R                  USS95        [        UUUUU UUUUUUUS9$ U(       aR  [        UR                  [        UU[        R                  " 5       [        R                  USS95        [        UUUUUUUS9$ [        UR                  [        UU[        R                  " 5       [        R                  USS95        [        UUUUUUU US9$ UR                  5       (       a>  [        UUUUUUUU UUU
UUS9nU(       a   [:        R                  " URh                  5        U$ [        UR                  [        UU[        R                  " 5       [        R                  USS95        [        UUUR                  US9nUR7                  5       (       d+  UR7                  5       (       d  [        UR@                  UUUS9  U$ ! [,         a`  nSU< S[/        U5      < S	3nUR0                  (       a+  U=R2                  S
-  sl        U R5                  U5         SnAg[!        U5      eSnAff = f! [f         a    Sn GNf = f)af  Performs copy from src_url to dst_url, handling various special cases.

Args:
  logger: for outputting log messages.
  src_url: Source StorageUrl.
  dst_url: Destination StorageUrl.
  gsutil_api: gsutil Cloud API instance to use for the copy.
  command_obj: command object for use in Apply in parallel composite uploads
      and sliced object downloads.
  copy_exception_handler: for handling copy exceptions during Apply.
  src_obj_metadata: If source URL is a cloud object, source object metadata
      with all necessary fields (per GetSourceFieldsNeededForCopy).
      Required for cloud source URLs. If source URL is a file, an
      apitools Object that may contain file size, or None.
  allow_splitting: Whether to allow the file to be split into component
                   pieces for an parallel composite upload or download.
  headers: optional headers to use for the copy operation.
  manifest: optional manifest for tracking copy operations.
  gzip_exts: List of file extensions to gzip, if any.
             If gzip_exts is GZIP_ALL_FILES, gzip all files.
  is_rsync: Whether or not the caller is the rsync command.
  preserve_posix: Whether or not to preserve posix attributes.
  gzip_encoded: Whether to use gzip transport encoding for the upload. Used
      in conjunction with gzip_exts. Streaming files compressed is only
      supported on the JSON GCS API.
  use_stet: If True, will perform STET encryption or decryption using
      the binary specified in the boto config or PATH.

Returns:
  (elapsed_time, bytes_transferred, version-specific dst_url) excluding
  overhead like initial GET.

Raises:
  ItemExistsError: if no clobber flag is specified and the destination
      object already exists.
  SkipUnsupportedObjectError: if skip_unsupported_objects flag is specified
      and the source is an unsupported type.
  CommandException: if other errors encountered.
r  NFTzZNo OWNER permission found for object %s. OWNER permission is required for preserving ACLs.rV  zError opening file "z": r"  r   r   "zV" exceeds the maximum gsutil-supported size for an S3 upload. S3 objects greater than zB in size require multipart uploads, which gsutil does not support.zASpecifying x-goog-if-generation-match is not supported with cp -nr   r  )overriderC  rD  r  )r   r  r  r  r  r  )r   r   r   )r;  r>  r#  )Tcopyro   r   r   rp   r   r   r   r   rT  rY  r\  r   r   r   r8  r!   rq   rl   rB   encrypt_uploadrj   r  r   continue_on_errorr   r   r  r  r   rh  r]  r   r   Setr  S3_MAX_UPLOAD_SIZErt   rk   r   msvcrtsetmodefilenoO_BINARYr   	gen_matchr   r  ItemExistsErrorGetObjectMetadatar   r   r   r   r2  rR   r   crypto_typerO   CMEK
crypto_key
kmsKeyNamerm   r   r   rF  rW   r~   r  r`   r;  r3   r  r  r!  r  r  r9  r;  r   rg  r0  r3  rf   )r   r   r   r   r  r  r>  r   headersmanifestr   r  r  r   r  dst_obj_headersrL  r   r8  r  copy_in_the_cloudr9  acl_textsource_stream_urlr   re  
dst_objectr  uploaded_metadataresults                                 r   PerformCopyry    s   n llnOO
 /?gnn4,_=M!OM.7>>!A#//))(FKw9&wAN#((L#3#?#? ++0B0B0D0D	4	(8(<(<,.567 	7 .11
 
4	01AB
()98
D#227VL!	(/0AB W^^--l	.33H &**lWW__%6%B%BCl))LL##V\:nnD''
 
#$67	9: : ZG%%''G,<,<,>,>
NN'07792;;G''  9 : : !"mrww~~g.A.ABB					11'2E2E292E2E;B>> 2 K

 
#//%11 &11 ' 3 3g'783F;))]-?-??$$9$D$D! ')9EJ//$;$N$N!ZZ.)-==  $FW.>?

!
!
giik#.#<#<'$&' #7#3#*#-#)#.#93B2@,42@,46 6 


!
!
giik#.#>#>'$&' %W%5%,%5%2%/4BD D 

!
!
giik#.#>#>'$&' ))9)0)9)6)3)/8FH H  .g.@.:.5.>.;.8.4.9.D8A>M;GI 

		$))*

!
!
giik#.#>#>'$&' w&,6,C,C0@Bf
 (8(8(:(:"7#6#6#3,42@	B mI  (293q6Bg		&	&$$)$Ww''(z  
s1   ]< !/_) <
_&A_!_!!_&)_98_9c                   R    \ rS rSrSrS rS rS rS rS r	S r
SS	 jrS
 rS rSrg)Manifesti  z2Stores the manifest items for the CpCommand class.c                     0 U l         0 U l        [        R                  " 5       U l        [
        R                  R                  U5      U l        U R                  5         U R                  5         g rq  )itemsmanifest_filterrA   r  lockr   rh  
expandusermanifest_path_ParseManifest_CreateManifestFile)r  rh  s     r   r  Manifest.__init__  sP    DJD*557DI++D1Dr   c                 6    [         R                  R                  U R                  5      (       a  [	        U R                  S5       nSn[
        R                  " U5      nU HO  nU(       a#   UR                  S5      nUR                  S5      nSnUW   nUW   nUS;   d  MA  XR                  U'   MQ     SSS5        gg! [         a    [        SU R                  -  5      ef = f! , (       d  f       g= f! [         a    [        S	U R                  -  5      ef = f)
zpLoad and parse a manifest file.

This information will be used to skip any files that have a skip or OK
status.
r  TSourceResultz$Missing headers in manifest file: %sF)OKskipNzCould not parse %s)r   rh  r  r  r6  csvreaderindexr  r!   r~  r  )	r  f	first_rowr  rowsource_indexresult_indexsourcerx  s	            r   r  Manifest._ParseManifest  s   H	**	+	+ $$$c*a)::a=&c;"yy2"yy2
 I&F&F' .4""6*  +* 
,   ;&'M'+'9'9(: ; ;; +*&  H1D4F4FFGGHsH   AC5 %C$,"B>C$"C$4C5 >#C!!C$$
C2.C5 2C5 5#Dc                     XR                   ;   $ )z?Returns whether the specified src url was marked as successful.)r~  )r  srcs     r   WasSuccessfulManifest.WasSuccessful  s    &&&&r   c                     [         R                  R                  U R                  5      (       a.  [         R                  " U R                  5      R
                  S:X  a  [        R                  (       aH  [        U R                  SSS9 n[        R                  " U5      nUR                  / SQ5        SSS5        g[        U R                  SS5       n[        R                  " U5      nUR                  / SQ5        SSS5        gg! , (       d  f       g= f! , (       d  f       g= f! [         a    [        S	5      ef = f)
z;Opens the manifest file and assigns it to the file pointer.r   r  r  newline)
r  DestinationStartEndMd5UploadIdzSource SizezBytes Transferredr  DescriptionNrU  r   zCould not create manifest file.)r   rh  r  r  r   st_sizer8  rH  r6  r  writerwriterowr  r!   )r  r  r  s      r   r  Manifest._CreateManifestFile  s    #@ww~~d0011774%%&..!377D&&R8AZZ]FOO   98 D&&a0AZZ]FOO   10% 4 98 10  @>??@sN   BD( *D2D( ;D( *D<D( 
DD( D( 
D%!D( %D( (D>c                 n    Uc  g XR                   ;   a  X0R                   U   U'   g X#0U R                   U'   g rq  r}  )r  r  r  values       r   rc  Manifest.Set  s5    } 
jj"jjocdjjor   c                     U R                  USU5        U R                  USU5        U R                  US[        R                  R                  [        R                  R                  S9R                  S S95        g )N
source_uridestination_urir  tztzinfo)rc  datetimenowtimezoneutcr  )r  
source_urlr  s      r   
InitializeManifest.Initialize)  sb    HHZz2HHZ*O<HHZx'8'8'<'<@Q@Q@U@U'<'V'^'^fj'^'klr   c                 `   U R                  USU5        U R                  USU5        U R                  USU5        U R                  US[        R                  R                  [        R                  R                  S9R                  S S95        U R                  U5        U R                  U5        g )Nbytesrx  descriptionr  r  r  )rc  r  r  r  r  r  _WriteRowToManifestFile_RemoveItemFromManifest)r  r  r  rx  r  s        r   	SetResultManifest.SetResult/  s    HHZ"34HHZ6*HHZ4HHZX%6%6%:%:h>O>O>S>S%:%T%\%\dh%\%ij  ,  ,r   c                    U R                   U   nUS   US   SUS   R                  5       -  SUS   R                  5       -  SU;   a  US   OSSU;   a  US   OSS	U;   a  [        US	   5      OSS
U;   a  [        US
   5      OSUS   US   /
nU Vs/ s H  n[        R                  " U5      PM     nnU R
                     [        (       a,  [        R                  (       a  [        U R                  SSSS9nO[        U R                  SS5      n[        R                  " U5      nUR                  U5        UR                  5         SSS5        gs  snf ! , (       d  f       g= f)zBWrites a manifest entry to the manifest file for the url argument.r  r  z%sZr  r  r.  r  	upload_idr   r  rx  r  ar   r  N)r}  	isoformatr   r8  r*  r  rk   rH  r6  r  r  r  r  r(  )r  r  row_itemr  r  r  r  s          r   r   Manifest._WriteRowToManifestFile7  sC   zz#H"#&0022$..00 H,"!,!8b!'8!3HV")X"5HW2D 044teCNN5!tD4 
	##S!R8##S!,zz!}foodggi 
	 5 
s    E BE
E"c                     U R                   U	 g rq  r  )r  r  s     r   r   Manifest._RemoveItemFromManifestT  s     	

3r   )r}  r  r~  r  N)r  )r   r   r   r   r   r  r  r  r  rc  r  r  r  r  r   r   r   r   r{  r{    s7    :H@'%@N	%m-:r   r{  c                       \ rS rSrSrSrg)rj  i[  zHException class for objects that are skipped because they already exist.r   Nr   r   r   r   rj  rj  [  s    Pr   rj  c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )SkipUnsupportedObjectErrori`  CException for objects skipped because they are an unsupported type.c                 8   > [         [        U ]  5         SU l        g )NUnknown)superr  r  unsupported_typer  	__class__s    r   r  #SkipUnsupportedObjectError.__init__c  s    	
$d46%Dr   r  r   r   r   r   r   r  r   __classcell__r  s   @r   r  r  `      K& &r   r  c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )rX  ih  r  c                 8   > [         [        U ]  5         SU l        g )NrW  )r  rX  r  r  r  s    r   r  SkipGlacierError.__init__k  s    	
D*,%Dr   r  r  r  s   @r   rX  rX  h  r  r   rX  c                    U R                   nU R                  5       (       aT  U R                  [        S5      S nUR	                  U5      S:X  a  gSUR                  U5      R                  U5      S   -  $ U R                  5       (       a  SU R                  -  $ U R                  R                  U5      R                  U5      S   n[        XA5      $ )a)  Returns the path section before the final directory component of the URL.

This handles cases for file system directories, bucket, and bucket
subdirectories. Example: for gs://bucket/dir/ we'll return 'gs://bucket',
and for file://dir we'll return file://

Args:
  url: StorageUrl representing a filesystem directory, cloud bucket or
       bucket subdir.
  exp_src_url: StorageUrl representing the fully expanded object
      to-be-copied; used for resolving cloud wildcards.

Returns:
  String name of above-described path, sans final path separator.
zfile://Nr
  z	file://%sr   z%s://)
r   r   r  r  findr   r   r   r   $ResolveWildcardsInPathBeforeFinalDir)r  r  seppast_schemepath_sans_final_dirs        r   r  r  p  s      			#]]__..Y1K";--c2==cB1EEE\\^^SZZ--c2==cB1E	-.A	OOr   c                 t   [        U 5      (       d  U $ [        U 5      R                  R                  S5      nUR                  R                  S5      n[	        [        U5      5       H  n[        X$   5      (       d  M  X4   X$'   M     SR                  U5      nUR                  5       nXVl        UR                  $ )aB  Returns the path section for a bucket subdir with wildcards resolved.

This handles cases for bucket subdirectories where the initial source URL
contains a wildcard. In this case, src_url must be wildcard-expanded
before calculating the final directory.

Example:
  A bucket containing:
    gs://bucket/dir1/subdir/foo
    gs://bucket/dir2/subdir/foo

  and source URL gs://bucket/*/subdir
  and src_url_path_sans_final dir gs://bucket/*

  should yield final path gs://bucket/dir1 or gs://bucket/dir2 according to
  the expanded source URL.

Args:
  src_url_path_sans_final_dir: URL string with wildcards representing a
      bucket subdir as computed from GetPathBeforeFinalDir.
  exp_src_url: CloudUrl representing the fully expanded object to-be-copied.

Returns:
  String name of above-described path, sans final path separator.
r  )	r.   r1   r   rN  r	   r  r  r  r  )r  r  wildcarded_src_obj_pathexpanded_src_obj_pathpath_segment_indexresolved_src_pathfinal_path_urls          r   r  r    s    6 
5	6	6&& 1!##.;uuSz %1177<!#&=">?/CDD  
3 1	 @ hh67$$&.0		"	""r   c                 ^    [        X5      n[        [        X15      S5      n[        X5      nX44$ )a	  Gets info about a file partition for parallel file/object transfers.

Args:
  file_size: The number of bytes in the file to be partitioned.
  max_components: The maximum number of components that can be composed.
  default_component_size: The size of a component, assuming that
                          max_components is infinite.
Returns:
  The number of components in the partitioned file, and the size of each
  component (except the last, which will have a different size iff
  file_size != 0 (mod num_components)).
r   )rr   maxrG  )rw  r  default_component_sizery  rz  s        r   rq  rq    s6     !C. s>:A>. !;.
	))r   c                     [        X5      n UR                  UR                  UR                  UR                  UR
                  S9  g! [         a     gf = f)zGWrapper func to be used with command.Apply to delete temporary objects.r  N)rJ   r  r   r   r}   r   r   )r   url_to_deleter   r   s       r   r  r    s]    "35*
	M55)55'4'?'?%2%9%9  ; 
 	
 		s   :A 
AAc           	         / nU Vs/ s H  oUR                   PM     nnU  H  nXv;  d  M
  UR                  X   5        M     / n/ n	/ n
U GH  nUR                   U R                  5       ;  d  UR                   U;   aE  UR                  5       nUR                   Ul         UR                  Ul        U	R                  U5        Mw  XR                      n[        UR                  UR                  UR                  5      n[        U5      n UR                  nUR                  UR                  UR                   UR                  UR                  / SQS9nUR                  nUU:w  a  UR                  U5        UR                  UR                   5        UR                  (       a?  UR                  R                  5       nUR                  Ul        U	R                  U5        GM  GM  UR                  R                  5       nUR                  Ul        U
R                  XR                  45        UR                  UR                   5        GM     U
(       a   [         R"                  " S[%        U
5      5        XJU	4$ s  snf ! [         a    Sn GN+f = f)a/  Determines course of action for component objects.

Given the list of all target objects based on partitioning the file and
the list of objects that have already been uploaded successfully,
this function determines which objects should be uploaded, which
existing components are still valid, and which existing components should
be deleted.

Args:
  dst_args: The map of file_name -> PerformParallelUploadFileToObjectArgs
            calculated by partitioning the file.
  existing_components: A list of ObjectFromTracker objects that have been
                       uploaded in the past.
  bucket_url: CloudUrl of the bucket in which the components exist.
  gsutil_api: gsutil Cloud API instance to use for retrieving object metadata.

Returns:
  components_to_upload: List of components that need to be uploaded.
  uploaded_components: List of components that have already been
                       uploaded and are still valid. Each element of the list
                       contains the dst_url for the uploaded component and
                       its size.
  existing_objects_to_delete: List of components that have already
                              been uploaded, but are no longer valid
                              and are in a versioned bucket, and
                              therefore should be deleted.
)r{   r|   r~   )r}   r  r  Nz0Found %d existing temporary components to reuse.)r   ru  r  r  r}   r$   r   r   r   rT   r   rk  r   r   r~   r  r  r  r  )r{  r  
bucket_urlr   r  r   existing_component_namescomponent_nameobjects_already_chosenr  r  tracker_objectr  dst_arg	file_partr  r   dst_metadata	cloud_md5!invalid_component_with_generations                       r   r  r    sc   : -@-@	-@   !n5!!(":; ! 
  "+n""(--/9""&<< c&22co%00cn '',112G))7+=+= ,,.I 5Y?Kg11





''>>: 2 <l &&i K!!'*##N$>$>?		"	" -4OO,A,A,C)7E7P7P)4"))*KL 
# OO!!#c%00cn  #':':!;<##N$>$>?a ,d LLC()+ 5O	PPIX   is   I1AI66JJrq  )FFFFFFFNFNN)F)NF)FN)FF)FFF)NTFF)NN)Nr   NN)TNFFF)FFFF)	NTNNNFFFF(  r   
__future__r   r   r   r   r%  collectionsr   r  r  r  rZ  r  r  r,  operatorr   r   r  r  rH  r  r.  r8  r   r$  rW  r  r  r   	six.movesr	   apitools.base.protorpcliter
   botor   r3  r  gslib.cloud_apir   r   r   r   r   r   r   r   r   r   r   r   gslib.commands.composer   gslib.commands.configr   r   r   r   r   r   gslib.cs_api_mapr   gslib.daisy_chain_wrapperr    gslib.exceptionr!   r"   r#   gslib.file_partr$   gslib.parallel_tracker_filer%   r&   r'   r(   r)   gslib.progress_callbackr*   r+    gslib.resumable_streaming_uploadr,   r-   gslib.storage_urlr.   r/   r0   r1   "gslib.third_party.storage_apitoolsr2   r   gslib.thread_messager3   r4   gslib.tracker_filer5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   gslib.utilsrA   rB   rC   rD   gslib.utils.boto_utilrE   rF   rG   rH   rI   gslib.utils.cloud_api_helperrJ   rK   gslib.utils.constantsrL   rM   rN   gslib.utils.encryption_helperrO   rP   rQ   rR   gslib.utils.hashing_helperrS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   gslib.utils.metadata_utilr]   &gslib.utils.parallelism_framework_utilr^   r_   r`   gslib.utils.posix_utilra   rb   rc   rd   re   rf   rg   gslib.utils.system_utilrh   ri   rj   rk   gslib.utils.translation_helperrl   rm   rn   ro   rp   rq   gslib.utils.unit_utilrr   rs   rt   ru   rv   gslib.wildcard_iteratorrw   rH  r  r  re  is_availabletop_level_managerr  r  r  r  r  rt  rr  r  r   r   r   r[  r   r  r  rd  r  r  r+  r  r   r   r   r   r   r   r   r   r   r   r   r  r!  r,  rA  rW  rb  rf  rn  r  r  r  r  r  r  r  r  r  r  r2  r;  rL  rR  rd  rm  r   r  r  r  r  objectr  r  r  r  r  r!  r  r3  r5  r;  rI  rP  rT  rY  r\  ry  r{  rj  r  rX  r  r  rq  r  r  r   r   r   <module>r     s    / & %  '  " 
        	    	  
       
   0    1 - $ / - 1 ) 6 9 4 = , 4 R M O O J @ ( 7 , 1 + $ E E L Q F ? ? P  . 8 6 2 W , 6 9 0 > 3 1 3 B > A . @ 9 2 ! + ! ; 2 / 4 6 < E : : & 7 A F A 7 I B C 7 3 : - 8 ? 9 = W H - 9 + , - = + 2 / 8 . I = ? D C H / 6 3 1 ) :777	$  46CCC (99IMP -779 ! ",  M   4 )3+) % )3+))* %  %/'% !  "  ' *; ' , 
 (46CCC (99IMP  #="G"G"I   Iy I
+9x , /   %*$)%*.3#(&+&+$(27,0,0!@!/6L40?f :%	` $)ePD=J !@DFL"%?d *. %JZK2 -2`'R 15=<F =B $	g;T5v$6,I: ,0AH/0t 27B'\ /4.3a)J 38/427$(N4Kn7'H #'(,%*%*P#f7+t0f-<`PGfD DV %)	23z &*#'p#t 26./,026f,^ 6:=0N +/)-#().#(RHB +005*/gT)X 04#J +005/47<k"b _$_$_$# >>"D "& $$"nb	Rv Rji 
& &&1 &P<,#^*0	 bQr   