
    s?                        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	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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  \!Rd                  r3S r4S!\4-   S"-   r5/ S#Qr6/ S$Qr7S% r8S)S& jr9 " S' S(\5      r:g)*zDImplementation of setmeta command for setting cloud object metadata.    )absolute_import)print_function)division)unicode_literalsN)encoding)AccessDeniedException)PreconditionException)Preconditions)Command)CommandArgument)ApiSelector)CommandException)NameExpansionIterator)SeekAheadNameExpansionIterator)StorageUrlFromString)storage_v1_messages)MetadataMessage)	constants)parallelism_framework_util)GetCloudApiInstance)IsCustomMetadataHeader)Retry)GcloudStorageFlag)GcloudStorageMap)InsistAsciiHeader)InsistAsciiHeaderValue)CopyObjectMetadata)ObjectMetadataFromHeaders)PreconditionsFromHeadersz6
  gsutil setmeta -h [header:value|header] ... url...
z
<B>SYNOPSIS</B>
u
  


<B>DESCRIPTION</B>
  The gsutil setmeta command allows you to set or remove the metadata on one
  or more objects. It takes one or more header arguments followed by one or
  more URLs, where each header argument is in one of two forms:

  - If you specify ``header:value``, it sets the provided value for the
    given header on all applicable objects.

  - If you specify ``header`` (with no value), it removes the given header
    from all applicable objects.

  For example, the following command sets the ``Content-Type`` and
  ``Cache-Control`` headers while also removing the ``Content-Disposition``
  header on the specified objects:

    gsutil setmeta -h "Content-Type:text/html" \
      -h "Cache-Control:public, max-age=3600" \
      -h "Content-Disposition" gs://bucket/*.html

  If you have a large number of objects to update you might want to use the
  gsutil -m option, to perform a parallel (multi-threaded/multi-processing)
  update:

    gsutil -m setmeta -h "Content-Type:text/html" \
      -h "Cache-Control:public, max-age=3600" \
      -h "Content-Disposition" gs://bucket/*.html

  You can also use the setmeta command to set custom metadata on an object:

    gsutil setmeta -h "x-goog-meta-icecreamflavor:vanilla" gs://bucket/object

  Custom metadata is always prefixed in gsutil with ``x-goog-meta-``. This
  distinguishes it from standard request headers. Other tools that send and
  receive object metadata by using the request body do not use this prefix.

  While gsutil supports custom metadata with arbitrary Unicode values, note
  that when setting metadata using the XML API, which sends metadata as HTTP
  headers, Unicode characters are encoded using UTF-8, then url-encoded to
  ASCII. For example:
  
    gsutil setmeta -h "x-goog-meta-foo: ã" gs://bucket/object

  stores the custom metadata key-value pair of ``foo`` and ``%C3%A3``.
  Subsequently, running ``ls -L`` using the JSON API to list the object's
  metadata prints ``%C3%A3``, while ``ls -L`` using the XML API url-decodes
  this value automatically, printing the character ``ã``.

  The setmeta command reads each object's current generation and metageneration
  and uses those as preconditions unless they are otherwise specified by
  top-level arguments. For example, the following command sets the custom
  metadata ``icecreamflavor:vanilla`` if the current live object has a
  metageneration of 2:

    gsutil -h "x-goog-if-metageneration-match:2" setmeta
      -h "x-goog-meta-icecreamflavor:vanilla"

  See `Object metadata <https://cloud.google.com/storage/docs/metadata>`_ for
  more information about object metadata.

<B>OPTIONS</B>
  -h          Specifies a header:value to be added, or header to be removed,
              from each named object.
)zcache-controlzcontent-dispositionzcontent-encodingzcontent-languagezcontent-typezcustom-time)storageobjectsupdatec                 H    U R                   R                  U5        SU l        g)zDException handler that maintains state about post-completion status.FN)loggererroreverything_set_okay)clses     )platform/gsutil/gslib/commands/setmeta.py_SetMetadataExceptionHandlerr*      s    **1!#    c                 "    U R                  XS9  g )Nthread_state)SetMetadataFunc)r'   name_expansion_resultr.   s      r)   _SetMetadataFuncWrapperr1      s    +Gr+   c                   D  ^  \ rS rSrSr\R                  " SS/\S\R                  SSSS\
R                  \
R                  /\
R                  \R                  " 5       /S9r\R                   " SS/S	S
\0 S9r\" \0 S9rU 4S jrS r\" \SSS9SS j5       rS rS rSrU =r$ )SetMetaCommand   z)Implementation of gsutil setmeta command.setmeta	setheader   zh:rRF)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command_helpz(Set metadata on already uploaded objects)	help_namehelp_name_aliases	help_typehelp_one_line_summary	help_textsubcommand_help_textgcloud_commandflag_mapc                 T  > / nU R                    H  u  p#US;   d  M  S/n  O   U R                  U R                  5       5      u  pE/ U l         U R                  U Vs0 s H  ofS _M     snSS9nU R                  USS9n[        U-   U-   U-   n	[        U	0 S9n
[        TU ]  U
5      $ s  snf )N)z-rz-Rz--recursiveT)unsetFrJ   )sub_opts_ParseMetadataHeaders_GetHeaderStringsFromSubOpts_translate_headers_GCLOUD_OBJECTS_UPDATE_COMMANDr   superget_gcloud_storage_args)selfrecursive_flago_	clear_setset_dict	clear_keyclear_flags	set_flagscommandgcloud_storage_map	__class__s              r)   rU   &SetMetaCommand.get_gcloud_storage_args   s    N	
l	'  44))+-I DM))*34)YD)4D * BK'''>I->LG *
 7*+=>> 	5s   B%c                 X   U R                  U R                  5       5      u  pX l        U H  nSU R                  U'   M     U R                  (       d  [        S5      e[	        U R
                  5      S:X  an  U R                  (       d]  [        U R
                  S   5      nUR                  5       (       a  UR                  5       (       d  [        SU R
                  S   -  5      eSU l
        [        U R                  5      U l        [        U R                  U R                   U R"                  U R$                  U R
                  U R                  U R&                  U R(                  / SQS9	n[+        U R                  U R                   U R-                  5       U R
                  U R                  U R&                  U R.                  S	9n U R1                  [2        U[4        SUS
9  U R                  (       d  [        S5      eg! [6         a&  nUR8                  S:X  a  U R;                  5         e SnAff = f)z,Command entry point for the setmeta command. z|gsutil setmeta requires one or more headers to be provided with the -h flag. See "gsutil help setmeta" for more information.r7   r   zURL (%s) must name an objectT)
generationmetadatametageneration)all_versionscontinue_on_errorbucket_listing_fields)rh   
project_id)fail_on_errorseek_ahead_iteratori  Nz+Metadata for some objects could not be set.)rP   rQ   metadata_changer   lenargsrecursion_requestedr   
IsCloudUrlIsObjectr&   r   headerspreconditionsr   command_namedebugr$   
gsutil_apirh   parallel_operationsr   GetSeekAheadGsutilApirk   Applyr1   r*   r   status_WarnServiceAccounts)rV   metadata_minusmetadata_plusheaderurlname_expansion_iteratorrm   r(   s           r)   
RunCommandSetMetaCommand.RunCommand   s   $($>$>))+%-!N ) %'d6" ! FG G 499~4#;#; 1.cnn3<<>>=		!LMM  $D1$,,?D3

		  &&22J	L 9

""$		  &&??$ jj((-#%8	  : ##JKK ! 	
S!!#s   G9 9
H)!H$$H)   )triestimeout_secsc           
      ^   [        XS9nUR                  nU R                  R                  SU5        [        R
                  " [        R                  UR                  5      n[        U R                  R                  U R                  R                  S9nUR                  c  UR                  Ul        UR                  c  UR                  Ul        [        U R                   5      nUR#                  UR$                  S9nU[&        R(                  :X  a  O.U[&        R*                  :X  a  [-        XuSS9  UnSUl        SUl        UR/                  UR0                  UR2                  UUR                  UUR$                  S/S	9  [5        UR6                  [9        [:        R:                  " 5       S
95        g)zSets metadata on an object.

Args:
  name_expansion_result: NameExpansionResult describing target object.
  thread_state: gsutil Cloud API instance to use for the operation.
r-   zSetting metadata on %s...)	gen_matchmeta_gen_matchN)providerT)overrideid)re   ru   r   fields)message_time)r   expanded_storage_urlr$   infor   JsonToMessageapitools_messagesObjectexpanded_resultr
   ru   r   r   re   rg   r   rn   GetApiSelectorschemer   XMLJSONr   PatchObjectMetadatabucket_nameobject_name_PutToQueueWithTimeoutstatus_queuer   time)	rV   r0   r.   rx   exp_src_urlcloud_obj_metadataru   patch_obj_metadataapis	            r)   r/   SetMetaCommand.SetMetadataFunc  s    %TEJ'<<KKK0+>!//  "7"G"GI "$$..))88:M & 2 = =m##+%7%F%Fm" 343G3GH

#
#[-?-?
#
@C koo
	  	 +$O-&*#*.'"";#:#:#.#:#:#5.9.D.D1>,7,>,>+/& # 2 :22*		DFr+   c                     U R                   (       d  / $ / nU R                    H5  u  p#US:X  d  M  SU;   d  SU;   a  [        S5      eUR                  U5        M7     U$ )a  Gets header values from after the "setmeta" part of the command.

Example: $ gsutil -h not:parsed setmeta is:parsed gs://bucket/object
           -> ["is:parsed"]

Returns:
  List[str]: Headers without the "-h" but not yet split on colons.

Raises:
  CommandException Found canned ACL.
z-hz
x-goog-aclz	x-amz-aclzWgsutil setmeta no longer allows canned ACLs. Use gsutil acl set ... to set canned ACLs.)rO   r   append)rV   rt   rX   as       r)   rQ   +SetMetaCommand._GetHeaderStringsFromSubOpts@  sb     ==iG	
d1q 0 ,- - 	q  Nr+   c                 P   [        5       n[        5       n0 n0 nSnSnSnSn	U H  n
U
R                  S5      nUu  pn[        U5        UR                  5       n[	        U5      nU(       d3  U[
        ;  a)  [        SU< S[        [        [
        5      5      < 35      eU(       a3  U(       a  XU'   US-  nM  [        X5        [        U5      nXU'   US-  nM  U(       a  UR                  U5        U	S-  n	M  UR                  U5        US-  nM     U[        U5      :w  dZ  U[        U5      :w  dK  U[        U5      :w  d<  U	[        U5      :w  d-  UR                  [        UR                  5       5      5      (       a  [        S5      eUR                  U5        UR                  U5        X$4$ )zValidates and parses metadata changes from the headers argument.

Args:
  headers: Header dict to validate and parse.

Returns:
  (metadata_plus, metadata_minus): Tuple of header sets to add and remove.
r   :zInvalid or disallowed header (zF).
Only these fields (plus x-goog-meta-* fields) can be set or unset:
r7   z%Each header must appear at most once.)set	partitionr   lowerr   SETTABLE_FIELDSr   sortedlistr   straddro   intersectionkeysr"   )rV   rt   r~   cust_metadata_minusr   cust_metadata_plusnum_metadata_plus_elemsnum_cust_metadata_plus_elemsnum_metadata_minus_elemsnum_cust_metadata_minus_elemsmd_argpartsr   rY   valuelowercase_headeris_custom_metas                    r)   rP   $SetMetaCommand._ParseMetadataHeadersX  s    UN%M  #$  $%! s#e v%   ..>?n 0 G VD1245 	5
 
',V
$
&!
+
&
 !
/e*%,1(
)
!Q
&
!

!
!&
)
'1
,
'


-
.
"a
'
"U X 	 3}#55$,>(?? C$77%-@)AA##C(:(:(<$=>>DEE+,-.**r+   )r&   rn   ru   rO   N)__name__
__module____qualname____firstlineno____doc__r   CreateCommandSpec	_SYNOPSISr   NO_MAXr   r   r   r   MakeZeroOrMoreCloudURLsArgumentcommand_specHelpSpec_DETAILED_HELP_TEXT	help_specr   rS   r`   rU   r   r   r	   r/   rQ   rP   __static_attributes____classcell__)ra   s   @r)   r3   r3      s    1 **'=
//


 !%%

9
9
;,( $F#) (3
?.=~ 		aa8/F 9/Fb0I+ I+r+   r3   r   );r   
__future__r   r   r   r   r   apitools.base.pyr   gslib.cloud_apir   r	   r
   gslib.commandr   gslib.command_argumentr   gslib.cs_api_mapr   gslib.exceptionr   gslib.name_expansionr   r   gslib.storage_urlr   "gslib.third_party.storage_apitoolsr   r   gslib.thread_messager   gslib.utilsr   r   gslib.utils.cloud_api_helperr   gslib.utils.metadata_utilr   gslib.utils.retry_utilr   gslib.utils.shim_utilr   r   gslib.utils.text_utilr   r   gslib.utils.translation_helperr   r   r   PutToQueueWithTimeoutr   r   r   r   rS   r*   r1   r3    r+   r)   <module>r      s    K & %  '  % 1 1 ) ! 2 ( , 6 ? 2 W 0 ! 2 < < ( 3 2 3 8 = D C3II 	AC P
 "B "HO+W O+r+   