
    "hj+F                         d dl mZ d dl mZ d dl mZ d dlmZ d dl d dlmZm	Z	m
Z
 d dlmZ d dlmZ d	d
lZd	d
lZej#                  e      Z G d de      Zy
)   )http)
exceptions)Bucket)_make_range_string)*)	to_stringurlsplitparse_qs)BaseCryptoProviderClientError    Nc                        e Zd ZdZ	 	 	 	 	 	 	 	 	 d fd	Zd Z	 	 d fd	ZddZ	 	 	 ddZ	 	 	 	 	 ddZ		 	 	 ddZ
dd	Z	 	 dd
Zd fd	Zd fd	Zd fd	Zd fd	Z	 ddZd Z xZS )CryptoBucketu  用于加密Bucket和Object操作的类，诸如上传、下载Object等。创建、删除bucket的操作需使用Bucket类接口。

    用法（假设Bucket属于杭州区域） ::

        >>> import oss2
        >>> auth = oss2.Auth('your-access-key-id', 'your-access-key-secret')
        >>> bucket = oss2.CryptoBucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'your-bucket', oss2.LocalRsaProvider())
        >>> bucket.put_object('readme.txt', 'content of the object')
        <oss2.models.PutObjectResult object at 0x029B9930>

    :param auth: 包含了用户认证信息的Auth对象
    :type auth: oss2.Auth

    :param str endpoint: 访问域名或者CNAME
    :param str bucket_name: Bucket名
    :param crypto_provider: 客户端加密类。该参数默认为空
    :type crypto_provider: oss2.crypto.BaseCryptoProvider
    :param bool is_cname: 如果endpoint是CNAME则设为True；反之，则为False。

    :param session: 会话。如果是None表示新开会话，非None则复用传入的会话
    :type session: oss2.Session

    :param float connect_timeout: 连接超时时间，以秒为单位。

    :param str app_name: 应用名。该参数不为空，则在User Agent中加入其值。
        注意到，最终这个字符串是要作为HTTP Header的值传输的，所以必须要遵循HTTP标准。

    :param bool enable_crc: 如果开启crc校验则设为True；反之，则为False

    c                    t        |t              st        d      t        j	                  dj                  |             t        t        | #  ||||||||	|
|||       || _	        i | _
        t        j                         | _        | j                  r0t        j                   dz   | j                  z   dz   t"        z   | _        y t        j                   dz   t"        z   | _        y )Nz9crypto_provider must be an instance of BaseCryptoProviderzInit CryptoBucket: {0})proxiesregioncloudbox_idis_path_style/)
isinstancer   r   loggerdebugformatsuperr   __init__crypto_providerupload_contexts	threadingLockupload_contexts_lockapp_namer   
USER_AGENTOSS_ENCRYPTION_CLIENT
user_agent)selfauthendpointbucket_namer   is_cnamesessionconnect_timeoutr"   
enable_crcr   r   r   r   	__class__s                 P/root/.hermes/SkillClaw/.venv/lib/python3.12/site-packages/oss2/crypto_bucket.pyr   zCryptoBucket.__init__2   s     /+=>YZZ-44[ABlD*4;RY[jlt+5wvcn  @M 	+ 	N  /!$-NN$4!=="oo3dmmCcILaaDO"oo36KKDO    c                 T    d|vr| j                   |d<   y |dxx   dt        z   z  cc<   y )Nz
User-Agentr   )r%   r$   )r&   headerss     r/   _init_user_agentzCryptoBucket._init_user_agentN   s.    w&$(OOGL!L!S+@%@@!r0   c                 H   t         j                  d       t        j                  |      }| j	                  |       | j
                  j                         }| j
                  j                  ||j                        }|j                  |      }t        t        | 3  ||||      S )u\  上传一个普通文件。

        用法 ::
            >>> bucket.put_object('readme.txt', 'content of readme.txt')
            >>> with open(u'local_file.txt', 'rb') as f:
            >>>     bucket.put_object('remote_file.txt', f)

        :param mat_desc: map，对象文件的description
        :param key: 上传到OSS的文件名

        :param data: 待上传的内容。
        :type data: bytes，str或file-like object

        :param headers: 用户指定的HTTP头部。可以指定Content-Type、Content-MD5、x-oss-meta-开头的头部等
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :param progress_callback: 用户指定的进度回调函数。可以用来实现进度条等功能。参考 :ref:`progress_callback` 。

        :return: :class:`PutObjectResult <oss2.models.PutObjectResult>`
        z#Start to put object to CryptoBucket)r   r   r   CaseInsensitiveDictr3   r   create_content_materialmake_encrypt_adaptercipherto_object_metar   r   
put_object)r&   keydatar2   progress_callbackcontent_crypto_materialr.   s         r/   r:   zCryptoBucket.put_objectT   s    . 	:;**73g&"&"6"6"N"N"P##88?V?]?]^)88A\43CwHYZZr0   c                     t        d      )u   使用加签的url上传对象

        :param sign_url: 加签的url
        :param data: 待上传的数据
        :param headers: 用户指定的HTTP头部。可以指定Content-Type、Content-MD5、x-oss-meta-开头的头部等，必须和签名时保持一致
        :param progress_callback: 用户指定的进度回调函数。参考 :ref:`progress_callback`
        :return:
        1The operation is not support for CryptoBucket nowr   )r&   sign_urlr<   r2   r=   s        r/   put_object_with_urlz CryptoBucket.put_object_with_urlu   s     MNNr0   c                     t        d      Nz-The operation is not support for CryptoBucketr   )r&   r;   positionr<   r2   r=   init_crcs          r/   append_objectzCryptoBucket.append_object        IJJr0   c           	         |rt        d      t        j                  |      }| j                  |       d}d}|r|d   |d   rt        d      | j                  j                  |d   |d         \  }	}
|	|
f}t        |      }|r||d<   |d   r|d   |d   k  r|d   |d   z
  }t        j                  dj                  |||             t        j                  dj                  | j                  t        |      |||             | j                  d	| j                  |||
      }t        j                  dj                  |j                  |j                               t        ||| j                   | j                  |      S )u\  下载一个文件。

        用法 ::

            >>> result = bucket.get_object('readme.txt')
            >>> print(result.read())
            'hello world'

        :param key: 文件名
        :param byte_range: 指定下载范围。参见 :ref:`byte_range`

        :param headers: HTTP头部
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :param progress_callback: 用户指定的进度回调函数。参考 :ref:`progress_callback`
        :param process: oss文件处理，如图像服务等。指定后process，返回的内容为处理后的文件。

        :param params: http 请求的查询字符串参数
        :type params: dict

        :return: file-like object

        :raises: 如果文件不存在，则抛出 :class:`NoSuchKey <oss2.exceptions.NoSuchKey>` ；还可能抛出其他异常
        9Process object operation is not support for Crypto Bucketr    r   :Don't support range get while start is none and end is notrangeQadjust range of get object, byte_range: {0}, adjust_byte_range: {1}, discard: {2}z[Start to get object from CryptoBucket: {0}, key: {1}, range: {2}, headers: {3}, params: {4}GET)r2   paramsz.Get object done, req_id: {0}, status_code: {1}r   discard)r   r   r5   r3   r   adjust_ranger   r   r   r   r)   r   _do
request_idstatusGetObjectResultr-   )r&   r;   
byte_ranger2   r=   processrP   rR   range_stringstartendadjust_byte_rangeresps                r/   
get_objectzCryptoBucket.get_object   s   < YZZ**73g&!}$A!"^__--:::a=*UV-XJE3!&-.?@L#/ !}!21!5
1!E$Q-*;A*>>LLlss-w8 9 	ipp  )C.,Q	R xxt//gfxUELLT__^b^i^ijkt%6Y]YmYm'.0 	0r0   c                    t        t        |      j                        }|rt        j                  |v rt        d      t        j                  |      }| j                  |       d}d}|r|d   s|d   rt        d      | j                  j                  |d   |d         \  }}	||	f}
t        |
      }|r||d<   |d   r|
d   |d   k  r|d   |
d   z
  }t        j                  dj                  ||
|             t        j                  dj                  | j                  |||             | j!                  d	||
      }t#        ||| j$                  | j                  |      S )u1  使用加签的url下载文件

        :param sign_url: 加签的url
        :param byte_range: 指定下载范围。参见 :ref:`byte_range`

        :param headers: HTTP头部
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict，必须和签名时保持一致

        :param progress_callback: 用户指定的进度回调函数。参考 :ref:`progress_callback`

        :return: file-like object

        :raises: 如果文件不存在，则抛出 :class:`NoSuchKey <oss2.exceptions.NoSuchKey>` ；还可能抛出其他异常
        rJ   r   rK   r   rL   rM   rN   z\Start to get object with url from CryptoBucket: {0}, sign_url: {1}, range: {2}, headers: {3}rO   )r2   rQ   )r
   r	   queryr   PROCESSr   r   r5   r3   r   rS   r   r   r   r   r)   _do_urlrW   r-   )r&   rA   rX   r2   r=   ra   rR   rZ   r[   r\   r]   r^   s               r/   get_object_with_urlz CryptoBucket.get_object_with_url   st   $ (+112fnn-YZZ**73g&a=Z]!"^__--:::a=*UV-XJE3!&-.?@L#/ !}!21!5
1!E$Q-*;A*>>LLlss-w8 9 	jqq  (L'C	D ||E8W|=t%6/3/C/CWV 	Vr0   c                     t        d      )Nz.The operation is not support for Crypto Bucketr   )r&   r;   select_meta_paramss      r/   create_select_object_metaz&CryptoBucket.create_select_object_meta   s    JKKr0   c                     t        d      rD   r   )r&   r;   sqlr=   select_paramss        r/   select_objectzCryptoBucket.select_object   rH   r0   c                    t        j                  |      }| j                  |       |r|j                  st	        d      t
        j                  dj                  |j                  |j                               |j                  rG| j                  j                  j                  |j                  |j                        }|s?t	        d      | j                  j                  j                  |j                        |_        | j                  j                         }||_        |j                  ||      }t         t"        | K  ||      }|S )u  客户端加密初始化分片上传。

        :param params
        :param upload_context

        :param headers: HTTP头部
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :return: :class:`InitMultipartUploadResult <oss2.models.InitMultipartUploadResult>`
        返回值中的 `crypto_multipart_context` 记录了加密Meta信息，在upload_part时需要一并传入
        zSIt is not support none upload_context and must specify data_size of upload_context zNStart to init multipart upload by CryptoBucket, data_size: {0}, part_size: {1}z:part_size is invalid for multipart upload for CryptoBucket)r   r5   r3   	data_sizer   r   infor   	part_sizer   r8   is_valid_part_sizedetermine_part_sizer6   r>   r9   r   r   init_multipart_upload)	r&   r;   r2   rP   upload_contextresr>   r^   r.   s	           r/   rr   z"CryptoBucket.init_multipart_upload  s    **73g&^%=%=sttdkk$$n&>&>@ 	A ##&&--@@AYAY[i[s[stC!"^__'+';';'B'B'V'VWeWoWo'pN$"&"6"6"N"N"P1H.)88.Q\4>sGLr0   c                    t         j                  dj                  ||             t        j                  |      }| j                  |       |r|}nt        d      |j                  }	|	j                  | j                  j                  j                  k7  s#|	j                  | j                  j                  k7  rd}
t        |
|       |	j                  ||      }| j                  j                  |	j                         }| j                  j#                  |	j$                        }|j&                  |dz
  z  }| j                  j                  j)                  |      }t+        j*                  |	j                        }|j-                  |||       | j                  j/                  ||      }t0        t2        | k  ||||||      }|S )u  客户端加密上传一个分片。

        :param upload_context:
        :param str key: 待上传文件名，这个文件名要和 :func:`init_multipart_upload` 的文件名一致。
        :param str upload_id: 分片上传ID
        :param int part_number: 分片号，最小值是1.
        :param data: 待上传数据。
        :param progress_callback: 用户指定进度回调函数。可以用来实现进度条等功能。参考 :ref:`progress_callback` 。

        :param headers: 用户指定的HTTP头部。可以指定Content-MD5头部等
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :return: :class:`PutObjectResult <oss2.models.PutObjectResult>`
        zMStart to upload multipart of CryptoBucket, upload_id = {0}, part_number = {1}zWCould not init upload context, upload contexts flag is False and upload context is nonez@Envelope or data encryption/decryption algorithm is inconsistentr   )r   rn   r   r   r5   r3   r   r>   cek_algr   r8   algwrap_algInconsistentErrorr9   decrypt_encrypted_keyencrypted_keydecrypt_encrypted_ivencrypted_ivro   calc_offsetcopy
initializer7   r   r   upload_part)r&   r;   	upload_idpart_numberr<   r=   r2   rs   contextr>   err_msg	plain_keyplain_ivoffsetcounterr8   r^   r.   s                    r/   r   zCryptoBucket.upload_part'  s    	[bbclcnp	q **73g&$Gwxx")"A"A"**d.B.B.I.I.M.MMQhQqQq$$--R.XG#GT22)88'J((>>?V?d?de	''<<=T=a=ab""kAo6&&--99&A299:)Xw7##88vF\44S)[RVXikrsr0   c                     t         j                  dj                  |             t        j                  |      }| j                  |       	 t        t        | #  ||||      }|S # t        $ r}|d}~ww xY w)u  客户端加密完成分片上传，创建文件。
        当所有分片均已上传成功，才可以调用此函数

        :param str key: 待上传的文件名，这个文件名要和 :func:`init_multipart_upload` 的文件名一致。
        :param str upload_id: 分片上传ID

        :param parts: PartInfo列表。PartInfo中的part_number和etag是必填项。其中的etag可以从 :func:`upload_part` 的返回值中得到。
        :type parts: list of `PartInfo <oss2.models.PartInfo>`

        :param headers: HTTP头部
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :return: :class:`PutObjectResult <oss2.models.PutObjectResult>`
        zCStart to complete multipart upload of CryptoBucket, upload_id = {0}N)
r   rn   r   r   r5   r3   r   r   complete_multipart_uploadr   )r&   r;   r   partsr2   r^   er.   s          r/   r   z&CryptoBucket.complete_multipart_uploadV  sx     	Y``ajkl**73g&	tFsIW\^efD   	G	s   A% %	A5.A00A5c                     t         j                  dj                  |             t        j                  |      }| j                  |       	 t        t        | #  ||      }|S # t        $ r}|d}~ww xY w)uU  取消分片上传。

        :param headers: 可以是dict，建议是oss2.CaseInsensitiveDict
        :param str key: 待上传的文件名，这个文件名要和 :func:`init_multipart_upload` 的文件名一致。
        :param str upload_id: 分片上传ID

        :return: :class:`RequestResult <oss2.models.RequestResult>`
        z@Start to abort multipart upload of CryptoBucket, upload_id = {0}N)
r   rn   r   r   r5   r3   r   r   abort_multipart_uploadr   )r&   r;   r   r2   r^   r   r.   s         r/   r   z#CryptoBucket.abort_multipart_uploadp  sr     	V]]^ghi**73g&	tCCSD   	G	s   A# #	A3,A..A3c                     t        d      )u!  分片拷贝。把一个已有文件的一部分或整体拷贝成目标文件的一个分片。

        :param target_part_number:
        :param target_upload_id:
        :param target_key:
        :param source_key:
        :param source_bucket_name:
        :param byte_range: 指定待拷贝内容在源文件里的范围。参见 :ref:`byte_range`

        :param headers: HTTP头部
        :type headers: 可以是dict，建议是oss2.CaseInsensitiveDict

        :return: :class:`PutObjectResult <oss2.models.PutObjectResult>`
        r@   r   )r&   source_bucket_name
source_keyrX   
target_keytarget_upload_idtarget_part_numberr2   s           r/   upload_part_copyzCryptoBucket.upload_part_copy  s      MNNr0   c                     t        d      rD   r   )r&   r;   rY   s      r/   process_objectzCryptoBucket.process_object  s    IJJr0   )	FNNrK   TNNNF)NN)NNN)NNNNN)N)__name__
__module____qualname____doc__r   r3   r:   rB   rG   r_   rd   rg   rk   rr   r   r   r   r   r   __classcell__)r.   s   @r/   r   r      s    @  !% !$L8A  %)[B
O #(,#K #%)=0@ (,$(.20VdL )-$(K$L-^4* 6:O$Kr0   r   )rK   r   r   r   apir   modelscompatr   r	   r
   cryptor   r   r   r   logging	getLoggerr   r   r    r0   r/   <module>r      sH       #  1 1 & #  			8	$EK6 EKr0   