
                            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mZ ddlm	Z	 ddl
mZ dd	lmZ ddlZdd
lmZ ej$                  j&                  Z G d de      Z G d dej.                        ZddZd ZddZy)zCommon ML file upload logic.    )absolute_import)division)unicode_literalsN)storage_api)storage_util)
exceptions)files)zipc                       e Zd ZdZy)MissingStagingBucketExceptionzIndicates 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____doc__     3lib/googlecloudsdk/command_lib/ml_engine/uploads.pyr   r   $   s    r   r   c                       e Zd ZdZy)BadDirectoryErrorz9Indicates that a provided directory for upload was empty.Nr   r   r   r   r   r   ,   s    Ar   r   c                     t        j                  t        j                        }| D ]  \  }}|j	                  |        |"dj                  ||j                         g      }n|j                         }t        j                         }g }| D ]  \  }}t        j                  j                  |dj                  ||g            }	|j                  ||	      }
|j                  dj                  d|
j                  |
j                  g              |S )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   UploadFilesr3   0   s    $   7>>:(#mj!Z( $ )X%7%7%9:;I""$I,,..
%#/j-**88CHHi78:G

&
&z7
;C	LL63::sxx89:	 $0
 
,r   c                    g }t        j                  t        j                  |             D ]]  \  }}}|D ]R  }t         j                  j                  ||      }|j                  t         j                  j                  ||              T _ |S )ae  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dirpathr-   	filenamesfilenameabs_paths          r   _GetFilesRelativerB   U   sn    " %!wws}}T':;gq)gx0hll277??84?89   < 
,r   c                    | j                  d      r| S |t        d      t        j                  j	                  |       st        dj                  |             t        |       }|D cg c]  }|j                  t        d       }}|D cg c]  }t        j                  | |g       }}t        t        t        ||            ||      }|st        dj                  |             |d   dt        |d           S c c}w c c}w )	aB  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   r6   r:   isdirr   formatrB   replace	_PATH_SEPr   r3   listr
   len)r:   staging_bucketr*   r	   fr/   
full_filesuploaded_pathss           r   UploadDirectoryIfNecessaryrO   n   s   , 
__WK
'	  
t	
<CCDI
JJ
D
!% /4
4e199Y$e%
43895a	ay)5*9tC
E$:;-)24. 

	""(&,0 0
 
	?Sq]N	++ 59s   )C>D)N)NN)r   
__future__r   r   r   r   r6   googlecloudsdk.api_lib.storager   r   googlecloudsdk.corer   googlecloudsdk.core.utilr	   r   r8   	six.movesr
   r:   seprH   	Exceptionr   Errorr   r3   rB   rO   r   r   r   <module>rX      sj    # &  '  	 6 7 * 8 
  GGKK	I B
(( B"J24,r   