
    $                     \   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	m
Z
 ddl	mZ ddl	mZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! dddZ"d Z#d Z$d Z%	 	 	 	 	 	 	 d dZ&d Z'y)!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                 J   t        j                  t        j                  j                  j
                  j                               }||k\  r@t        j                  j                  | j                  v rt        j                  j                  S t        j                  j                  S )a
  Determines 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   sz     '3333779;**++s/?/??##---##***    c                    |rt         j                  S t        j                         D ]  \  }}| j	                  |      s|c S  t
        j                  j                         sxt        j                  j                  j                  j                         rFt        j                  ddd| gdt        j                  d      }|j                   j#                         }nt%        j&                  |       \  }}|r|S t         j                  S )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^^VT8[A"&#-??/35F ==&&(L**;7OL!		4	44r(   c                    |j                   j                  }t        j                  j                  j
                  j                         r|j                   j                  nd}t        j                  ||      }t        j                  t        j                  j                  j                  j                               }t        j                  j                  |v rut!        j"                          |t        j                  j$                  k(  st!        j&                         r.t(        j*                  j,                  t!        j.                         iS i S | j0                  s9t        j                  j2                  |v s|t        j                  j4                  k(  ri S t(        j*                  j6                  t9        j:                         iS )ai  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   sL    "--44( 
			"	"	F	F	N	N	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                    |rtt        j                  ||xs d|| j                  |j                  ||t        j                  j
                  t        j                         t        j                         
      }nd}| j                  j                  rt        j                  dd      }	n)t        j                  | j                  j                        }	| j                  j                  r^t!        j"                  t$        j&                  j(                  j*                  j-                               }
t/        j0                  |	|
||      S |t3        j4                  |	|||      S t7        j8                  |	||||      S )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|      sL   : *HH&{"..,88))"00::99;%%'   ))IIa&M**##113M   **$77!!33779;O!66'+	- -
 ~%%+	- - ++fVy+- -r(   c                    | syt         j                  j                  | v r=t        j                  | t         j                  j                           }|j                  }nt         j                  j
                  | v r=t        j                  | t         j                  j
                           }|j                  }nAt        j                  dj                  dj                  | j                                           	 t        j                  |j                  j                   ||       y# t        j"                  $ r1 t%        j&                  |j                        j)                  |        w xY w)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   8+D$ $AE()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(   