
    =                     0   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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\R,                  5      r " S S\R,                  5      r " S S5      r " S S5      rg)z(Module for handling recursive expansion.    )absolute_import)division)unicode_literalsN)	cloud_api)errors)folder_util)plurality_checkable_iterator)storage_url)wildcard_iterator)resource_reference)log)
properties)debug_outputc                   $    \ rS rSrSrSrSrSrSrg)BucketSetting$   z9An enum saying whether or not to include matched buckets._yes_no_no_with_error N)	__name__
__module____qualname____firstlineno____doc__YESNONO_WITH_ERROR__static_attributes__r       8lib/googlecloudsdk/command_lib/storage/name_expansion.pyr   r   $   s    A#""-r    r   c                   $    \ rS rSrSrSrSrSrSrg)RecursionSetting,   z5An enum saying whether or not recursion is requested.r   _no_with_warningr   r   N)	r   r   r   r   r   r   NO_WITH_WARNINGr   r   r   r    r!   r#   r#   ,   s    ="&/#r    r#   c                      \ rS rSrSr\R                  R                  S\R                  \
R                  R                  \
R                  R                  \R                  R                  SSS\R"                  S4S jr\
R                  R                  \
R                  R                  4S jr\S 5       rS	 rS
 rS rS rS rS rSrg)NameExpansionIterator3   aj  Expand all urls passed as arguments, and yield NameExpansionResult.

For each url, expands wildcards, object-less bucket names,
subdir bucket names, and directory names, and generates a flat listing of
all the matching objects/files.
The resulting objects/files are wrapped within a NameExpansionResult instance.
See NameExpansionResult docstring for more info.
FTNc                 \   Xpl         [        R                  " U5      U l        X l        X0l        X@l        XPl        X`l        Xl	        Xl
        U
U l        Xl        Uc  [        R                  " 5       U l        OXl        [        R                  " U R!                  5       5      U l        SU l        g)a  Instantiates NameExpansionIterator.

Args:
  urls_iterable (Iterable[str]): The URLs to expand.
  fields_scope (cloud_api.FieldsScope): Determines amount of metadata
    returned by API.
  ignore_symlinks (bool): Skip over symlinks instead of following them.
  include_buckets (BucketSetting): Whether to fetch matched buckets and
    whether to raise an error.
  managed_folder_setting (folder_util.ManagedFolderSetting): Indicates how
    to deal with managed folders.
  folder_setting (folder_util.FolderSetting): Indicates how to deal with
    folders.
  object_state (cloud_api.ObjectState): Versions of objects to query.
  preserve_symlinks (bool): Preserve symlinks instead of following them.
  raise_error_for_unmatched_urls (bool): If True, raises an error if any url
    in `url_found_match_tracker` is unmatched after expansion.
  raise_managed_folder_precondition_errors (bool): If True, raises
    precondition errors from managed folder listing. Otherwise, suppresses
    these errors. This is helpful in commands that list managed folders by
    default.
  recursion_requested (RecursionSetting): Says whether or not recursion is
    requested.
  url_found_match_tracker (OrderedDict|None): Maps top-level URLs to a
    boolean indicating whether they matched resources. Mutated as resources
    are yielded. Reusing a tracker dict across NameExpansionIterators with
    different expansion criteria suppresses unmatched errors if any iterator
    expands a URL.
N)object_stater	   PluralityCheckableIterator_urls_iterator_fields_scope_ignore_symlinks_include_buckets_managed_folder_setting_folder_setting_preserve_symlinks_raise_error_for_unmatched_urls)_raise_managed_folder_precondition_errors_recursion_requestedcollectionsOrderedDict_url_found_match_tracker_get_top_level_iterator_top_level_iterator!_has_multiple_top_level_resources)selfurls_iterablefields_scopeignore_symlinksinclude_bucketsmanaged_folder_settingfolder_settingr+   preserve_symlinksraise_error_for_unmatched_urls(raise_managed_folder_precondition_errorsrecursion_requestedurl_found_match_trackers                r!   __init__NameExpansionIterator.__init__=   s    X %$??N 	 &++#9 )/+I(0 	2 !4&&1&=&=&?d#&=# 	%??((*	
 	
 .2D*r    c                 H   [         R                  " U[        R                  R                  R
                  R                  5       [        R                  R                  R                  :g  U R                  U R                  UUU R                  U R                  U R                  S9	$ )z>Returns get_wildcard_iterator with instance variables as args.)fetch_encrypted_object_hashesr?   r@   rB   rC   r+   rD   rF   )r   get_wildcard_iteratorr   VALUESstoragecheck_hashesGetCheckHashesNEVERvaluer.   r/   r+   r3   r5   )r=   urlrB   rC   s       r!   _get_wildcard_iterator,NameExpansionIterator._get_wildcard_iterator   s     22%%22668%%++112 ''--5%&&11:: r    c                     U R                   c@  U R                  R                  5       =(       d    U R                  R                  5       U l         U R                   $ )aO  Returns if the iterator yields plural items without recursing.

Also returns True if the iterator was created with multiple URLs.
This may not be true if one URL doesn't return anything, but it's
consistent with gsutil and the user's probable intentions.

Returns:
  Boolean indicating if iterator contains multiple top-level sources.
)r<   r-   	is_pluralr;   r=   s    r!    has_multiple_top_level_resources6NameExpansionIterator.has_multiple_top_level_resources   sO     --5



'
'
) 2%%//1 , 111r    c              #     #    U R                    GH.  n[        R                  " U5      n[        U[        R                  5      (       at  UR                  5       (       a_  U R                  [        R                  LaB  U R                  [        R                  L a%  [        R                  " SR                  U5      5      eU R                  R!                  US5      U R                  U'   U R"                  [$        R&                  R(                  [$        R&                  R*                  1;   a8  U R                  [        R                  L a  [$        R&                  R,                  nOU R"                  nU R.                  nU R1                  UUUS9 H  nU R"                  [$        R&                  R*                  L a  [        U[2        R4                  5      (       dF  U R.                  [$        R6                  R*                  L a!  [        U[2        R4                  5      (       a  M  XR9                  UUR                  U5      4v   M     GM1     g7f)z<Iterates over user-entered URLs and does initial processing.z!Expected object URL. Received: {}FrB   rC   N)r-   r
   storage_url_from_string
isinstanceCloudUrl	is_bucketr6   r#   r   r0   r   r   r   InvalidUrlErrorformatr9   getr1   r   ManagedFolderSettingLIST_WITH_OBJECTSLIST_WITHOUT_OBJECTSLIST_AS_PREFIXESr2   rV   r   ObjectResourceFolderSetting_get_name_expansion_result)r=   rU   original_storage_url(wildcard_iterator_managed_folder_setting wildcard_iterator_folder_settingresources         r!   r:   -NameExpansionIterator._get_top_level_iterator   s    ""(@@E
);+?+?
@
@",,..''/?/C/CC##}'B'BB$$/66s;
 	
 ,0+H+H+L+L
u,d##C(
 
&
&..@@..CC
 ''+;+?+??
 ,,== 	1 483O3O0)-)=)=&11
!I9 2 ( ((//DDE8%7%F%FGG  ((==>8%7%F%FGG
2283;3G3G3GI I 	IE #s   IIc              #   *  #    UR                   R                  R                  S5      nU R                  UR                  U R
                  U R                  S9nU H5  nU R                  XAR                   R                  UR                  5      v   M7     g 7f)Nz**r^   )	rp   r
   joinrV   
url_stringr1   r2   rl   original_url)r=   parent_name_expansion_resultnew_storage_urlchild_resourceschild_resources        r!   _get_nested_objects_iterator2NameExpansionIterator._get_nested_objects_iterator   s     2;;GGLLO11""#;;++ 2 O
 *++
??KK
&
3
35 5 *s   BBc                     U R                   [        R                  R                  L =(       d    UR                  nU(       d0  [
        R                  " UR
                  R                  5      nXQl        [        XU5      $ )zEReturns a NameExpansionResult, removing generations when appropriate.)	r+   r   ObjectStateLIVE_AND_NONCURRENT
generationr
   r_   versionless_url_stringNameExpansionResult)r=   rp   expanded_urlru   keep_generation_in_urlrw   s         r!   rl   0NameExpansionIterator._get_name_expansion_result   sh     	Y22FFF 	#""  "#;;



5
57o,x|DDr    c                    U R                   (       d  g U R                  R                  5        VVs/ s H  u  pU(       a  M  UPM     nnnU(       a4  [        R                  " SR                  SR                  U5      5      5      eg s  snnf )Nz2The following URLs matched no objects or files:
{}
)r4   r9   itemsr   rc   rd   rs   )r=   rU   found_matchnon_matching_urlss       r!   &_raise_no_url_match_error_if_necessary<NameExpansionIterator._raise_no_url_match_error_if_necessary   s    // %)$A$A$G$G$I$I  	$I   ""
?
F
Fii)*,- - 	s   BBc                     U R                   (       aH  [        U[        R                  5      (       a(  UR                  (       a  [
        R                  " S5      eg g g )NzDMultiple URL strings are not supported when transferring from stdin.)r<   r`   r
   FileUrlis_stdior   Error)r=   r   s     r!   ._raise_error_if_multiple_sources_include_stdinDNameExpansionIterator._raise_error_if_multiple_sources_include_stdin  sO    ..:k))4+ 4+/;/D/DLL  0E4+.r    c              #   f  #    U R                   R                  5       U l        U R                    GHm  u  pU R                  UR                  5        U R
                  [        R                  L =(       a$    UR                  R                  R                  5       nU R                  [        R                  R                  [        R                  R                  1;   =(       a$    [!        UR                  ["        R$                  5      nU R&                  [        R(                  R                  [        R(                  R*                  1;   =(       a$    [!        UR                  ["        R,                  5      n["        R.                  " UR                  5      (       a  U(       d  U(       d  U(       a  SU R0                  U'   Uv   ["        R.                  " UR                  5      (       d  GM  U R2                  [4        R                  L a.  U R7                  U5       H  nSU R0                  U'   Uv   M     GM   U(       a  GM
  U(       a  GM  U(       a  GM  U R2                  [4        R8                  L d  GM>  [:        R<                  " SR?                  UR                  5      5        GMp     U RA                  5         g7f)zIterates over each URL in self._urls_iterator and yield the expanded result.

Yields:
  NameExpansionResult instance.

Raises:
  InvalidUrlError: No matching objects found.
TzDOmitting {} because it is a container, and recursion is not enabled.N)!r;   rY   r<   r   r   r0   r   r   rp   r
   rb   r1   r   rf   rg   rh   r`   r   ManagedFolderResourcer2   rk   LIST_AS_FOLDERSFolderResource!is_container_or_has_container_urlr9   r6   r#   rz   r&   r   warningrd   r   )r=   	input_urlname_expansion_resultshould_return_bucketshould_return_managed_foldershould_return_foldernested_name_expansion_results          r!   __iter__NameExpansionIterator.__iter__  s4     .2-E-E-O-O .D*,0,D,D(	
99

,
,. "22m6G6GG 

(
(
4
4
>
>
@  &*%A%A

*
*
<
<

*
*
?
?F & & 

(
(

2
2 # "11

#
#
8
8

#
#
3
36   

(
(

+
+  !BB#,,  ")!37%%i0##		=	=

(
(
* 
*$$(8(<(<<.2.O.O#/%*7;D)))4../% ! ++##&&*:*J*JJ KK ++161::,<=c -Ej 	//1s&   GJ1#AJ18J1J1J1,AJ1)r.   r2   r<   r/   r0   r1   r3   r4   r5   r6   r;   r9   r-   r+   )r   r   r   r   r   r   FieldsScopeNO_ACLr   r   r   rf   DO_NOT_LISTrk   r}   LIVEr#   r&   rI   rV   propertyr[   r:   rz   rl   r   r   r   r   r   r    r!   r(   r(   3   s     ((//#&&(==II ..::((--%)/3*::"F2V )==II ..::	0 2 2"5In5
E-@2r    r(   c                   0    \ rS rSrSrS rS rS rS rSr	g)	r   iV  a  Holds one fully expanded result from iterating over NameExpansionIterator.

This class is required to pass the expanded_url information to the caller.
This information is required for cp and rsync command, where the destination
name is determined based on the expanded source url.
For example, let's say we have the following objects:
gs://bucket/dir1/a.txt
gs://bucket/dir1/b/c.txt

If we run the following command:
cp -r gs://bucket/dir* foo

We would need to know that gs://bucket/dir* was expanded to gs://bucket/dir1
so that we can determine destination paths (foo/a.txt, foo/b/c.txt) assuming
that foo does not exist.

Attributes:
  resource (Resource): Yielded by the WildcardIterator.
  expanded_url (StorageUrl): The expanded wildcard url.
  original_url (StorageUrl): Pre-expanded URL.
c                 (    Xl         X l        X0l        g)a  Initialize NameExpansionResult.

Args:
  resource (resource_reference.Resource): Yielded by the WildcardIterator.
  expanded_url (StorageUrl): The expanded url string without any wildcard.
    This value should preserve generation even if not available in
    resource.storage_url. The versionless version of this should be same
    as resource.storage_url if recursion was not requested. This field is
    intended for only the cp and rsync commands.
  original_url (StorageUrl): Pre-expanded URL. Useful for knowing intention.
N)rp   r   ru   )r=   rp   r   ru   s       r!   rI   NameExpansionResult.__init__m  s     M$$r    c                 .    [         R                  " U 5      $ N)r   generic_reprrZ   s    r!   __repr__NameExpansionResult.__repr__}  s    $$T**r    c                 B    U R                   R                  R                  $ r   )rp   r
   rt   rZ   s    r!   __str__NameExpansionResult.__str__  s    ==$$///r    c                     [        U[        U 5      5      (       d  [        $ U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r   )r`   typeNotImplementedrp   r   )r=   others     r!   __eq__NameExpansionResult.__eq__  sI    eT$Z(( MMU^^+ 8!!U%7%779r    )r   ru   rp   N)
r   r   r   r   r   rI   r   r   r   r   r   r    r!   r   r   V  s    ,% +09r    r   )r   
__future__r   r   r   r7   enumgooglecloudsdk.api_lib.storager   "googlecloudsdk.command_lib.storager   r   r	   r
   r   ,googlecloudsdk.command_lib.storage.resourcesr   googlecloudsdk.corer   r   googlecloudsdk.core.utilr   Enumr   r#   r(   r   r   r    r!   <module>r      sn    / &  '   4 5 : K : @ K # * 1#DII #tyy `2 `2F	39 39r    