
    9iN                     T   S r SSKJr  SSKJr  SSKJrJr  SSKJrJ	r	J
r
  SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSKr SSKJr  SS	KJr  SSKrSS
KJr  SSKrS/rSrSrS2S jrS3S jr S r!S r"S r#S r$S r%S r&\&" 5       r'S4S jr(S r)S r*S r+\RX                  " S5      r-\RX                  " S5      r.\RX                  " S5      r/S r0S r1S  r2 " S! S"\35      r4S# r5S$ r6S% r7 S& r8S' r9S( r:S) r;S* r<S+ r=S, r>S- r?S5S. jr@SrA " S/ S0\35      rBS1 rCg! \ a	    SSKJr   Nf = f)6z0
This module provide some tools for bce client.
    )print_function)absolute_import)strbytes)	iteritemsiterkeys
itervalues)compatN)urlparse)AES)http_headerss   .cdn.bcebos.coms
   bcebos.coms   http    c                    U R                  5       nU(       a  U R                  U5        [        R                  " 5       n UnXbs=:  a  S:  a  O  OUnU R	                  U5      nU(       d  O.UR                  U5        US:  a  U[        U5      -  nUS:X  a  OMZ  U R                  U5        [        R                  " UR                  5       5      $ )z
Get MD5 from file by fp.

:type fp: FileIO
:param fp: None

:type offset: long
:param offset: None

:type length: long
:param length: None
=======================
:return:
    **file_size, MD(encode by base64)**
r   )
tellseekhashlibmd5readupdatelenbase64standard_b64encodedigest)fpoffsetlengthbuf_sizeorigin_offsetr   bytes_to_readbufs           N/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/baidubce/utils.pyget_md5_from_fpr"   ,   s    " GGIM

++-C
 %A%"Mggm$

3A:c#hFQ;  GGM$$SZZ\22    c                    U S:X  a  [         R                   R                  5       nO[         R                   R                  U 5      nSUR                  UR                  UR
                  UR                  UR                  UR                  4-  $ )z
Get cannonical time.

:type timestamp: int
:param timestamp: None
=======================
:return:
    **string of canonical_time**
r   s   %04d-%02d-%02dT%02d:%02d:%02dZ)	datetimeutcnowutcfromtimestampyearmonthdayhourminutesecond)	timestamputctimes     r!   get_canonical_timer0   Q   sm     A~##**,##44Y?,gmmW[[gnngnn06 6 6r#   c                      U R                  S5      nUS   n U S:X  a  gU R                  S5      n[        U5      S:w  a  gU H#  n[        U5      S:  d  [        U5      S:  d  M#    g    g!    g= f)	z
Check a string whether is a legal ip address.

:type s: string
:param s: None
=======================
:return:
    **Boolean**
   :r   s	   localhostT   .   F   )splitr   int)stmp_listis      r!   is_ipr;   d   su    774=QK774=x=Aq6A:Q#  
 s"   A+  A+  !A+ %A+ 'A+ +A/c                 .    [         R                  " U 5      $ )z
Encode a string to utf-8.

:type input_string: string
:param input_string: None
=======================
:return:
    **string**
)r
   convert_to_bytes)input_strings    r!   convert_to_standard_stringr?      s      ""<00r#   c                     0 nU  HU  u  p#[        U[        5      (       a  UR                  S5      n[        U[        5      (       a  UR                  S5      nX1U'   MW     U$ )zl
Transfer a header list to dict

:type s: list
:param s: None
=======================
:return:
    **dict**
   ")
isinstancer   strip)header_list
header_mapabs       r!   convert_header2maprH      sX     JaAaA1  r#   c                     [        U5       HG  u  p#UR                  5       R                  5       U R                  5       R                  5       :X  d  ME  Us  $    g)z
Get element from dict which the lower of key and name are equal.

:type name: string
:param name: None

:type container: dict
:param container: None
=======================
:return:
    **Value**
 )r   rC   lower)name	containerkvs       r!   safe_get_elementrP      sC     )$779??

 2 2 44H % r#   c                 `    Sn U R                   S:X  d  U R                   S:X  a  SnU$ !    U$ = f)zm
Check whether the response is redirect.

:type res: HttpResponse
:param res: None

:return:
    **Boolean**
Fi-  i.  T)status)resis_redirects     r!   check_redirectrU      sB     K::

c 1K s   "( -c                  6   [        S5       V s/ s H  n SU -  PM
     nn [        R                  [        R                  -   S-    H  nX![	        U5      '   M     [        US   [        5      (       a   U Vs/ s H  o3R                  S5      PM     nnU$ s  sn f s  snf )z "
:return:
    **ASCII string**
   z%%%02Xz.~-_r   utf-8)rangestringascii_lettersdigitsordrB   r   encode)r:   retchr8   s       r!   _get_normalized_char_listra      s    
 "'s
,A8a<C
,""V]]2V;CG <#a&#*-.#Qxx #.J - /s   B3Bc                 B   / n[        U 5       H~  nSnSn[        U[        5      (       a  [        U5      R	                  S5      nUnOUn[        U5      nUS:X  a  U(       d  UR                  S5        Mf  UR                  [        U   5        M     SR                  U5      $ )z
Encode in_str.
When encoding_slash is True, don't encode skip_chars, vice versa.

:type in_str: string
:param in_str: None

:type encoding_slash: Bool
:param encoding_slash: None
===============================
:return:
    **ASCII  string**
rJ   rX      /r#   )	r?   rB   r7   chrr^   r]   append_NORMALIZED_CHAR_LISTjoin)in_strencoding_slashtmpr`   sepindexs         r!   normalize_stringrn      s     C(0b#b'..)CECGE$;~JJtJJ,U34 1 ::c?r#   c                 f   U /nU H'  nU(       d  M  UR                  [        US5      5        M)     [        U5      S:  ab  US   R                  S5      US'   US   R	                  S5      US'   [        S[        U5      S-
  5       H  nX$   R                  S5      X$'   M     SR                  U5      $ )z
Append path_components to the end of base_uri in order, and ignore all empty strings and None

:param base_uri: None
:type base_uri: string

:param path_components: None

:return: the final url
:rtype: str
F   r   rd   rc   )rf   rn   r   rstriplstriprY   rC   rh   )base_uripath_componentsrk   pathr:   s        r!   
append_urirv      s     *C4JJ'e45   3x!|Qt$Ab'..&Bq#c(Q,'AV\\$'CF (;;sr#   c                     Sn[        U 5      S:  d  [        U 5      S:  a  gU S   S:X  d	  U S   S:X  a  gSU S	   s=::  a  S
::  d  O  SU S	   s=::  a  S::  d   g  gU  H
  nX!;  d  M
    g   g)z
Check bucket name whether is legal.

:type bucket: string
:param bucket: None
=======================
:return:
    **Boolean**
z%abcdefghijklmnopqrstuvwxyz0123456789-   ?   Frc   -_rF   r   z09T)r   )bucketalphabetr:   s      r!   check_bucket_validr     s     7H
6{Q#f+*bzSF2J#-F1I$$#*Ac*A +B}  r#   c                    [        5       nSUS'   SUS'   SUS'   SUS'   S	US
'   SUS'   SUS'   SUS'   SUS'   SUS'   SUS'    [        R                  " U 5      n [        R                  R                  U R                  5       5      nUR                  S5      S   nU[        U5      ;   a  X   nO4SSK	nUR                  5         UR                  R                  SU-   S5      n U(       d  Sn[        R                  " U5      $ !   Sn N%= f)z
Get file type by filename.

:type file_name: string
:param file_name: None
=======================
:return:
    **Type Value**
zapplication/javascriptjszAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetxlsxzDapplication/vnd.openxmlformats-officedocument.spreadsheetml.templatexltxzEapplication/vnd.openxmlformats-officedocument.presentationml.templatepotxzFapplication/vnd.openxmlformats-officedocument.presentationml.slideshowppsxzIapplication/vnd.openxmlformats-officedocument.presentationml.presentationpptxzBapplication/vnd.openxmlformats-officedocument.presentationml.slidesldxzGapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentdocxzGapplication/vnd.openxmlformats-officedocument.wordprocessingml.templatedotxz.application/vnd.ms-excel.addin.macroEnabled.12xlamz5application/vnd.ms-excel.sheet.binary.macroEnabled.12xlsb.rc   r   Nzapplication/octet-stream)dictr
   convert_to_stringosru   basenamerK   r6   r   	mimetypesinit	types_mapgetr=   )	file_namemime_maprL   suffix	mime_typer   s         r!   guess_content_type_by_file_namer   )  s     vH-HTNZHV]HV^HV_HVbHV[HV`HV`HVGHVNHV/,,Y7	ww	 12C$Xh'' (INN!++//f>XYI .	""9--/.	s   A*D .3D Dz(.)([A-Z][a-z]+)z([a-z])([0-9]{2,})z([a-z0-9])([A-Z])c                     U S:X  a  g[         R                  SU 5      n[        R                  SU5      n[        R                  SU5      R	                  5       $ )a  Convert camel case to a "pythonic" name.
Examples::
    pythonize_name('CamelCase') -> 'camel_case'
    pythonize_name('already_pythonized') -> 'already_pythonized'
    pythonize_name('HTTPRequest') -> 'http_request'
    pythonize_name('HTTPStatus200Ok') -> 'http_status_200_ok'
    pythonize_name('UPPER') -> 'upper'
    pythonize_name('ContentMd5')->'content_md5'
    pythonize_name('') -> ''
eTagetagz\1_\2)_first_cap_regexsub_number_cap_regex_end_cap_regexrK   )rL   s1s2s      r!   pythonize_namer   W  sN     v~			h	-B			x	,Bh+1133r#   c                 <   U c  g/ n[        U 5       Hg  u  p4U(       a.  UR                  [        R                  R                  5       :w  d  M:  Uc  SnUR	                  S[        U5      [        U5      4-  5        Mi     UR                  5         SR                  U5      $ )z0

:param params:
:param for_signature:
:return:
rJ   s   %s=%s   &)r   rK   r   AUTHORIZATIONrf   rn   sortrh   )paramsfor_signatureresultrN   rO   s        r!   get_canonical_querystringr   i  s     ~F&!<+E+E+K+K+M MyMM(&6q&9;KA;N%OOP	 "
 KKM;;vr#   c                    / n[        U R                  5       H  u  p#UR                  S5      (       a  M  US:w  d  M%  [        U[        5      (       a  UR                  U< SU< S35        MU  [        U[        5      (       a  UR                  U< SU< S35        M  UR                  U< SU< 35        M     SSR                  U5      -  $ )	z

:param obj:
:return:
__raw_dataz:''z:u':z{%s},)r   __dict__
startswithrB   r   rf   r   rh   )objrk   rN   rO   s       r!   print_objectr   |  s     C#,,'||D!!a:o!U##

1-.As##

A./

a+, ( CHHSM!!r#   c                   .    \ rS rSrSrSS jrS rS rSrg)	Expandoi  z
Expandable class
Nc                 J    U(       a  U R                   R                  U5        g g N)r   r   )self	attr_dicts     r!   __init__Expando.__init__  s    MM  + r#   c                 <    UR                  S5      (       a  [        eg )Nr   )r   AttributeError)r   items     r!   __getattr__Expando.__getattr__  s    ??4    r#   c                     [        U 5      $ r   )r   r   s    r!   __repr__Expando.__repr__  s    D!!r#    r   )	__name__
__module____qualname____firstlineno____doc__r   r   r   __static_attributes__r   r#   r!   r   r     s    ,
"r#   r   c                     0 n[        U 5       HI  u  p#[        U[        R                  5      (       d  [        R                  " U5      n[        U5      nX1U'   MK     [        U5      $ )z

:param d:
:return:
)r   rB   r
   string_typesr   r   r   )dattrrN   rO   s       r!   dict_to_python_objectr     sY     D!!V0011((+A1Q	 
 4=r#   c                     ^  U 4S jnU$ )z7
decorator of input param check
:param types:
:return:
c                 :   >^  U U4S jnT R                   Ul         U$ )Nc                  f  > [        U 5       H  u  p#TR                  R                  U   T;   d  M$  Uc%  [        STR                  R                  U   -  5      e[	        UTTR                  R                  U      5      (       a  My  [        STR                  R                  U   < SU< STTR                  R                  U      < 35      e   [        U5       HL  u  pCUT;   d  M  Uc  [        SU-  5      e[	        UTU   5      (       a  M4  [        SU< SU< STU   < 35      e   T" U 0 UD6$ )Nzarg "%s" should not be Nonezarg "z"= z does not match )	enumerate__code__co_varnames
ValueErrorrB   	TypeErrorr   )argskwdsr:   rO   rN   ftypess        r!   
_decorated/required.<locals>._required.<locals>._decorated  s&   !$::))!,5y()F*+***@*@*C*E F F%aqzz/E/Ea/H)IJJ')*)?)?)B)*).qzz/E/Ea/H)I)K L L ( "$:y()F)JKK%aq22'AqRWXYRZ([\\ ( d#d##r#   )r   )r   r   r   s   ` r!   	_requiredrequired.<locals>._required  s    	$$  jj
r#   r   )r   r   s   ` r!   requiredr     s    * r#   c           	      v   SU ;  a  SU -   n  [        U [        R                  " UR                  5      5      nUR                  [        R                  " [        R                  R                  R                  5      :X  a?  [        R                  R                  n[        R                  R                  R                  nOUR                  [        R                  " [        R                  R                  R                  5      :X  a?  [        R                  R                  n[        R                  R                  R                  nO[        SUR                  -  5      eUR                  nUR                  b  UR                  nXFU4$ ! [         a,  n[        SU < S[        R                  " U5      < 35      eSnAff = f)aC  
parse protocol, host, port from endpoint in config

:type: string
:param endpoint: endpoint in config

:type: baidubce.protocol.HTTP or baidubce.protocol.HTTPS
:param default_protocol: if there is no scheme in endpoint,
                          we will use this protocol as default
:return: tuple of protocol, host, port
s   //zInvalid endpoint:z, error:NzUnsupported protocol %s)r   r
   r=   rL   	Exceptionr   r   schemebaidubceprotocolHTTPdefault_portHTTPShostnameport)endpointdefault_protocolparse_resulter   r   hosts          r!   parse_host_portr     s^    H8#*''(8(=(=>@ f55h6G6G6L6L6Q6QRR$$))  %%22			 7 78I8I8O8O8T8T U	U$$**  &&332\5H5HHII  D$  4!  *H$$Q') * 	**s   *F 
F8'F33F8c                     S nUSS n[         R                  n[         R                  " X45      nU" U 5      nUR                  SS9nUR	                  U5      n[
        R                  " US5      n	U	R                  SS9n
U
$ )zS

:param adminpass: adminpass
:param secretkey: secretkey
:return: cipheradminpass
c                 `    U S[        U 5      S-  -
  [        S[        U 5      S-  -
  5      -  -   $ )N   )r   re   )r8   s    r!   <lambda>+aes128_encrypt_16char_key.<locals>.<lambda>  s-    qBQ",BQ"4D0EEEr#   r   r   rX   )encoding	hex_codec)r   MODE_ECBnewr^   encryptcodecsdecode)	adminpass	secretkeypad_itkeymodecryptor	pad_adminbyte_pad_admincryptoradminpassbyte_cipheradminpasscipheradminpasss              r!   aes128_encrypt_16char_keyr    s     FF
Ab/C<<Dggc Gy!I%%w%7N~6 "==)9;G +1171CO r#   c                 r    U c  g[          H)  nU R                  5       R                  U5      (       d  M)    g   g)zI
:param host: custom domain
:return: domain end with cdn endpoint or not
FT)DEFAULT_CNAME_LIKE_LISTrK   endswith)r   r   s     r!   is_cname_like_hostr    s5    
 |)::<  (( * r#   c                    U b  Uc  gU R                  S5      nU R                  5       R                  [        R                  " UR                  5       5      5      =(       a     [        U5      S:H  =(       a    [        U 5      $ )zE
custom host : xxx.region.bcebos.com
: return: custom, domain or not
Fr3   r4   )r6   rK   r   r
   r=   r   is_bos_suffixed_host)r   bucket_name
host_splits      r!   is_custom_hostr  +  sm    
 |{*D!J::<""6#:#:;;L;L;N#OP J*o*J/CD/IJr#   c                     U c  gU R                  S5      (       a  U SS nOU nUR                  5       R                  [        5      $ )z8
:param host: bos endpoint
:return: bos endpoint or not
NFrd   rc   )r  rK   DEFAULT_BOS_DOMAIN_SUFFIX)r   
check_hosts     r!   r  r  9  sF    
 |}}T#2Y

&&'@AAr#   c                 P    [         R                  " S5      nUR                  U 5      $ )z2
:param ipAddr: ip address
:return: true or false
sL   ((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3})recompilematch)ipAddr
compile_ips     r!   
check_ipv4r   H  s$    
 zzijJF##r#   c                     [        U S5      (       a  [        U 5      $ [        U S5      (       a  U R                  $ [        U S5      (       a  [        U S5      (       a  [        U 5      $ g )N__len__r   r   r   )hasattrr   file_object_remaining_bytes)datas    r!   _get_data_sizer&  P  sV    tY4ytUxxtVv!6!6*400r#   c                     U R                  5       nU R                  S[        R                  5        U R                  5       nU R                  U[        R                  5        X!-
  $ Nr   )r   r   r   SEEK_ENDSEEK_SET)fileobjcurrentends      r!   r$  r$  \  sD    llnGLLBKK 
,,.CLL"++&=r#   c                 $    U (       a	  U " X5        g g r   r   )progress_callbackconsumed_bytestotal_bytess      r!   _invoke_progress_callbackr2  e  s    .6 r#   c                     Uc  [        U 5      nUc.  [        SR                  U R                  R                  5      5      e[        XU5      $ )a0  return a adapter,when reading 'data', that is, calling read or iterating 
over it Call the progress callback function

:param data: bytes,file object or iterable
:param progress_callback: callback function, ref:`_default_progress_callback`
:param size: size of `data`

:return: callback function adapter
z{0} is not a file object)r&  r   format	__class__r   _BytesAndFileAdapter)r%  r/  sizes      r!   make_progress_adapterr8  i  sF     |d#|3::4>>;R;RSTT>>r#   c                   F    \ rS rSrSrS	S jr\S 5       rS r\r	S
S jr
Srg)r6  i~  a  With this adapter, you can add progress monitoring to 'data'.

:param data: bytes or file object
:param progress_callback: user-provided callback function. like callback(bytes_read, total_bytes)
    bytes_read is readed bytes;total_bytes is total bytes
:param int size : data size 
Nc                 6    Xl         X l        X0l        SU l        g r(  )r%  r/  r7  r   )r   r%  r/  r7  s       r!   r   _BytesAndFileAdapter.__init__  s    	!2	r#   c                     U R                   $ r   )r7  r   s    r!   r   _BytesAndFileAdapter.len  s    yyr#   c                     g)NTr   r   s    r!   __bool___BytesAndFileAdapter.__bool__  s    r#   c                 Z   U R                   U R                  :  a  [        R                  " S5      $ Ub  US:  a  U R                  U R                   -
  nO"[	        XR                  U R                   -
  5      n[        U R                  [        5      (       a'  U R                  U R                   U R                   U-    nOU R                  R                  U5      nU =R                   U-  sl         [        U R                  [	        U R                   U R                  5      U R                  5        U$ )NrJ   r   )r   r7  r
   r=   minrB   r%  r   r   r2  r/  )r   amtr   contents       r!   r   _BytesAndFileAdapter.read  s    ;;$))#**2..;#' II3MYY%<=Mdii''iiDKK,EFGiinn]3G}$!$"8"8#dkk499:UW[W`W`ar#   )r%  r   r/  r7  )NNr   )r   r   r   r   r   r   propertyr   r?  __nonzero__r   r   r   r#   r!   r6  r6  ~  s1       K"r#   r6  c                 &   U(       a  [        S[        U 5      [        U5      -  -  5      nSU-  nSSU-
  -  nUS:X  a  [        SR                  X#U5      SS9  O[        SR                  X#U5      SS9  [        R
                  R                  5         gg)	zProgress bar callback function that calculates the percentage of current completion

:param consumed_bytes: Amount of data that has been uploaded/downloaded
:param total_bytes: According to the total amount
d   *r   z{}%[{}->{}]
rJ   )r-  z{}%[{}->{}]N)r7   floatprintr4  sysstdoutflush)r0  r1  ratestart_progressend_progresss        r!   default_progress_callbackrS    s     3%/%2DDEFtcDj)3;#**4NTVW/((|LRTU

 r#   )r   rc   r   )r   )Tr   )Dr   
__future__r   r   builtinsr   r   future.utilsr   r   r	   r   r
   r   r  r%   r   r   rZ   rM  urllib.parser   ImportErrorCrypto.Cipherr   baidubce.httpr   r   r  r  HTTP_PROTOCOL_HEADr"   r0   r;   r?   rH   rP   rU   ra   rg   rn   rv   r   r   r  r   r   r   r   r   r   objectr   r   r   r   r  r  r  r  r   r&  r$  r2  r8  _CHUNK_SIZEr6  rS  r   r#   r!   <module>r^     sf   & &  8 8  	 	     
"%   & -. )  "3J6&61$(&&
 23 B0.&.R ::01 JJ34 /04$&"$"f ""<% N:
JB$
7?& 96 9vs  "!"s   D D'&D'