o
    .&ßaj  ã                   @   sš   d dl Z d dlZd dl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 e e¡ZG dd„ deƒZG dd„ deƒZG d	d
„ d
e
ƒZdS )é    N)ÚTransferManager)ÚBaseSubscriber)Úcollections_abcc                   @   s   e Zd Zdd„ ZdZdS )ÚNoSuchBucketErrorc                 K   s(   | j jdi |¤Ž}t | |¡ || _d S )N© )ÚfmtÚformatÚ	ExceptionÚ__init__Úkwargs)Úselfr   Úmsgr   r   úB/usr/lib/python3/dist-packages/awscli/customizations/s3uploader.pyr
      s   
zNoSuchBucketError.__init__zaS3 Bucket does not exist. Execute the command to create a new bucket
aws s3 mb s3://{bucket_name}N)Ú__name__Ú
__module__Ú__qualname__r
   r   r   r   r   r   r      s    r   c                   @   sp   e Zd ZdZedd„ ƒZejdd„ ƒZ				ddd„Zd	d
„ Zddd„Z	dd„ Z
dd„ Zdd„ Zddd„ZdS )Ú
S3Uploaderz–
    Class to upload objects to S3 bucket that use versioning. If bucket
    does not already use versioning, this class will turn on versioning.
    c                 C   s   | j S )zO
        Metadata to attach to the object(s) uploaded by the uploader.
        )Ú_artifact_metadata)r   r   r   r   Úartifact_metadata1   s   zS3Uploader.artifact_metadatac                 C   s&   |d urt |tjƒstdƒ‚|| _d S )Nz(Artifact metadata should be in dict type)Ú
isinstancer   ÚMappingÚ	TypeErrorr   )r   Úvalr   r   r   r   8   s   
NFc                 C   sB   || _ || _|p	d | _|| _|| _|| _|st| jƒ| _d | _d S ©N)Úbucket_nameÚprefixÚ
kms_key_idÚforce_uploadÚs3Útransfer_managerr   r   )r   Ú	s3_clientr   r   r   r   r   r   r   r   r
   >   s   

zS3Uploader.__init__c              
   C   sö   | j rt| j ƒdkrd | j |¡}| js&|  |¡r&t d |¡¡ |  |¡S z3ddi}| jr7d|d< | j|d< | j	r?| j	|d< t
||ƒ}| j || j|||g¡}| ¡  |  |¡W S  tjjyz } z|jd	 d
 }|dkrtt| jd�‚|‚d}~ww )zÄ
        Uploads given file to S3
        :param file_name: Path to the file that will be uploaded
        :param remote_path:  be uploaded
        :return: VersionId of the latest upload
        r   z{0}/{1}z:File with same data already exists at {0}. Skipping uploadÚServerSideEncryptionÚAES256zaws:kmsÚSSEKMSKeyIdÚMetadataÚErrorÚCodeÚNoSuchBucket)r   N)r   Úlenr   r   Úfile_existsÚLOGÚdebugÚmake_urlr   r   ÚProgressPercentager   Úuploadr   ÚresultÚbotocoreÚ
exceptionsÚClientErrorÚresponser   )r   Ú	file_nameÚremote_pathÚadditional_argsÚprint_progress_callbackÚfutureÚexÚ
error_coder   r   r   r.   P   s@   ÿ
ÿ

ÿü€üzS3Uploader.uploadc                 C   s*   |   |¡}|}|r|d | }|  ||¡S )zù
        Makes and returns name of the S3 object based on the file's MD5 sum

        :param file_name: file to upload
        :param extension: String of file extension to append to the object
        :return: S3 URL of the uploaded object
        Ú.)Úfile_checksumr.   )r   r4   Ú	extensionÚfilemd5r5   r   r   r   Úupload_with_dedup�   s
   
zS3Uploader.upload_with_dedupc                 C   s2   z| j j| j|d� W dS  tjjy   Y dS w )z¥
        Check if the file we are trying to upload already exists in S3

        :param remote_path:
        :return: True, if file exists. False, otherwise
        )ÚBucketÚKeyTF)r   Úhead_objectr   r0   r1   r2   )r   r5   r   r   r   r)   –   s   ÿýzS3Uploader.file_existsc                 C   s   d  | j|¡S )Nzs3://{0}/{1})r   r   )r   Úobj_pathr   r   r   r,   ¨   s   ÿzS3Uploader.make_urlc                 C   s”   t |dƒ�;}t ¡ }d}| ¡ }| d¡ | |¡}t|ƒdkr0| |¡ | |¡}t|ƒdks | |¡ | ¡ W  d   ƒ S 1 sCw   Y  d S )NÚrbi   r   )	ÚopenÚhashlibÚmd5ÚtellÚseekÚreadr(   ÚupdateÚ	hexdigest)r   r4   Úfile_handlerG   Ú
block_sizeÚcurposÚbufr   r   r   r<   ¬   s   



þ
$ïzS3Uploader.file_checksumc                 C   s.   | j jj}d || j|¡}|rd ||¡}|S )z§
            This link describes the format of Path Style URLs
            http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro
        z{0}/{1}/{2}z{0}?versionId={1})r   ÚmetaÚendpoint_urlr   r   )r   ÚkeyÚversionÚbaser/   r   r   r   Úto_path_style_s3_urlÁ   s
   
zS3Uploader.to_path_style_s3_url)NNFNr   )r   r   r   Ú__doc__Úpropertyr   Úsetterr
   r.   r?   r)   r,   r<   rV   r   r   r   r   r   +   s"    


û
1r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )r-   c                 C   s2   || _ || _ttj |¡ƒ| _d| _t 	¡ | _
d S )Nr   )Ú	_filenameÚ_remote_pathÚfloatÚosÚpathÚgetsizeÚ_sizeÚ_seen_so_farÚ	threadingÚLockÚ_lock)r   Úfilenamer5   r   r   r   r
   Ñ   s
   zProgressPercentage.__init__c                 K   sr   | j �, |  j|7  _| j| j d }tj d| j| j| j|f ¡ tj ¡  W d   ƒ d S 1 s2w   Y  d S )Néd   z#Uploading to %s  %s / %s  (%.2f%%))rd   ra   r`   ÚsysÚstdoutÚwriter[   Úflush)r   r8   Úbytes_transferredr   Ú
percentager   r   r   Úon_progressØ   s   ÿÿÿ"ùzProgressPercentage.on_progressN)r   r   r   r
   rm   r   r   r   r   r-   Î   s    r-   )rF   Úloggingrb   r]   rg   r0   Úbotocore.exceptionsÚs3transfer.managerr   Ús3transfer.subscribersr   Úawscli.compatr   Ú	getLoggerr   r*   r	   r   Úobjectr   r-   r   r   r   r   Ú<module>   s   
 $