
                            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rSS
KJr  \R$                  R&                  r " S S\5      r " S S\R.                  5      rSS jrS rSS jrg)zCommon ML file upload logic.    )absolute_import)division)unicode_literalsN)storage_api)storage_util)
exceptions)files)zipc                       \ rS rSrSrSrg)MissingStagingBucketException$   zIndicates that a staging bucket was not provided with a local path.

It doesn't inherit from core.exceptions.Error because it should be caught and
re-raised at the call site with an actionable message.
 N__name__
__module____qualname____firstlineno____doc____static_attributes__r       3lib/googlecloudsdk/command_lib/ml_engine/uploads.pyr   r   $   s    r   r   c                       \ rS rSrSrSrg)BadDirectoryError,   z9Indicates that a provided directory for upload was empty.r   Nr   r   r   r   r   r   ,   s    Ar   r   c                    [         R                  " [        R                  S9nU  H  u  pEUR	                  U5        M     Ub!  SR                  X#R                  5       /5      nOUR                  5       n[        R                  " 5       n/ nU  H}  u  pH[        R                  R                  USR                  X(/5      5      n	UR                  XI5      n
UR                  SR                  SU
R                  U
R                  /5      5        M     U$ )a  Uploads files at the local path to a specifically prefixed location.

The prefix is 'cloudmldist/<current timestamp>'.

Args:
  upload_pairs: [(str, str)]. Pairs of absolute paths to local files to upload
    and corresponding path in Cloud Storage (that goes after the prefix). For
    example, ('/path/foo', 'bar') will upload '/path/foo' to '<prefix>/bar' in
    Cloud Storage.
  bucket_ref: storage_util.BucketReference.
    Files will be uploaded to this bucket.
  gs_prefix: str. Prefix to the GCS Path where files will be uploaded.
Returns:
  [str]. A list of fully qualified gcs paths for the uploaded files, in the
    same order they were provided.
)	algorithm/zgs:/)
file_utilsChecksumhashlibsha256AddFileContentsjoin	HexDigestr   StorageClientr   ObjectReferenceFromBucketRefCopyFileToGCSappendbucketname)upload_pairs
bucket_ref	gs_prefixchecksum
local_path_storage_clientdestsuploaded_pathobj_refobjs              r   UploadFilesr7   0   s    $   7>>:(#mjZ( $ )%7%7%9:;I""$I,,..
%#/j**88CHHi78:G

&
&z
;C	LL63::sxx89:	 $0
 
,r   c           	         / n[         R                  " [        R                  " U 5      5       HZ  u  p#nU HN  n[         R                  R                  X%5      nUR                  [         R                  R                  X`S95        MP     M\     U$ )aQ  Return all the descendents of root, relative to its path.

For instance, given the following directory structure

    /path/to/root/a
    /path/to/root/a/b
    /path/to/root/c

This function would return `['a', 'a/b', 'c']`.

Args:
  root: str, the path to list descendents of.

Returns:
  list of str, the paths in the given directory.
)start)oswalksix	text_typepathr#   r)   relpath)rootpathsdirpathr1   	filenamesfilenameabs_paths          r   _GetFilesRelativerF   U   sh    " %!wws}}T':;g)g0hll277??8?89   < 
,r   c                 0   U R                  S5      (       a  U $ Uc  [        S5      e[        R                  R	                  U 5      (       d  [        SR                  U 5      5      e[        U 5      nU Vs/ s H  oDR                  [        S5      PM     nnU Vs/ s H  n[        R                  X/5      PM     nn[        [        [        Xe5      5      UUS9nU(       d  [        SR                  U 5      5      eUS   S[        US   5      *  $ s  snf s  snf )	a"  Uploads path to Cloud Storage if it isn't already there.

Translates local file system paths to Cloud Storage-style paths (i.e. using
the Unix path separator '/').

Args:
  path: str, the path to the directory. Can be a Cloud Storage ("gs://") path
    or a local filesystem path (no protocol).
  staging_bucket: storage_util.BucketReference or None. If the path is local,
    the bucket to which it should be uploaded.
  gs_prefix: str, prefix for the directory within the staging bucket.

Returns:
  str, a Cloud Storage path where the directory has been uploaded (possibly
    prior to the execution of this function).

Raises:
  MissingStagingBucketException: if `path` is a local path, but staging_bucket
    isn't found.
  BadDirectoryError: if the given directory couldn't be found or is empty.
zgs://NzKThe path provided was local, but no staging bucket for upload was provided.z[{}] is not a valid directory.r   )r.   zYCannot upload contents of directory [{}] to Google Cloud Storage; directory has no files.r   )
startswithr   r:   r>   isdirr   formatrF   replace	_PATH_SEPr#   r7   listr
   len)r>   staging_bucketr.   r	   fr3   
full_filesuploaded_pathss           r   UploadDirectoryIfNecessaryrS   n   s   , 
__WK
'	  
t		
<CCDI
JJ
D
!% /4
4e99Y$e%
43895a	y)5*9tC
$:;-)24. 

	""(&,0 0
 
	?Sq]N	++ 59s   4D D)N)NN)r   
__future__r   r   r   r    r:   googlecloudsdk.api_lib.storager   r   googlecloudsdk.corer   googlecloudsdk.core.utilr	   r   r<   	six.movesr
   r>   seprL   	Exceptionr   Errorr   r7   rF   rS   r   r   r   <module>r\      sj    # &  '  	 6 7 * 8 
  GGKK	I B
(( B"J24,r   