
    $                     ^   S 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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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J r   SSKJ!r!  SSS.r"S r#S r$S r%       S S jr&S r'g)!z2Utility functions for performing upload operation.    )absolute_import)division)unicode_literalsN)api_factory)	cloud_api)request_config_factory)buffered_upload_stream)component_stream)errors)fast_crc32c_util)	hash_util)progress_callbacks)upload_stream)task_status)delete_task)crc32c)
properties)files)hashing)	platforms)scaled_integerztext/markdownzapplication/gzip)z.mdz.tgzc                 P   [         R                  " [        R                  R                  R
                  R                  5       5      nX:  aB  [        R                  R                  U R                  ;   a  [        R                  R                  $ [        R                  R                  $ )zDetermines if resumbale uplaod should be performed.

Args:
  api (CloudApi): An api instance to check if it supports resumable upload.
  object_length (int): Length of the data to be uploaded.

Returns:
  bool: True if resumable upload can be performed.
)r   ParseIntegerr   VALUESstorageresumable_thresholdGetr   
CapabilityRESUMABLE_UPLOADcapabilitiesUploadStrategy	RESUMABLESIMPLE)apiobject_lengthr   s      >lib/googlecloudsdk/command_lib/storage/tasks/cp/upload_util.pyget_upload_strategyr'   5   sw     '3333779;*++s/?/??##---##***    c                 <   U(       a  [         R                  $ [        R                  5        H  u  p#U R	                  U5      (       d  M  Us  $    [
        R                  R                  5       (       d{  [        R                  R                  R                  R                  5       (       aD  [        R                  " SSSU /S[        R                  SS9nUR                   R#                  5       nO[$        R&                  " U 5      u  p5U(       a  U$ [         R                  $ )a  Gets a file's MIME type.

Favors returning the result of `file -b --mime ...` if the command is
available and users have enabled it. Otherwise, it returns a type based on the
file's extension.

Args:
  source_path (str): Path to file. May differ from file_resource.storage_url
    if using a temporary file (e.g. for gzipping).
  is_stream (bool): If the source file is a pipe (typically FIFO or stdin).

Returns:
  A MIME type (str).
  If a type cannot be guessed, request_config_factory.DEFAULT_CONTENT_TYPE is
  returned.
filez-bz--mimeT)checkstdoutuniversal_newlines)r   DEFAULT_CONTENT_TYPECOMMON_EXTENSION_RULESitemsendswithr   OperatingSystem	IsWindowsr   r   r   use_magicfileGetBool
subprocessrunPIPEr,   strip	mimetypes
guess_type)source_path	is_stream	extensioncontent_typeoutput_s         r&   get_content_typerB   H   s    " !666 "8!=!=!?iI&& "@ 
#
#
-
-
/
/--5577^^VT8[A"&#-??/35F ==&&(L**;7OL		4	44r(   c                    UR                   R                  n[        R                  R                  R
                  R                  5       (       a  UR                   R                  OSn[        R                  " X#5      n[        R                  " [        R                  R                  R                  R                  5       5      n[        R                  R                  U;   a~  [         R"                  " 5         U[        R                  R$                  :X  d  [         R&                  " 5       (       a/  [(        R*                  R,                  [         R.                  " 5       0$ 0 $ U R0                  (       d<  [        R                  R2                  U;   d  U[        R                  R4                  :X  a  0 $ [(        R*                  R6                  [8        R:                  " 5       0$ )aY  Gets appropriate hash objects for upload validation.

Args:
  source_resource (resource_reference.FileObjectResource): The upload source.
  destination_resource (resource_reference.ObjectResource): The upload
    destination.

Returns:
  A dict[hash_util.HashAlgorithm, hash object], the values of which should be
  updated with uploaded bytes.
N)storage_urlschemer   r   r   #enable_zonal_buckets_bidi_streamingr5   bucket_namer   get_capabilitiesCheckHashescheck_hashesr   r   r   APPENDABLE_UPLOADr   log_or_raise_crc32c_issuesALWAYScheck_if_will_use_fast_crc32cr   HashAlgorithmCRC32C
get_crc32cmd5_hashCLIENT_SIDE_HASH_VALIDATIONNEVERMD5r   get_md5)source_resourcedestination_resourceproviderrG   r    rJ   s         r&   get_digestersrZ   p   sP    "--44( 
			"	"	F	F	N	N	P	P &&22 
 --hD,'',,0024, ++|;//1
..55599;;%%,,.>.I.I.KLLI66,Fj,,222I

!
!
%
%w'8	99r(   c                    U(       ay  [         R                  " UU=(       d    SUU R                  UR                  UU[        R                  R
                  [        R                  " 5       [        R                  " 5       S9
nOSnU R                  R                  (       a  [        R                  " SS5      n	O*[        R                  " U R                  R                  5      n	U R                  R                  (       a]  [         R"                  " [$        R&                  R(                  R*                  R-                  5       5      n
[.        R0                  " U	U
UUS9$ Uc  [2        R4                  " U	UUUS9$ [6        R8                  " XXUS9$ )a  Gets a stream to use for an upload.

Args:
  source_resource (resource_reference.FileObjectResource): Contains a path to
    the source file.
  length (int|None): The total number of bytes to be uploaded.
  offset (int|None): The position of the first byte to be uploaded.
  digesters (dict[hash_util.HashAlgorithm, hash object]|None): Hash objects to
    be populated as bytes are read.
  task_status_queue (multiprocessing.Queue|None): Used for sending progress
    messages. If None, no messages will be generated or sent.
  destination_resource (resource_reference.ObjectResource|None): The upload
    destination. Used for progress reports, and should be specified if
    task_status_queue is.
  component_number (int|None): Identifies a component in composite uploads.
  total_components (int|None): The total number of components used in a
    composite upload.

Returns:
  An UploadStream wrapping the file specified by source_resource.
r   )
status_queueoffsetlength
source_urldestination_urlcomponent_numbertotal_componentsoperation_name
process_id	thread_idNrb)max_buffer_size	digestersprogress_callback)r^   rh   ri   )r]   r^   rh   ri   )r   FilesAndBytesProgressCallbackrD   r   OperationName	UPLOADINGosgetpid	threading	get_identis_stdiofdopenr   BinaryFileReaderresource_namer=   r   ParseBinaryIntegerr   r   r   upload_chunk_sizer   r	   BufferedUploadStreamr   UploadStreamr
   ComponentStream)rW   r^   r]   rh   task_status_queuerX   ra   rb   ri   source_streamrg   s              r&   
get_streamr|      sH   : *HH&{"..,88))"00::99;%%'   ))IIa&M**##113M   **$77!!33779;O!66'+	- -
 ~%%+	- - ++V+- -r(   c                    U (       d  g[         R                  R                  U ;   a>  [         R                  " U [         R                  R                     5      nUR                  nO[         R                  R
                  U ;   a>  [        R                  " U [         R                  R
                     5      nUR                  nOB[        R                  " SR                  SR                  U R                  5       5      5      5      e [         R                  " UR                  R                   UU5        g! [        R"                   a/    [$        R&                  " UR                  5      R)                  US9  e f = f)zHRaises error if hashes for uploaded_resource and digesters do not match.Nz4Unsupported hash algorithm(s) found in digesters: {}z, )rz   )r   rO   rU   get_base64_hash_digest_stringrR   rP   r   get_hashcrc32c_hashr   Errorformatjoinkeysvalidate_object_hashes_matchrD   
url_stringHashMismatchErrorr   DeleteObjectTaskexecute)rh   uploaded_resourcerz   calculated_digestdestination_hashs        r&   validate_uploaded_objectr      s1   	
  I-!??)))--.0(11%%2)))001 )44
,,>EEIIinn&'	
 

**%%002C 
	!	! 
  !2!>!>?GG+ H  
	
s   ,D1 1AE4)NNNNNNN)(__doc__
__future__r   r   r   r:   rm   r6   ro   googlecloudsdk.api_lib.storager   r   r   "googlecloudsdk.command_lib.storager	   r
   r   r   r   r   r   (googlecloudsdk.command_lib.storage.tasksr   +googlecloudsdk.command_lib.storage.tasks.rmr   googlecloudsdk.command_lib.utilr   googlecloudsdk.corer   googlecloudsdk.core.utilr   r   r   r   r/   r'   rB   rZ   r|   r    r(   r&   <module>r      s     9 &  '  	   6 4 A E ? 5 ? 8 A < @ C 2 * * , . 3  +&%5P$:P !%$( $ $D-N
r(   