
    D'                     J   d Z ddlm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
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# ejH                  Z%dZ&de&z   dz   Z'd e#jP                         z   dz   dz    e#jP                         z   dz   dz   dz   d z   d!z    e#jR                         z   d"z   d#z   d$z   d%z   d!z    e#jR                         z   d&z   d'z   Z* G d( d)e      Z+y)*zEImplementation of hash command for calculating hashes of local files.    )absolute_import)print_function)division)unicode_literalsN)Command)CommandArgument)ApiSelector)CommandException)FileProgressCallbackHandler)ProgressCallbackWithTimeout)StorageUrlFromString)FileMessage)FinalMessage)	boto_util)	constants)hashing_helper)parallelism_framework_util)GcloudStorageFlag)GcloudStorageMap)	shim_utilz*
  gsutil hash [-c] [-h] [-m] filename...
z
<B>SYNOPSIS</B>
a  


<B>DESCRIPTION</B>
  Calculate hashes on local files, which can be used to compare with
  ``gsutil ls -L`` output. If a specific hash option is not provided, this
  command calculates all gsutil-supported hashes for the files.

  Note that gsutil automatically performs hash validation when uploading or
  downloading files, so this command is only needed if you want to write a
  script that separately checks the hash.

  If you calculate a CRC32c hash for files without a precompiled crcmod
  installation, hashing will be very slow. See "gsutil help crcmod" for details.

<B>OPTIONS</B>
  -c          Calculate a CRC32c hash for the specified files.

  -h          Output hashes in hex format. By default, gsutil uses base64.

  -m          Calculate a MD5 hash for the specified files.
z>--format=value[separator="",terminator=""](digest_format.sub("z", "Hashes ["),z	url.sub("z", "] for ").sub("$", ":^\^n"),z,md5_hash.yesno(yes="	Hash (md5):		", no=""),zmd5_hash.yesno(no=""),z$md5_hash.yesno(yes="NEWLINE", no="")z.sub("NEWLINE", "z"),z2crc32c_hash.yesno(yes="	Hash (crc32c):		", no=""),zcrc32c_hash.yesno(no=""),z'crc32c_hash.yesno(yes="NEWLINE", no="")z"))c                   
    e Zd ZdZ ej
                  dg edej                  dddde	j                  ge	j                   ej                         g      Z ej                  dd	gd
dei       Z fdZed        Zd Zd Z xZS )HashCommandz&Implementation of gsutil hash command.hash   chmTFr   )command_name_aliasesusage_synopsismin_argsmax_argssupported_sub_argsfile_url_okprovider_url_okurls_start_arggs_api_supportgs_default_apiargparse_argumentschecksumcommand_helpzCalculate file hashes)	help_namehelp_name_aliases	help_typehelp_one_line_summary	help_textsubcommand_help_textc           	      T   t        ddt        gt        d      d d d      }t        | j                  | j
                  D cg c]  \  }}|	 c}}z         }d|v rd|vr|xj                  dgz  c_        nd|v rd|vr|xj                  d	gz  c_        t        | !  |      S c c}}w )
Nstorager   z--hex)-h-c-m)gcloud_commandflag_mapr3   r4   z
--skip-md5z--skip-crc32c)	r   _GCLOUD_FORMAT_STRINGr   setargssub_optsr5   superget_gcloud_storage_args)selfgcloud_storage_mapflag_args_set	__class__s        &platform/gsutil/gslib/commands/hash.pyr<   z#HashCommand.get_gcloud_storage_argst   s    )!
 $G,
 499DMMBMqMBBCHxD0''L>9'		d(2''O+<<'7*+=>>  Cs   B$c                     d}d}d }d }d}d}|r,|D ]'  \  }	}
|	dk(  rd}d}|	dk(  r	d}d	 }d
 }|	dk(  s$d}d}) |sd}d}|r3t        j                         s|j                  t        j                         |||||fS )aZ  Returns behavior variables based on input options.

    Args:
      sub_opts: getopt sub-arguments for the command.
      logger: logging.Logger for the command.

    Returns:
      Tuple of
      calc_crc32c: Boolean, if True, command should calculate a CRC32c checksum.
      calc_md5: Boolean, if True, command should calculate an MD5 hash.
      format_func: Function used for formatting the hash in the desired format.
      cloud_format_func: Function used for formatting the hash in the desired
                         format.
      output_format: String describing the hash output format.
    Fc                 H    t        j                  | j                               S N)r   Base64EncodeHash	hexdigestdigests    rC   <lambda>z(HashCommand._ParseOpts.<locals>.<lambda>   s    ~66v7G7G7IJ    c                     | S rF    rI   s    rC   rK   z(HashCommand._ParseOpts.<locals>.<lambda>   s    vrL   base64r3   Tr2   hexc                 "    | j                         S rF   )rH   rI   s    rC   rK   z(HashCommand._ParseOpts.<locals>.<lambda>   s    v'7'7'9rL   c                 J    t        j                  |       j                  d      S )Nascii)r   Base64ToHexHashdecoderI   s    rC   rK   z(HashCommand._ParseOpts.<locals>.<lambda>   s    ,,V4;;GDrL   r4   )r   UsingCrcmodExtensionwarnr   SLOW_CRCMOD_WARNING)clsr:   loggercalc_crc32ccalc_md5format_funccloud_format_funcfound_hash_optionoutput_formatounused_as              rC   
_ParseOptszHashCommand._ParseOpts   s    " KHJ -M!+!X9+"
$Y-9+
 $Y("
 " kh999;kk.445+/@-OOrL   c                     i }|r"t         j                  j                  d      |d<   |rt        j                         |d<   |S )a4  Constructs the dictionary of hashes to compute based on the arguments.

    Args:
      calc_crc32c: If True, CRC32c should be included.
      calc_md5: If True, MD5 should be included.

    Returns:
      Dictionary of {string: hash digester}, where string the name of the
          digester algorithm.
    zcrc-32ccrc32cmd5)crcmod
predefinedCrcr   GetMd5)r=   r[   r\   	hash_dicts       rC   _GetHashClassesFromArgsz#HashCommand._GetHashClassesFromArgs   sC     I"--11)<i'..0irL   c                 J   | j                  | j                  | j                        \  }}}}}d}| j                  D ]  }| j	                  |      j                  g d      D ]f  }d}t        |      }	|j                  j                  }
t        |      j                         rFt        j                  j                  |
      }| j                  j                  j                  t!        |	dt#        j"                         |dt         j$                               t'        |t)        | j                  j                  t        |      d      j*                        }| j-                  ||      }t/        |
d	      5 }t1        j2                  |||
       ddd       | j                  j                  j                  t!        |	dt#        j"                         |dt         j$                               ni }|j4                  }|j6                  }|j8                  du}|j:                  du}|s(|s&t=        j>                         jA                  d|       |r|j8                  |d<   |r|j:                  |d<   tC        d|d|
d       tE        jF                  |      D ]4  \  }}tC        d|d|	j                         r ||      n ||             6 i  |stI        d      tK        | j                  j                  tM        t#        j"                                      y# 1 sw Y   xY w)z)Command entry point for the hash command.F)re   customerEncryptionmd5Hashsize)bucket_listing_fieldsTN)rp   finishedmessage_typeHashing)src_urloperation_namerb)callback_processorzNo hashes present for %srf   re   zHashes [z] for :z	Hash (z):		zNo files matchedr   )'rc   r:   rZ   r9   WildcardIteratorIterObjectsr   storage_urlobject_name	IsFileUrlospathgetsize
gsutil_apistatus_queueputr   time	FILE_HASHr   r   callrl   openr   CalculateHashesFromContentsroot_objectrp   ro   re   logging	getLoggerrW   printsix	iteritemsr
   _PutToQueueWithTimeoutr   )r=   r[   r\   r]   r^   r`   matched_oneurl_strfile_refurl	file_name	file_sizerx   rk   fpobj_metadatamd5_presentcrc32c_presentnamerJ   s                       rC   
RunCommandzHashCommand.RunCommand   s    t}}dkkB[(K):K99++G4@@! A ( "7+((44	(224ggooi0)
//
&
&
*
*#))+(#('2'<'<>?  ;)$//*F*F2Fw2O9BDDHD	 J

 22;I)It$66I2DF % //
&
&
*
*#))+(#''2'<'<>? )!--,"'')$,,D8+'..d:.^$$%?I+33Ie"."5"5Ih}i@AMM)4LD&
@CV)<.?.G*HJ K 5c n /004??77'		46C %$s   3LL")__name__
__module____qualname____doc__r   CreateCommandSpec	_SYNOPSISr   NO_MAXr	   JSONr   MakeZeroOrMoreFileURLsArgumentcommand_specHelpSpec_DETAILED_HELP_TEXT	help_specr<   classmethodrc   rl   r   __classcell__)rB   s   @rC   r   r   Y   s    . +**!&&' %%H/HHJKM, g#3#)?* .P .P`$ArL   r   ),r   
__future__r   r   r   r   r   r   r   rg   r   gslib.commandr   gslib.command_argumentr   gslib.cs_api_mapr	   gslib.exceptionr
   gslib.progress_callbackr   r   gslib.storage_urlr   gslib.thread_messager   r   gslib.utilsr   r   r   r   gslib.utils.shim_utilr   r   r   PutToQueueWithTimeoutr   r   r   get_format_flag_caretget_format_flag_newliner7   r   rN   rL   rC   <module>r      s   L & %  '  	   
 ! 2 ( , ? ? 2 , - ! ! & 2 3 2 !3II 	 4 O#I##%&(9:<GH#I##%&(JK 66 	  F	F
 
 <);;=>
 AFF <<    #LL  <);;=> AEE HKK t' trL   