
    G'                         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Z G d
 d ej                   ej"                              Z G d de      Z G d de      Zy)z1Utilities for expanding wildcarded GCS pathnames.    )absolute_import)division)unicode_literalsN)storage_api)storage_util)log)
propertiesc                   <   e Zd ZdZdZed        Zd Zej                  d        Z
ej                  d        Zej                  d        Zej                  d        Zej                  d	        Zej                  d
        Zed        Zd Zd Zd Zd Zd Zd Zd Zy)PathExpanderz0Abstract base class for path wildcard expansion.z[*?[]c                 L    |j                  d      r
t               S t               S Ngs://)
startswithGCSPathExpanderLocalPathExpanderclspaths     3lib/googlecloudsdk/command_lib/storage/expansion.pyForPathzPathExpander.ForPath(   s     w    c                     || _         y N)_sep)selfseps     r   __init__zPathExpander.__init__.   s	    DIr   c                      y r    r   r   s     r   AbsPathzPathExpander.AbsPath1       r   c                      y r   r   r    s     r   IsFilezPathExpander.IsFile5   r"   r   c                      y r   r   r    s     r   IsDirzPathExpander.IsDir9   r"   r   c                      y r   r   r    s     r   ExistszPathExpander.Exists=   r"   r   c                      y r   r   r    s     r   ListDirzPathExpander.ListDirA   r"   r   c                      y r   r   r   path1path2s      r   JoinzPathExpander.JoinE   r"   r   c                 \    t        t        j                  t        j                  |            S r   )boolresearchr   EXPANSION_CHARSr   s     r   HasExpansionzPathExpander.HasExpansionI   s    		,66=>>r   c                 :   t               }t               }| j                  | j                  |            D ]@  }|j                  | j                        r|j                  |       0|j                  |       B | j                  |      r|j                          ||fS )a  Expand the given path that contains wildcard characters.

    Args:
      path: str, The path to expand.

    Returns:
      ({str}, {str}), A tuple of the sets of files and directories that match
      the wildcard path. All returned paths are absolute.
    )set_Globr!   endswithr   addIsEndRecursiveclear)r   r   filesdirsps        r   
ExpandPathzPathExpander.ExpandPathM   sy     EE5DZZT*+	
DII			!	 ,
 4  jjl4=r   c                     t               }t               }|D ]a  }| j                  |      \  }}|s'|s%t        j                  dj	                  |             @|j                  |       |j                  |       c ||fS )Nz[{}] does not match any paths.)r7   r@   r   warningformatupdate)r   pathsr=   r>   r?   current_filescurrent_dirss          r   ExpandPathszPathExpander.ExpandPathse   sq    EE5D&*ooa&8#}l<4;;A>?ll=!
kk,  $;r   c                 >    |j                  | j                  dz         S Nz**r9   r   r    s     r   r;   zPathExpander.IsEndRecursiveq   s    ==T)**r   c                 8    |j                  | j                        S r   rK   r    s     r   	IsDirLikezPathExpander.IsDirLiket   s    ==##r   c              #   v  K   | j                  |      s%| j                  |      r| j                  |       y t        j                  j                  |      \  }}| j                  |      }| j                  |      D ]  }|s8| j                  ||      }| j                  |      s)| j                  |       =|dk(  r*| j                  |      D ]  }| j                  |        lt        j                  | j                  |      |      D ]%  }| j                  | j                  ||             '  y wrJ   )r5   r(   _FormatPathosr   splitr8   r/   _RecursiveDirListfnmatchfilterr*   )r   r   dir_pathbasenamehas_basename_expansionexpanded_dir_pathns          r   r8   zPathExpander._Globw   s    T"	T	t$$t,Hh!..x8!ZZ1#yy*H5;;t  &
&t))*;<a""1%% = >>ll,-a ""499->#BCC 2s   B#D9&BD9c              #      K   | j                  |      D ]2  }| j                  ||      }| | j                  |      D ]  }|  4 y wr   )r*   r/   rR   )r   rU   rY   r   xs        r   rR   zPathExpander._RecursiveDirList   sH     \\(#YYx#dj%%d+! , $s   AA
c                 |    | j                  |      r*|j                  | j                        s|| j                  z   }|S r   )r&   r9   r   r    s     r   rO   zPathExpander._FormatPath   s0    zz$dii 8DIIdKr   N)__name__
__module____qualname____doc__r4   classmethodr   r   abcabstractmethodr!   r$   r&   r(   r*   r/   r5   r@   rH   r;   rM   r8   rR   rO   r   r   r   r   r   #   s    8/ 
 	 	 	 	 	 	 	 	 	 	 	 	 ? ?0
+$D.r   r   c                   F     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
 xZS )	r   z3Implements path expansion for the local filesystem.c                 H    t         t        |   t        j                         y r   )superr   r   rP   r   r   	__class__s    r   r   zLocalPathExpander.__init__   s    	
T+BFF3r   c                 @    t         j                  j                  |      S r   )rP   r   abspathr    s     r   r!   zLocalPathExpander.AbsPath   s    77??4  r   c                 @    t         j                  j                  |      S r   )rP   r   isfiler    s     r   r$   zLocalPathExpander.IsFile       77>>$r   c                 @    t         j                  j                  |      S r   )rP   r   isdirr    s     r   r&   zLocalPathExpander.IsDir   s    77==r   c                 @    t         j                  j                  |      S r   )rP   r   existsr    s     r   r(   zLocalPathExpander.Exists   rm   r   c                 d    	 t        j                  |      S # t         j                  $ r g cY S w xY wr   )rP   listdirerrorr    s     r   r*   zLocalPathExpander.ListDir   s.    ZZ88 is    //c                 B    t         j                  j                  ||      S r   )rP   r   joinr,   s      r   r/   zLocalPathExpander.Join   s    77<<u%%r   )r]   r^   r_   r`   r   r!   r$   r&   r(   r*   r/   __classcell__rh   s   @r   r   r      s)    ;4!  &r   r   c                   t     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Z fdZ xZS )r   z?Implements path expansion for gs:// formatted resource strings.c                 z    t         t        |   d       t        j                         | _        i | _        i | _        y )N/)rf   r   r   r   StorageClient_client_objects_object_detailsrg   s    r   r   zGCSPathExpander.__init__   s1    	/4)#.,,.DLDMDr   c                     g }|D ]5  }| j                  |      \  }}|r|n|dz   }|j                  |||df       7 t        |d       }|D cg c]  }|d   	 c}S c c}w )a-  Gets all the details for the given paths and returns them sorted.

    Args:
      object_paths: [str], A list of gs:// object or directory paths.

    Returns:
      [{path, data}], A list of dicts with the keys path and data. Path is the
      gs:// path to the object or directory. Object paths will not end in a '/'
      and directory paths will. The data is either a storage.Object message (for
      objects) or a storage_util.ObjectReference for directories. The sort
      order is alphabetical with all directories first and then all objects.
    r{   )r   datac                     | d   | d   d   fS )Nr      r   r   )os    r   <lambda>z8GCSPathExpander.GetSortedObjectDetails.<locals>.<lambda>   s    qtQqT&\.Br   )keyr   )_GetObjectDetailsappendsorted)r   object_pathsall_datar   is_objr   ds          r   GetSortedObjectDetailsz&GCSPathExpander.GetSortedObjectDetails   su     H++D1lfdTdoovd;<= 
 h$BCH"#(QAaD(###s   Ac                     | j                   j                  |      }|rd|fS dt        j                  j	                  |d      fS )ak  Gets the actual object data for a given GCS path.

    Args:
      object_path: str, The gs:// path to an object or directory.

    Returns:
      (bool, data), Where element 0 is True if the path is an object, False if
      a directory and where data is either a storage.Object message (for
      objects) or a storage_util.ObjectReference for directories.
    TFallow_empty_object)r   getr   ObjectReferenceFromUrl)r   object_pathdetailss      r   r   z!GCSPathExpander._GetObjectDetails   sS     ""&&{3G7] L0088
$ 9 0 0 0r   c                 >    |j                  d      st        d      |S )Nr   z0GCS paths must be absolute (starting with gs://))r   
ValueErrorr    s     r   r!   zGCSPathExpander.AbsPath   s    ??7#IJJKr   c                 8    | j                  |      \  }}|xr | S r   _Existsr   r   rq   is_dirs       r   r$   zGCSPathExpander.IsFile   s!    \\$'NFF &j r   c                 6    | j                  |      \  }}|xr |S r   r   r   s       r   r&   zGCSPathExpander.IsDir   s    \\$'NFFfr   c                 .    | j                  |      \  }}|S r   r   )r   r   rq   _s       r   r(   zGCSPathExpander.Exists   s    T"IFAMr   c                    | j                  |      ry|j                  d      }t        j                  j	                  |d      }| j                  |j                         |j                  | j                  v r|j                  sy|j                  | j                  |j                     v ry| j                  |j                        }| j                  |j                     D ]  }|j                  |      s y y)N)TTr{   Tr   )TF)FF)_IsRootrstripr   r   r   _LoadObjectsIfMissing
bucket_refbucketr~   name_GetDirStringr   )r   r   obj_refdir_nameis        r   r   zGCSPathExpander._Exists   s    ||D;;sD**22 3 'Gw112~~&\\	w~~6	6##GLL1h}}W^^,!<<! - r   c              #     K   | j                  |      rb| j                  j                  t        j                  j
                  j                  j                  d            D ]  }|j                    y t        j                  j                  |d      }| j                  |j                         | j                  |j                        }t        |      }t!               }| j"                  |j$                     D ]Q  }|j'                  |      s||d  }|j)                  | j*                        d   }	|	|vs=|j-                  |	       |	 S y w)NT)required)projectr   r   )r   r}   ListBucketsr	   VALUEScorer   Getr   r   r   r   r   r   r   lenr7   r~   r   r   rQ   r   r:   )
r   r   br   r   parent_dir_lengthseenobj_namesuffixresults
             r   r*   zGCSPathExpander.ListDir  s!    ||D ||''##((0044d4C ( E!ffE **22 3 'Gw112!!',,/HH5DMM'..1			X	&+,-dii(+
((6
, 2s   DE'E8Ec                     | j                  |      rd|j                  | j                        z   S |j                  | j                        | j                  z   |j                  | j                        z   S r   )r   lstripr   r   r,   s      r   r/   zGCSPathExpander.Join-  sT    ||Eu||DII...<<		"TYY.dii1HHHr   c                     |dk(  xs |dk(  S )Nr   zgs:r   r    s     r   r   zGCSPathExpander._IsRoot2  s    7?+dem+r   c                     | j                   j                  |j                        }|	 | j                  j	                  |      }t               }|D ]U  }d| j                  |j                  |j                        z   }|| j                  |<   |j                  |j                         W | j                   j                  |j                  t                     j                  |       y y # t        j                  $ r Y y w xY wr   )r~   r   r   r}   
ListBucketr7   r/   r   r   r:   
setdefaultrD   r   BucketNotFoundError)r   r   objectsobject_namesr   	full_paths         r   r   z%GCSPathExpander._LoadObjectsIfMissing5  s    mm
 1 12G,,))*5uA		**;*;QVV DD),-$

y
)


166
"  	  !2!2CE:AA,O  ,, s   B<C' 'C=<C=c                 ^    |r*|j                  | j                        s|| j                  z   S |S r   rK   r    s     r   r   zGCSPathExpander._GetDirStringG  s(    DMM$)),DIIKr   c                 <    t         t        |   |      }|dk(  rdS |S )Nzgs:/r   )rf   r   rO   )r   r   rh   s     r   rO   zGCSPathExpander._FormatPathL  s%    $3D9Dfn7.$.r   )r]   r^   r_   r`   r   r   r   r!   r$   r&   r(   r   r*   r/   r   r   r   rO   rw   rx   s   @r   r   r      sR    G$,0(
!22I
,$
/ /r   r   )r`   
__future__r   r   r   rb   rS   rP   r2   googlecloudsdk.api_lib.storager   r   googlecloudsdk.corer   r	   sixwith_metaclassABCMetar   r   r   r   r   r   <module>r      si     8 &  ' 
  	 	 6 7 # * 
u%3%%ckk2 up& &8W/l W/r   