
    "hje                        d 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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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ZddlmZ ddlmZ ddlmZ ddlmZ dd	lm Z m!Z!m"Z" dd
l#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)  ejT                  e+      Z,dddddddddddddZ-d Z.d Z/d Z0d Z1d Z2d Z3d Z4d Z5d!Z6 e7e5e6z         Z8d"Z9d#Z:d$ Z;d% Z<d& Z= G d' d(e>      Z?d) Z@d* ZAd+ ZBd, ZCd-ZDdhd.ZEdid/ZFdjd0ZGdjd1ZHd2 ZIdjd3ZJd4 ZKdjd5ZL G d6 d7e>      ZM G d8 d9e>      ZN G d: d;e>      ZO G d< d=e>      ZP G d> d?e>      ZQd@ZRdAZSdBZTdCZUdDZV ej                  ej                         G dE dFe>             ZY G dG dHeY      ZZdI Z[dJ Z\dK Z] e
j                         Z_dLZ` ej                  dM      Zb ej                  dN      ZcddOdPdQdRdSdTdUdVdWdXdYdZZdd[ Zedhd\Zfd] Zgd^ Zhd_ Zid` Zjda Zkdb Zldc Zm	 	 dkddZnde Zodf Zpdg Zqy)lu.   
oss2.utils
----------

工具函数模块。
    
formatdateN)AES)Random)Counter   )mkCombineFun)	to_stringto_bytesurlparse)ClientErrorInconsistentErrorRequestErrorOpenApiFormatError)defaultszapplication/javascriptzAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetzDapplication/vnd.openxmlformats-officedocument.spreadsheetml.templatezEapplication/vnd.openxmlformats-officedocument.presentationml.templatezFapplication/vnd.openxmlformats-officedocument.presentationml.slideshowzIapplication/vnd.openxmlformats-officedocument.presentationml.presentationzBapplication/vnd.openxmlformats-officedocument.presentationml.slidezGapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentzGapplication/vnd.openxmlformats-officedocument.wordprocessingml.templatez.application/vnd.ms-excel.addin.macroEnabled.12z5application/vnd.ms-excel.sheet.binary.macroEnabled.12z'application/vnd.android.package-archive)z.jsz.xlsxz.xltxz.potxz.ppsxz.pptxz.sldxz.docxz.dotxz.xlamz.xlsbz.apkc                 P    t        t        j                  t        |                   S N)r
   base64	b64encoder   datas    H/root/.hermes/SkillClaw/.venv/lib/python3.12/site-packages/oss2/utils.pyb64encode_as_stringr   ;   s    V%%htn566    c                     	 t        j                  t        |             S # t        t        j
                  f$ r}t        dt        |       z         d }~ww xY w)NzBase64 Error: )r   	b64decoder
   	TypeErrorbinasciiErrorr   )r   es     r   b64decode_from_stringr!   ?   sM    E	$00x~~& E !1IdO!CDDEs     AAAc                 p    t        j                  t        |             }t        |j	                               S )u   计算data的MD5值，经过Base64编码并返回str类型。

    返回值可以直接作为HTTP Content-Type头部的值
    )hashlibmd5r   r   digest)r   ms     r   content_md5r'   F   s'    
 	HTN#Aqxxz**r   c                 Z    t        j                  t        |             j                         S )u[   返回 `data` 的MD5值，以十六进制可读字符串（32个小写字符）的方式。)r#   r$   r   	hexdigestr   s    r   
md5_stringr*   O   s    ;;x~&0022r   c                     t         j                  j                  |       d   j                         }|t        v r	t        |   S t        j                  |       d   S )u'   根据文件名，返回Content-Type。r   r   )ospathsplitextlower_EXTRA_TYPES_MAP	mimetypes
guess_type)nameexts     r   content_type_by_namer5   T   sN    
''

4
 
#
)
)
+C
$$%a((r   c                 B    | xs i } d| v r| S t        |      }|r|| d<   | S )un   根据文件名在headers里设置Content-Type。如果headers中已经存在Content-Type，则直接返回。zContent-Type)r5   )headersr3   content_types      r   set_content_typer9   ]   s4    mG '-L".Nr   c                 6   d}| j                  d      }| d   dk(  r|dkD  r| d| }d}n| j                  d      d   }|dk(  ry	 |r%t        j                  t        j                  |       yt        j
                  |       	 y# t        j                  $ r Y yw xY w)	u,   判断网络地址是否为IP或localhost。F]r   [r   T:	localhost)findsplitsocket	inet_ptonAF_INET6	inet_atonerror)netlocis_ipv6right_bracket_indexlocs       r   is_ip_or_localhostrJ   k   s    G ++c*ayC/!3Q*+ll3"
kV__c2 	 S!  << s   &B +B BB$abcdefghijklmnopqrstuvwxyz0123456789-        c                     t        |       dk  st        |       dkD  ry| d   t        k(  ry| d   t        vryt        |       t        k  S )u!   判断是否为合法的Bucket名   ?   Fr   )len_HYPHEN
_ALPHA_NUMset_BUCKET_NAME_CHARS)r3   s    r   is_valid_bucket_namerX      sH    
4y1}D	BBx7Awj t9***r   c                 <    | yd}t        j                  ||       ryy)u    判断是否为合法的endpointFz^([a-zA-Z]+://)?[\w.-]+(:\d+)?$T)rematch)endpointpatterns     r   is_valid_endpointr^      s$    1G	xx"r   c                 L    t         j                  dk(  r| j                          y y )Nlittle)sys	byteorderreverse)bytes_arrays    r   change_endianness_if_neededre      s    
}}  !r   c                   .    e Zd ZdZd ZddZed        Zy)SizedFileAdapteruh   通过这个适配器（Adapter），可以把原先的 `file_object` 的长度限制到等于 `size`。c                 .    || _         || _        d| _        y Nr   )file_objectsizeoffset)selfrj   rk   s      r   __init__zSizedFileAdapter.__init__   s    &	r   Nc                 f   | j                   | j                  k\  ry|!|dk  s|| j                   z   | j                  k\  rE| j                  j                  | j                  | j                   z
        }| j                  | _         |S | xj                   |z  c_         | j                  j                  |      S N r   )rl   rk   rj   read)rm   amtr   s      r   rr   zSizedFileAdapter.read   s    ;;$))#K37dkk(9TYY(F##((T[[)@AD))DKKs$$S))r   c                     | j                   S r   rk   rm   s    r   rS   zSizedFileAdapter.len       yyr   r   )__name__
__module____qualname____doc__rn   rr   propertyrS    r   r   rg   rg      s#    r

*  r   rg   c                     | |z   dz
  |z  S )Nr   r}   )r&   ns     r   how_manyr      s    EAI!r   c                     | j                         }| j                  dt        j                         | j                         }| j                  |t        j                         ||z
  S ri   )tellseekr,   SEEK_ENDSEEK_SET)fileobjcurrentends      r   file_object_remaining_bytesr      sF    llnGLLBKK 
,,.CLL"++&=r   c                 n    t        | d      xs( t        | d      xs t        | d      xr t        | d      S N__len__rS   r   r   )hasattrr   s    r   _has_data_size_attrr      s6    4#pwtU';pf@U@oZabfhnZopr   c                     t        | d      rt        |       S t        | d      r| j                  S t        | d      rt        | d      rt        |       S y r   )r   rS   r   r   s    r   _get_data_sizer      sJ    tY4ytUxxtVv!6*400r   i    c                    t        |       } |t        |       }|^t        | d      rt        | |      S t        | d      rt	        | |      S t        dj                  | j                  j                              t        | ||      S )u  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够
     调用进度回调函数。当 `size` 没有指定，且无法确定时，上传回调函数返回的总字节数为None。

    :param data: 可以是bytes、file object或iterable
    :param progress_callback: 进度回调函数，参见 :ref:`progress_callback`
    :param size: 指定 `data` 的大小，可选

    :return: 能够调用进度回调函数的适配器
    rr   __iter__){0} is not a file object, nor an iterator)
r   r   r   _FileLikeAdapter_IterableAdapterr   format	__class__rx   _BytesAndFileAdapter)r   progress_callbackrk   s      r   make_progress_adapterr      s     D>D|d#|4 #D*;<<T:&#D*;<<IPPQUQ_Q_QhQhijj#D*;TBBr   c                    t        |       } t        |       r-|rt        d      t        | t	        |       t        |            S t        | d      rt        | t        |      |      S t        | d      r#|rt        d      t        | t        |            S t        dj                  | j                  j                              )	u6  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够计算CRC。

    :param discard:
    :return:
    :param data: 可以是bytes、file object或iterable
    :param init_crc: 初始CRC值，可选

    :return: 能够调用计算CRC函数的适配器
    ;Bytes of file object adapter does not support discard bytes)rk   crc_callbackrr   )r   discardr   /Iterator adapter does not support discard bytes)r   r   )r   r   r   r   r   Crc64r   r   r   r   r   rx   )r   init_crcr   s      r   make_crc_adapterr      s     D>D 4 [\\#D~d/CRWX`Rabb	v	5?GTT	z	"OPP5?CCELLT^^MdMdeffr   c                     d}t        |      }| D ]C  }|j                  r|j                  s y |j                  ||j                  |j                        }E |S ri   )r   part_crcrk   combine)partsr   
object_crccrc_objparts        r   calc_obj_crc_from_partsr     sS    JHoG O}}DII T]]DIINJ	O
 r   c                 R   t        |       } t        |       r$|rt        d      t        | t	        |       |      S t        | d      rt        | ||      S t        | d      r|rt        d      t        | |      S t        dj                  | j                  j                              )	uq  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够进行加解密操作。

        :param encrypt:
        :param cipher_callback:
        :param discard: 读取时需要丢弃的字节
        :param data: 可以是bytes、file object或iterable

        :return: 能够客户端加密函数的适配器
        r   )rk   cipher_callbackrr   )r   r   r   r   )r   z{0} is not a file object)r   r   r   r   r   r   r   r   r   r   rx   )r   r   r   s      r   make_cipher_adapterr   #  s     D>D 4 [\\#D~d/CUdeetVowWW	z	"OPPoFF4;;DNN<S<STUUr   c                     |L|I||k7  rCt        dj                  || ||            }t        j                  dj                  |             |y y y )NzeInconsistentError: req_id: {0}, operation: {1}, CRC checksum of client: {2} is mismatch with oss: {3}zException: {0})r   r   loggerrE   )	operation
client_crcoss_crc
request_idr    s        r   	check_crcr   ?  s^    '"5*:O ..4fZJX_.`b%,,Q/0	 ;P"5r   c                      | r | ||d         y y r   r}   )r   contentr   s      r   _invoke_crc_callbackr   G  s    WWX&' r   c                     | r
 | ||       y y r   r}   )r   consumed_bytestotal_bytess      r   _invoke_progress_callbackr   L  s    .+6 r   c                 $    | r | |      }||d  S |S r   r}   )r   r   r   s      r   _invoke_cipher_callbackr   Q  s!    !'*wx  Nr   c                   6    e Zd ZddZd Zd Zd Zed        Zy)r   Nc                 \    t        |      | _         || _        d| _        || _        || _        y ri   )iterr   rl   r   r   )rm   r   r   r   r   s        r   rn   z_IterableAdapter.__init__Y  s,    J	!2(.r   c                     | S r   r}   rv   s    r   r   z_IterableAdapter.__iter__a      r   c                 "    | j                         S r   nextrv   s    r   __next__z_IterableAdapter.__next__d      yy{r   c                    t        | j                  | j                  d        t        | j                        }| xj                  t        |      z  c_        t        | j                  |       t        | j                  |      }|S r   )
r   r   rl   r   r   rS   r   r   r   r   rm   r   s     r   r   z_IterableAdapter.nextg  s^    !$"8"8$++tLtyy/s7|#T..8)$*>*>Hr   c                     | j                   r| j                   j                  S | j                  r| j                  j                  S y r   )r   crcr   rv   s    r   r   z_IterableAdapter.crcs  5    $$(((YY99== r   )NNN)	rx   ry   rz   rn   r   r   r   r|   r   r}   r   r   r   r   X  s*    /
  r   r   c                   B    e Zd ZdZd	dZd Zd Zd Zd
dZe	d        Z
y)r   u   通过这个适配器，可以给无法确定内容长度的 `fileobj` 加上进度监控。

    :param fileobj: file-like object，只要支持read即可
    :param progress_callback: 进度回调函数
    Nc                 f    || _         || _        d| _        || _        || _        || _        d| _        y )Nr   F)r   r   rl   r   r   r   read_all)rm   r   r   r   r   r   s         r   rn   z_FileLikeAdapter.__init__  s6    !2(.r   c                     | S r   r}   rv   s    r   r   z_FileLikeAdapter.__iter__  r   r   c                 "    | j                         S r   r   rv   s    r   r   z_FileLikeAdapter.__next__  r   r   c                 d    | j                   rt        | j                  t              }|r|S t        r   )r   StopIterationrr   _CHUNK_SIZEr   s     r   r   z_FileLikeAdapter.next  s+    ==))K(Nr   c                    | j                   }|| j                  k  r|r| j                  r|| j                  z  }| j                  j	                  |      }|s*d| _        t        | j                  | j                   d        |S t        | j                  | j                   d        | xj                   t        |      z  c_         d}|| j                  k  r0t        |      | j                  k  rt        |      }n| j                  }t        | j                  ||       t        | j                  ||      }| xj                  |z  c_        |S )NTr   )rl   r   r   r   rr   r   r   r   rS   r   r   r   )rm   rs   offset_startr   real_discards        r   rr   z_FileLikeAdapter.read  s    {{$,,&343G3G4<<C,,##C( DM%d&<&<dkk4P"  &d&<&<dkk4PKK3w<'KLdll*w<4<</#&w<L#'<<L !2!2G\J-d.B.BG\ZGLLL(Lr   c                     | j                   r| j                   j                  S | j                  r| j                  j                  S y r   )r   r   r   rv   s    r   r   z_FileLikeAdapter.crc  s7    $$(((\\<<###r   )NNNr   r   )rx   ry   rz   r{   rn   r   r   r   rr   r|   r   r}   r   r   r   r   }  s4    	 6  r   r   c                   \    e Zd ZdZddZed        Zd ZeZd Z	d Z
d Zdd	Zed
        Zy)r   u  通过这个适配器，可以给 `data` 加上进度监控。

    :param data: 可以是unicode字符串（内部会转换为UTF-8编码的bytes）、bytes或file object
    :param progress_callback: 用户提供的进度报告回调，形如 callback(bytes_read, total_bytes)。
        其中bytes_read是已经读取的字节数；total_bytes是总的字节数。
    :param int size: `data` 包含的字节数。
    Nc                 j    t        |      | _        || _        || _        d| _        || _        || _        y ri   )r   r   r   rk   rl   r   r   )rm   r   r   rk   r   r   s         r   rn   z_BytesAndFileAdapter.__init__  s3    TN	!2	(.r   c                     | j                   S r   ru   rv   s    r   rS   z_BytesAndFileAdapter.len  rw   r   c                      yNTr}   rv   s    r   __bool__z_BytesAndFileAdapter.__bool__      r   c                     | S r   r}   rv   s    r   r   z_BytesAndFileAdapter.__iter__  r   r   c                 "    | j                         S r   r   rv   s    r   r   z_BytesAndFileAdapter.__next__  r   r   c                 @    | j                  t              }|r|S t        r   )rr   r   r   r   s     r   r   z_BytesAndFileAdapter.next  s    ))K(Nr   c                    | j                   | j                  k\  rt        d      S ||dk  r| j                  | j                   z
  }n#t        || j                  | j                   z
        }t	        | j
                  t              r'| j
                  | j                   | j                   |z    }n| j
                  j                  |      }| xj                   |z  c_         t        | j                  t        | j                   | j                        | j                         t        | j                  |       t        | j                  |      }|S rp   )rl   rk   r   min
isinstancer   bytesrr   r   r   r   r   r   r   )rm   rs   bytes_to_readr   s       r   rr   z_BytesAndFileAdapter.read  s    ;;$))#B<;#' II3MTYY%<=Mdii'iiDKK,EFGiinn]3G}$!$"8"8#dkk499:UW[W`W`aT..8)$*>*>Hr   c                     | j                   r| j                   j                  S | j                  r| j                  j                  S y r   )r   r   r   rv   s    r   r   z_BytesAndFileAdapter.crc  r   r   )NNNNr   )rx   ry   rz   r{   rn   r|   rS   r   __nonzero__r   r   r   rr   r   r}   r   r   r   r     sT    /   K 0  r   r   c                   >    e Zd ZdZdZd	dZd Zd Zd Ze	d        Z
y)
r   l   6S rN   c                     t        j                  | j                  |d| j                        | _        t        | j                  |d| j                        | _        y NT)initCrcrevxorOut)crcmodCrc_POLY_XOROUTcrc64r	   crc64_combineFunrm   r   s     r   rn   zCrc64.__init__  s>    ZZ

H$t||\
 ,TZZt\`\h\h ir   c                 &    | j                  |       y r   updaterm   r   s     r   __call__zCrc64.__call__      Dr   c                 :    | j                   j                  |       y r   )r   r   r   s     r   r   zCrc64.update      

$r   c                 (    | j                  |||      S r   )r   )rm   crc1crc2len2s       r   r   zCrc64.combine  s    $$T466r   c                 .    | j                   j                  S r   )r   crcValuerv   s    r   r   z	Crc64.crc"      zz"""r   Nr   )rx   ry   rz   r   r   rn   r   r   r   r|   r   r}   r   r   r   r     s5    E Gj
 7 # #r   r   c                   8    e Zd ZdZdZddZd Zd Zed        Z	y)	Crc32l   	 rM   c                 h    t        j                  | j                  |d| j                        | _        y r   )r   r   r   r   crc32r   s     r   rn   zCrc32.__init__*  s     ZZ

H$t||\
r   c                 &    | j                  |       y r   r   r   s     r   r   zCrc32.__call__-  r   r   c                 :    | j                   j                  |       y r   )r
  r   r   s     r   r   zCrc32.update0  r   r   c                 .    | j                   j                  S r   )r
  r  rv   s    r   r   z	Crc32.crc3  r  r   Nr  )
rx   ry   rz   r   r   rn   r   r   r|   r   r}   r   r   r  r  &  s0    EG]  # #r   r            zAES/GCM/NoPaddingzAES/CTR/NoPaddingc                      e Zd ZdZd Zej                  d        Zej                  d        Zej                  dd       Z	ej                  d        Z
ej                  d        Zej                  dd	       Zd
 Zd ZddZy)	AESCipheru  AES256 加密实现。
            :param str key: 对称加密数据密钥
            :param str start: 对称加密初始随机值
        .. note::
            用户可自行实现对称加密算法，需服务如下规则：
            1、提供对称加密算法名，ALGORITHM
            2、提供静态方法，返回加密密钥和初始随机值（若算法不需要初始随机值，也需要提供）
            3、提供加密解密方法
    c                 T    d | _         t        | _        t        | _        t
        | _        y r   )alg_AES_256_KEY_SIZEkey_len_AES_BLOCK_LENblock_size_len_AES_BLOCK_BITS_LENblock_size_len_in_bitsrv   s    r   rn   zAESCipher.__init__M  s     (,&9#r   c                      y r   r}   rv   s    r   get_keyzAESCipher.get_keyS      r   c                      y r   r}   rv   s    r   get_ivzAESCipher.get_ivW  r  r   c                      y r   r}   )rm   keyivoffs       r   
initializezAESCipher.initialize[  r  r   c                      y r   r}   rm   raws     r   encryptzAESCipher.encrypt_  r  r   c                      y r   r}   rm   encs     r   decryptzAESCipher.decryptc  r  r   Nc                      y r   r}   )rm   	data_sizeexcepted_part_sizes      r   determine_part_sizezAESCipher.determine_part_sizeg  r  r   c                 
    ||fS r   r}   rm   startr   s      r   adjust_rangezAESCipher.adjust_rangek  s    czr   c                 .    |d}d|| j                   z  k(  S ri   r  rm   rl   s     r   is_block_alignedzAESCipher.is_block_alignedn  s"    >FFT00000r   c                      yr   r}   rm   	part_sizer.  s      r   is_valid_part_sizezAESCipher.is_valid_part_sizes  r   r   r  r   )rx   ry   rz   r{   rn   abcabstractmethodr  r  r$  r(  r,  r0  r4  r8  r<  r}   r   r   r  r  @  s    : 	  	  	  	  	  	 1
r   r  c                   b     e Zd ZdZ fdZd Zd ZddZd Zd Z	d Z
d	 Zd
 Zd ZddZ xZS )AESCTRCipheru  AES256 加密实现。
        :param str key: 对称加密数据密钥
        :param str start: 对称加密初始随机值
    .. note::
        用户可自行实现对称加密算法，需服务如下规则：
        1、提供对称加密算法名，ALGORITHM
        2、提供静态方法，返回加密密钥和初始随机值（若算法不需要初始随机值，也需要提供）
        3、提供加密解密方法
    c                 N    t         t        |           t        | _        d | _        y r   )superr@  rn   AES_CTRr  _AESCTRCipher__cipher)rm   r   s    r   rn   zAESCTRCipher.__init__  s    lD*,r   c                 ,    t        | j                        S r   )
random_keyr  rv   s    r   r  zAESCTRCipher.get_key  s    $,,''r   c                     t               S r   )	random_ivrv   s    r   r  zAESCTRCipher.get_iv  s
    {r   c                 D    t        |      |z   }| j                  ||       y r   )iv_to_big_intinitial_by_counter)rm   r!  r"  rl   counters        r   r$  zAESCTRCipher.initialize  s!    #f,W-r   c                     t        j                  | j                  |      }t        j                  |t        j                  |      | _        y )N)initial_value)rL  )r   newr  r   MODE_CTRrD  )rm   r!  rL  ctrs       r   rK  zAESCTRCipher.initial_by_counter  s0    kk$55WMS\\3?r   c                 8    | j                   j                  |      S r   rD  r(  r&  s     r   r(  zAESCTRCipher.encrypt      }}$$S))r   c                 8    | j                   j                  |      S r   rS  r*  s     r   r,  zAESCTRCipher.decrypt  rT  r   c                     |rC|r%||k  r|| j                   z  | j                   z  }||fS || j                   z  | j                   z  }||fS r   r6  r2  s      r   r4  zAESCTRCipher.adjust_range  s]    C<"d&9&99T=P=PPE cz $"5"559L9LLczr   c                 |    | j                  |      r|t        j                  k  ry|t        j                  z  |k  ryy)NFT)r8  r   min_part_sizemax_part_countr:  s      r   r<  zAESCTRCipher.is_valid_part_size  s9    $$Y/9x?U?U3Ux...:r   c                 X    | j                  |      st        d      || j                  z  S )Nz$offset is not align to encrypt block)r8  r   r  r7  s     r   calc_offsetzAESCTRCipher.calc_offset  s-    $$V,DEE,,,,r   c                    |rT| j                  ||      r|S |t        j                  z  |k\  r*t        || j                  z  dz         | j                  z  }|S t        j
                  }|t        j                  z  |k  r|dz  }|t        j                  z  |k  r| j                  |      s(t        || j                  z  dz         | j                  z  }|S )Nr      )r<  r   rY  intr  r;  r8  )rm   r.  r/  r;  s       r   r0  z AESCTRCipher.determine_part_size  s    &&'99E))#h&=&==J 2T5H5H H1 LMPTPcPcc	   &&	(111I=!AI (111I= $$Y/I(;(;;a?@4CVCVVIr   r  r   )rx   ry   rz   r{   rn   r  r  r$  rK  r(  r,  r4  r<  r[  r0  __classcell__)r   s   @r   r@  r@  w  s@    
(.@**-
r   r@  c                 H    t        j                         j                  |       S r   )r   rO  rr   )r  s    r   rF  rF    s    ::<W%%r   c                      t        j                         j                  d      } | dd t        j                  dd      z   | dd  z   }|S )Nr  r      z>L   )r   rO  rr   structpack)r"  safe_ivs     r   rH  rH    sC    			2	B1gD!,,r"#w6GNr   c                 N    t        j                  d|       }|d   dz  |d   z  }|S )Nz>QQr   @   r   )rd  unpack)r"  iv_high_low_pair
iv_big_ints      r   rJ  rJ    s3    }}UB/!!$*-=a-@@Jr   z%Y-%m-%dT%H:%M:%S.000Zz(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), (?P<day>0[1-9]|([1-2]\d)|(3[0-1])) (?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (?P<year>\d+) (?P<hour>([0-1]\d)|(2[0-3])):(?P<minute>[0-5]\d):(?P<second>[0-5]\d) GMT$z(?P<year>\d+)-(?P<month>01|02|03|04|05|06|07|08|09|10|11|12)-(?P<day>0[1-9]|([1-2]\d)|(3[0-1]))T(?P<hour>([0-1]\d)|(2[0-3])):(?P<minute>[0-5]\d):(?P<second>[0-5]\d)\.000Z$r]  rP               rb  	   
      rc  )JanFebMarAprMayJunJulAugSepOctNovDecc           	          t         5  t        t        j                  t	        j
                  | |                  cd d d        S # 1 sw Y   y xY wr   )_STRPTIME_LOCKr^  calendartimegmtimestrptime)time_stringformat_strings     r   to_unixtimer    s:    	 O8??4==m#LMNO O Os   2AAc                     t        | d      S )u   返回符合HTTP标准的GMT时间字符串，用strftime的格式表示就是"%a, %d %b %Y %H:%M:%S GMT"。
    但不能使用strftime，因为strftime的结果是和locale相关的。
    T)usegmtr   )timevals    r   	http_dater    s     gd++r   c                    t         j                  |       }|st        | dz         t        |j	                  d            }t
        |j	                  d         }t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        j                  ||||||      j                         }t        j                  |      S )u   把HTTP Date格式的字符串转换为UNIX时间（自1970年1月1日UTC零点的秒数）。

    HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。
    z! is not in valid HTTP date formatdaymonthyearhourminutesecond)
_HTTP_GMT_REr[   
ValueErrorr^  group_MONTH_MAPPINGdatetime	timetupler  r  	r  r&   r  r  r  r  r  r  tms	            r   http_to_unixtimer     s    
 	;'A'JJKK
aggen
C1777+,EqwwvDqwwvD"#F"#F			4T66	B	L	L	NB??2r   c                    t         j                  |       }|st        | dz         t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        |j	                  d            }t        j
                  ||||||      j                         }t        j                  |      S )ue   把ISO8601时间字符串（形如，2012-02-24T06:07:48.000Z）转换为UNIX时间，精确到秒。z is not in valid ISO8601 formatr  r  r  r  r  r  )	_ISO8601_REr[   r  r^  r  r  r  r  r  r  s	            r   iso8601_to_unixtimer    s     	+&A'HHII
aggen
C !EqwwvDqwwvD"#F"#F			4T66	B	L	L	NB??2r   c                 ,    | j                  t              S r   )strftime_ISO8601_FORMAT)ds    r   date_to_iso8601r  *  s    ::o&&r   c                 V    t        |       }t        j                  j                  |      S r   )r  r  datefromtimestamp)r  	timestamps     r   iso8601_to_dater  .  s!    #K0I==&&y11r   c                     	 t        j                  |        y # t         j                  $ r(}|j                  t        j                  k7  r Y d }~y d }~ww xY wr   )r,   makedirsrE   errnoEEXIST)dirpathr    s     r   	makedir_pr  3  s?    
G88 77ell" #s    AAAc                     	 t        j                  |        y# t        $ r(}|j                  t        j                  k7  r Y d}~yd}~ww xY w)u3   删除文件，如果文件不存在也不报错。N)r,   removeOSErrorr  ENOENT)filenamer    s     r   silently_remover  ;  s;    
		( 77ell" #s    	A	AA	c                     	 t        j                  | |       y # t        $ rJ}|j                  t        j                  k(  r"t        |       t        j                  | |       n Y d }~y d }~ww xY wr   )r,   renamer  r  r  r  )srcdstr    s      r   force_renamer  D  sS    
		#s 77ell"C IIc3  s    	A,A A''A,c                     d}	 | j                  |      }|sn |t        |      z  }|j                  |       4||k7  rt        d|      y)zPcopy data from file-like object fsrc to file-like object fdst, and verify lengthr   zIncompleteRead from sourceN)rr   rS   writer   )fsrcfdstexpected_len
chunk_sizer   num_readbufs          r   copyfileobj_and_verifyr  O  s[    
 H
ii
#CH

3  < <jII  r   c                 D    | y| d   }| d   }||ydt        ||      z   S )Nrq   r   r   zline-range=_range_internalranger3  lasts      r   _make_line_range_stringr  a  s:    }!HE8D}?5$777r   c                 D    | y| d   }| d   }||ydt        ||      z   S )Nrq   r   r   zsplit-range=r  r  s      r   _make_split_range_stringr  m  s:    }!HE8D}OE4888r   c                 0    d } ||       dz    ||      z   S )Nc                     | yt        |       S )Nrq   )str)poss    r   to_strz_range_internal.<locals>.to_strz  s    ;s8Or   rL   r}   )r3  r  r  s      r   r  r  y  s!     %=3--r   r   )r   r   r  )i @  rq   )rr{   email.utilsr   loggingos.pathr,   r1   rA   r#   r   	threadingr  r  r  r  r   r   rZ   ra   randomr=  sixrd  Crypto.Cipherr   Cryptor   Crypto.Utilr   crc64_combiner	   compatr
   r   r   
exceptionsr   r   r   r   rq   r   	getLoggerrx   r   r0   r   r!   r'   r*   r5   r9   rJ   rU   rT   rV   rW   _MAX_UINT32_MAX_UINT64rX   r^   re   objectrg   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  AES_GCMrC  add_metaclassABCMetar  r@  rF  rH  rJ  Lockr  r  compiler  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r}   r   r   <module>r     s   #              	 
       ' 1 1 X X 			8	$ $PSTUXQVV=D5  7E+3
)0 4

g-. +	
v 0q
 C4g:V8(
7
"v "JDv DNH6 HV#F #.#F #$   

 3;;3 3  3lK9 K\&  !*
 rzz ^ bjj s
  O
,,('2
 '.&(J$
8
9.r   