+
    kHàjË8  ã                  ó®  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
HtHtHtHtHt ^RIHt ]P$                  ! ]4      tRtRt^t^
tR	t^tR
tRtRt^tRtRt  ! R R]!4      t" ! R R]"4      t# ! R R]"4      t$] ! R R4      4       t%] ! R R4      4       t&R R lt'R R lt(] ! R R4      4       t) ! R R 4      t*R! R" lt+R# R$ lt,R% R& lt-R# )'u&  QQ Bot chunked upload flow (files 10 MB..~100 MB; inline uploads cap at ~10 MB):
1. POST .../upload_prepare â†’ upload_id, block_size, pre-signed COS part URLs;
2. per part: PUT bytes to COS, then POST .../upload_part_finish;
3. POST .../files with {"upload_id"} â†’ ``file_info`` for a RichMedia message.
biz_code 40093001 = part_finish retryable until ``retry_timeout``; 40093002 = daily
quota (UploadDailyLimitExceededError); other API/I/O failures raise RuntimeError.
Ported from WideLee's qqbot-agent-sdk v1.2.2 (authorship via Co-authored-by).
)ÚannotationsN)Ú	dataclass)ÚPath)ÚAnyÚ	AwaitableÚCallableÚDictÚList)ÚFILE_UPLOAD_TIMEOUTiJÅciIÅcg     Àr@ç      ð?g      ^@g     À‚@g       @i  ˜ c                  óD   a € ] tR t^$tR V 3R llt]R R l4       tRtV ;t# )Ú_UploadErrorc               ó(   € V ^8„  d   QhRRRRRRRR/# ©é   Ú	file_nameÚstrÚ	file_sizeÚintÚmessageÚreturnÚNone© )Úformats   "ÚK/home/ubuntu/.hermes/hermes-agent/plugins/platforms/qqbot/chunked_upload.pyÚ__annotate__Ú_UploadError.__annotate__%   s(   € ÷ "ñ " #ð "°#ð "Àð "Èñ "ó    c                	óB   <€ WuV n         V n        \        SV `  V4       R # ©N)r   r   ÚsuperÚ__init__©Úselfr   r   r   Ú	__class__s   &&&&€r   r!   Ú_UploadError.__init__%   s   ø€ Ø)2Ð&ˆŒ˜œÜ‰Ñ˜Ö!r   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r   *   s   € ÷ +ñ + ñ +r   c                	ó,   € \        V P                  4      # r   )Úformat_sizer   ©r#   s   &r   Úfile_size_humanÚ_UploadError.file_size_human)   s   € ä˜4Ÿ>™>Ó*Ð*r   )r   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r!   Úpropertyr+   Ú__static_attributes__Ú__classcell__©r$   s   @r   r   r   $   s!   ø† ÷"ð "ð ô+ó ö+r   r   c                  ó6   a € ] tR t^.tRtRR V 3R llltRtV ;t# )ÚUploadDailyLimitExceededErrorzKRaised when ``upload_prepare`` returns biz_code 40093002 (daily quota hit).c               ó(   € V ^8„  d   QhRRRRRRRR/# r   r   )r   s   "r   r   Ú*UploadDailyLimitExceededError.__annotate__1   s.   € ÷ lñ l #ð l°#ð lÀð lÈTñ lr   c                	óD   <€ \         ST `  YT;'       g    R V: 24       R# )z Daily upload limit exceeded for N)r    r!   r"   s   &&&&€r   r!   Ú&UploadDailyLimitExceededError.__init__1   s$   ø€ Ü‰Ñ˜¨w×/jÐ/jÐ<\Ð]fÑ\iÐ:jÖkr   r   )Ú )r-   r.   r/   r0   Ú__doc__r!   r2   r3   r4   s   @r   r6   r6   .   s   ø† ÙU÷l÷ lð lr   r6   c                  óL   a € ] tR t^5tRtRR V 3R lllt]R R l4       tRtV ;t	# )ÚUploadFileTooLargeErrorz<Raised when a file exceeds the platform per-file size limit.c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r   r   r   r   Úlimit_bytesr   r   r   r   )r   s   "r   r   Ú$UploadFileTooLargeError.__annotate__8   s8   € ÷ xñ x #ð x°#ð xÀCð xÐVYð xÐcgñ xr   c           
     	ó    <€ W0n         V'       d   R \        V4       R2MRp\        ST `  YT;'       g    RV: R \        V4       RV 24       R# )z (Ú)r;   zFile z) exceeds platform limitN)r@   r)   r    r!   )r#   r   r   r@   r   Ú	limit_strr$   s   &&&&& €r   r!   Ú UploadFileTooLargeError.__init__8   sX   ø€ Ø&Ôß8C�bœ [Ó1Ð2°!Ñ4Èˆ	Ü‰Ñ˜Ø ×vÐv e¨I©=¸¼;ÀyÓ;QÐ:RÐRjÐktÐjuÐ$vö	xr   c               ó   € V ^8„  d   QhRR/# r'   r   )r   s   "r   r   rA   ?   s   € ÷ Pñ P˜Sñ Pr   c                	óT   € V P                   '       d   \        V P                   4      # R # )Úunknown)r@   r)   r*   s   &r   Úlimit_humanÚ#UploadFileTooLargeError.limit_human>   s#   € à04×0@×0@Ð0@Œ{˜4×+Ñ+Ó,ÐOÀiÐOr   )r@   )é    r;   )
r-   r.   r/   r0   r<   r!   r1   rI   r2   r3   r4   s   @r   r>   r>   5   s(   ø† ÙF÷xò xð ôPó öPr   r>   c                  ó:   € ] tR t^Ct$ R]R&   R]R&   ^ tR]R&   RtR# )Ú_PreparePartr   Úindexr   Úpresigned_urlÚ
block_sizer   N)r-   r.   r/   r0   Ú__annotations__rP   r2   r   r   r   rM   rM   C   s   ‡ àƒJØÓØ€J�×r   rM   c                  óR   € ] tR t^Jt$ R]R&   R]R&   R]R&   ]tR]R&   RtR	]R
&   RtR# )Ú_PrepareResultr   Ú	upload_idr   rP   zlist[_PreparePart]ÚpartsÚconcurrencyç        ÚfloatÚretry_timeoutr   N)	r-   r.   r/   r0   rQ   Ú_DEFAULT_CONCURRENT_PARTSrV   rY   r2   r   r   r   rS   rS   J   s&   ‡ àƒNØƒOØÓØ0€K�Ó0Ø€M�5×r   rS   c               ó    € V ^8„  d   QhRRRR/# )r   Úrawúdict[str, Any]r   rS   r   )r   s   "r   r   r   S   s   € ÷ Cñ C ð C°Nñ Cr   c                óV  € \        V P                  R4      \        4      '       d   V P                  R4      MT p\        VP                  RR4      4      ;p'       g   \	        R\        V 4      R,           24      h\        VP                  R^ 4      4      pVP                  R4      ;'       g    VP                  R4      ;'       g    . p\        V\        4      '       d	   V'       g   \	        R	\        V 4      R,           24      hV Uu. uF¸  p\        V\        4      '       g   K  \        \        VP                  R
4      ;'       g    VP                  R4      ;'       g    ^ 4      \        VP                  R4      ;'       g    VP                  R4      ;'       g    R4      \        VP                  R^ 4      4      R7      NKº  	  pp\        Y#T\        VP                  R\        4      4      ;'       g    \        \        VP                  RR4      ;'       g    R4      R7      # u upi )zCParse upload_prepare response (either bare or wrapped in ``data``).ÚdatarT   r;   z+upload_prepare response missing upload_id: ºNéÈ   NrP   rU   Ú	part_listz'upload_prepare response missing parts: Ú
part_indexrN   rO   Úurl)rN   rO   rP   rV   rY   rW   )rT   rP   rU   rV   rY   )Ú
isinstanceÚgetÚdictr   Ú
ValueErrorr   ÚlistrM   rS   rZ   rX   )r\   ÚsrcrT   rP   Ú	raw_partsÚprU   s   &      r   Ú_parse_prepare_responserm   S   s´  € ä'¨¯©°«¼×>Ò>ˆ#�'‰'�&Œ/ÀC€CÜ˜SŸW™W [°"Ó5Ó6Ð6ˆIÖ6ÜÐFÄsÈ3ÃxÐPTÅ~ÐFVÐWÓXÐXÜ�S—W‘W˜\¨1Ó-Ó.€JØ—‘˜Ó ×>Ð> C§G¡G¨KÓ$8×>Ð>¸B€IÜ�i¤×&Ò&¯iÜÐBÄ3ÀsÃ8ÈDÅ>ÐBRÐSÓTÐTñ  ó8ñ  �¤:¨a´×#6ôBŒ\¤ A§E¡E¨,Ó$7×$NÐ$N¸1¿5¹5À»>×$NÐ$NÈQÓ OÜ(+¨A¯E©E°/Ó,B×,XÐ,XÀaÇeÁeÈEÃl×,XÐ,XÐVXÓ(YÜ%(¨¯©¨|¸QÓ)?Ó%@÷Bñ  ð 
ð 8ô Ø¸%Ü˜Ÿ™ Ô/HÓIÓJ×gÐgÔNgÜ˜CŸG™G O°SÓ9×@Ð@¸SÓAôCð Cùò	8s$   Ä	H&Ä&!H&ÅH&Å!"H&ÆH&Æ*H&c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Ú	chat_typer   Ú	target_idÚendpointr   r   )r   s   "r   r   r   f   s.   € ÷ [ñ [˜ð [¨ð [¸ð [Àñ [r   c                ó(   € V R 8X  d   RMR RV RV 2# )Úc2cz	/v2/usersz
/v2/groupsÚ/r   )ro   rp   rq   s   &&&r   Ú	_api_pathru   f   s$   € Ø&¨%Ô/‰k°\ÐBÀ!ÀIÀ;ÈaÐPXÈzÐZÐZr   c                  ó–   € ] tR t^jt$ RtR]R&   R]R&   R]R&   R]R&   RtR]R	&   ^ tR]R
&   ^ tR]R&   Rt	R]R&   ^ t
R]R&   R R ltRtR# )Ú_Jobz,Per-upload state shared by the part workers.r   ro   rp   Ú	file_pathr   r   r;   rT   rP   Útotal_partsrW   rX   rY   Ú	completedc               ó    € V ^8„  d   QhRRRR/# )r   rq   r   r   r   )r   s   "r   r   Ú_Job.__annotate__w   s   € ÷ Cñ C˜Sð C Sñ Cr   c                	óD   € \        V P                  V P                  V4      # r   )ru   ro   rp   )r#   rq   s   &&r   ÚpathÚ	_Job.pathw   s   € Ü˜Ÿ™¨¯©¸ÓBÐBr   r   N)r-   r.   r/   r0   r<   rQ   rT   rP   ry   rY   rz   r~   r2   r   r   r   rw   rw   j   sW   ‡ á6ØƒNØƒNØƒNØƒNØ€IˆsÓØ€J�ÓØ€K�ÓØ€M�5ÓØ€IˆsÓ÷Cñ Cr   rw   c                  óŠ   € ] tR t^{tRtRR R lltR R ltR R ltR R	 ltR
 R lt	R R lt
R R ltR R ltR R ltRtR# )ÚChunkedUploaderu@  Run the prepare â†’ PUT parts â†’ complete sequence. ``api_request`` is the adapter's
bound ``_api_request(method, path, body=..., timeout=...)`` (injected to avoid a
circular import; must raise RuntimeError with the biz_code in the message);
``http_put`` is ``(url, data, headers) -> httpx-like response`` for COS PUTs.c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úapi_requestz(Callable[..., Awaitable[dict[str, Any]]]Úhttp_putzCallable[..., Awaitable[Any]]Úlog_tagr   r   r   r   )r   s   "r   r   ÚChunkedUploader.__annotate__�   s,   € ÷  ñ  Ð$Lð  Ø8ð ØCFð ØUYñ r   c                	ó*   € Wn         W n        W0n        R # r   ©Ú_api_requestÚ	_http_putÚ_log_tag)r#   rƒ   r„   r…   s   &&&&r   r!   ÚChunkedUploader.__init__�   s   € à'ÔØ!ŒØŽr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Újobrw   rq   r   Úbodyr]   r   r   )r   s   "r   r   r†   ‡   s.   € ÷ kñ k˜tð k¨sð k¸.ð kÈ^ñ kr   c              ƒ  	ón   "  € V P                  R VP                  V4      V\        R7      G Rj  x€L
 #  L5i)ÚPOST)r�   ÚtimeoutN)r‰   r~   r
   )r#   rŽ   rq   r�   s   &&&&r   Ú_postÚChunkedUploader._post‡   s/   é € Ø×&Ñ& v¨s¯x©x¸Ó/AÈÔViÐ&Ój×jÐjÑjùs   ‚,5®3¯5c               ó0   € V ^8„  d   QhRRRRRRRRRRRR	/# )
r   ro   r   rp   rx   Ú	file_typer   r   r   r]   r   )r   s   "r   r   r†   Š   s9   € ÷ )ñ ) cð )°cð )Àcð )ÐVYð )Ðfið )Ðn|ñ )r   c              ƒ  ó¸  a a	a
a"  € VR	9  d   \        RV: 24      h\        WV\        V4      P                  4       P                  4      o
\
        P                  RS P                  V\        S
P                  4      V4       \        P                  ! 4       P                  R\        VS
P                  4      G Rj  x€L
 pS P                  S
WEV4      G Rj  x€L
 p\        VP                   \"        4      pVP$                  VP&                  \)        VP*                  4      uS
n        S
n        S
n        \        VP.                  ^ 8”  d   VP.                  M\0        \2        4      S
n        \
        P                  RS P                  S
P$                  \        S
P&                  4      S
P,                  V4       \        P4                  ! \7        V^4      4      oR V
V V3R llo	\        P8                  ! V	3R lVP*                   4       !  G Rj  x€L
  \
        P                  RS P                  S
P,                  4       S P;                  S
4      G Rj  x€L
 #  EL— EL LN L5i)
z÷Run the full chunked upload (``chat_type`` 'c2c'|'group', ``file_type`` MEDIA_TYPE_*)
and return the raw ``complete_upload`` response (contains ``file_info``).
Raises UploadDailyLimitExceededError (40093002), UploadFileTooLargeError, RuntimeError.z'ChunkedUploader: unsupported chat_type z2[%s] Chunked upload start: file=%s size=%s type=%dNzA[%s] Prepared: upload_id=%s block_size=%s parts=%d concurrency=%dc               ó    € V ^8„  d   QhRRRR/# )r   ÚpartrM   r   r   r   )r   s   "r   r   Ú,ChunkedUploader.upload.<locals>.__annotate__ž   s   € ÷ 	7ñ 	7˜\ð 	7¨dñ 	7r   c              “  óÐ   <"  € S;_uu_4       GR j  x€L
  SP                  SV 4      G R j  x€L
  R R R 4      GR j  x€L
  R #  L0 L L
  + GR j  x€L 
 '       g   i     R # ; i5ir   )Ú_upload_one_part)r™   rŽ   r#   Úsems   &€€€r   Ú_runÚ$ChunkedUploader.upload.<locals>._runž   s:   øé € ß—s’sØ×+Ñ+¨C°Ó6×6Ð6÷ —s“sÙ6÷ —s—s“süsW   ƒA&’A“A&–A	¬A­A	±A&¼A½A&ÁA	ÁA&Á	A#	ÁAÁ
A#	ÁA#	Á	A&c              3  ó4   <"  € T F  pS! V4      x € K  	  R # 5ir   r   )Ú.0rl   rž   s   & €r   Ú	<genexpr>Ú)ChunkedUploader.upload.<locals>.<genexpr>¢   s   øé € Ð>±¨1™t AŸw˜w³ùs   ƒu)   [%s] All %d parts uploaded, completingâ€¦>   rs   Úgroup)rh   rw   r   ÚstatÚst_sizeÚloggerÚinfor‹   r)   r   ÚasyncioÚget_running_loopÚrun_in_executorÚ_compute_file_hashesÚ_prepareÚminrV   Ú_MAX_CONCURRENT_PARTSrT   rP   ÚlenrU   ry   rY   Ú_PART_FINISH_DEFAULT_TIMEOUTÚ_PART_FINISH_MAX_TIMEOUTÚ	SemaphoreÚmaxÚgatherÚ	_complete)r#   ro   rp   rx   r–   r   ÚhashesÚprepareÚmax_concurrentrž   rŽ   r�   s   f&&&&&   @@@r   ÚuploadÚChunkedUploader.uploadŠ   sË  ûé € ð Ð,Ô,ÜÐFÀyÁmÐTÓUÐUÜ�9¨´D¸³O×4HÑ4HÓ4J×4RÑ4RÓSˆÜ�‰ÐHÈ$Ï-É-ÐYbÜ §¡Ó.°	ô	;ô ×/Ò/Ó1×AÑAÀ$ÔH\Ð^gÐil×ivÑivÓw×wˆØŸ™ c¨9ÀÓH×HˆÜ˜W×0Ñ0Ô2GÓHˆØ9@×9JÑ9JÈG×L^ÑL^Ô`cÐdk×dqÑdqÓ`rÐ6ˆŒ�s”~ s¤Ü¸×9NÑ9NÐQRÔ9R × 5Ò 5ÔXtÜ 8ó:ˆÔä�‰ÐWÐY]×YfÑYfØ—M‘M¤;¨s¯~©~Ó#>ÀÇÁÐQ_ô	aä×Ò¤ N°AÓ 6Ó7ˆ÷	7ò 	7ô �nŠnÔ>°·²Ó>Ñ?×?Ð?Ü�‰Ð?ÀÇÁÐPS×P_ÑP_Ô`Ø—^‘^ CÓ(×(Ð(ò! xÚHñ 	@á(ùsJ   †B3IÂ9IÂ:IÃIÃD2IÈIÈAIÉIÉIÉIÉIÉIc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   rŽ   rw   r–   r   r   r   r·   údict[str, str]r   rS   r   )r   s   "r   r   r†   ¦   s1   € ÷ 	,ñ 	, $ð 	,°3ð 	,À3ð 	,ÐP^ð 	,Ðcqñ 	,r   c              ƒ  	óH  "  € R VRVRVP                   RVR,          RVR,          RVR,          /p V P                  VRV4      G Rj  x€L
 p\        T4      #  L  \         d<   p\         \	        T4      9   d!   \        Y1P                   \	        T4      4      Thh Rp?ii ; i5i)r–   r   r   Úmd5Úsha1Úmd5_10mÚupload_prepareN)r   r“   ÚRuntimeErrorÚ_BIZ_CODE_DAILY_LIMITr   r6   rm   )r#   rŽ   r–   r   r·   r�   r\   Úexcs   &&&&&   r   r­   ÚChunkedUploader._prepare¦   s¡   é € Ø˜Y¨°YÀÈSÏ]É]Ø�v˜e•} f¨f°V­n¸iÈÐPYÕIZð\ˆð	ØŸ
™
 3Ð(8¸$Ó?×?ˆCô
 ' sÓ+Ð+ñ @øÜô 	Ü'Ð(¬S°«XÔ5Ü3°I¿}¹}ÌcÐRUËhÓWÐ]`Ð`Øûð	üs:   ‚.B"±A ÁAÁA ÁB"ÁA ÁBÁ$6BÂBÂB"c               ó$   € V ^8„  d   QhRRRRRR/# )r   rŽ   rw   r™   rM   r   r   r   )r   s   "r   r   r†   ±   s!   € ÷ "ñ "¨$ð "°lð "Àtñ "r   c           	   ƒ  ó(  "  € VP                   VP                  rCV^,
          VP                  ,          p\        VP                  ^ 8”  d   VP                  MVP                  VP                  V,
          4      p\
        P                  ! 4       P                  R\        VP                  WV4      G Rj  x€L
 p\        P                  ! V4      P                  4       p\        P                  RV P                  W4\!        V4      WX4       V P#                  VP$                  WsV4      G Rj  x€L
  V P'                  WWh4      G Rj  x€L
  V;P(                  ^,          un        \        P                  RV P                  W4VP(                  V4       R#  LÛ Lh LP5i)z6PUT one part to COS, then call ``upload_part_finish``.Nz0[%s] Part %d/%d: uploading %s (offset=%d md5=%s)z"[%s] Part %d/%d done (%d/%d total))rN   ry   rP   r®   r   r©   rª   r«   Ú_read_file_chunkrx   Úhashlibr¿   Ú	hexdigestr§   Údebugr‹   r)   Ú_put_to_presigned_urlrO   Ú_part_finish_with_retryrz   )	r#   rŽ   r™   rc   ry   ÚoffsetÚlengthr_   Úmd5_hexs	   &&&      r   rœ   Ú ChunkedUploader._upload_one_part±   s,  é € à"&§*¡*¨c¯o©o�KØ˜q•. C§N¡NÕ2ˆä¨¯©¸!Ô(;�T—_’_ÀÇÁÐQT×Q^ÑQ^ÐagÕQgÓhˆÜ×-Ò-Ó/×?Ñ?ÀÔFVÐX[×XeÑXeÐgmÓv×vˆÜ—+’+˜dÓ#×-Ñ-Ó/ˆÜ�‰ÐGÈÏÉÐXbÜ  Ó(¨&ô	;à×(Ñ(¨×);Ñ);¸TÈ{Ó[×[Ð[Ø×*Ñ*¨3¸FÓL×LÐLØ�Š˜Õ�Ü�‰Ð9¸4¿=¹=È*Ðcf×cpÑcpØ ö	"ñ wñ 	\ÙLùs8   ‚B.FÂ0FÂ1A4FÄ%FÄ&FÄ?FÅ AFÆFÆFc               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r   Ú
attempt_fnzCallable[[], Awaitable[Any]]Úmax_retriesr   Ú
base_delayrX   Úlabelr   Úfailure_labelr   r   r   )r   s   "r   r   r†   Á   sD   € ÷ cñ cÐ.Jð cÐ\_ð cÐmrð cØ#&ðcØ7:ðcØ?Bñcr   c          
   ƒ  ó–  "  € Rp\        V^,           4       F  p V! 4       G Rj  x€L
 u # 	  \        V RV^,            RV 24      h L"  \         dr   pTpYr8  d_   T^T,          ,          p	\        P                  RT P                  YG^,           Y˜4       \
        P                  ! T	4      G Rj  x€L 
   Rp?K¤   Rp?Kª  Rp?ii ; i5i)zJRun *attempt_fn* up to ``max_retries + 1`` times with exponential backoff.Nz-[%s] %s attempt %d failed, retry in %.1fs: %sz failed after z attempts: )ÚrangeÚ	Exceptionr§   Úwarningr‹   r©   ÚsleeprÃ   )
r#   rÔ   rÕ   rÖ   r×   rØ   Úlast_excÚattemptrÅ   Údelays
   &&$$$$    r   Ú_with_retriesÚChunkedUploader._with_retriesÁ   s¼   é € ð &*ˆÜ˜[¨1�_Ö-ˆGð/Ù'›\×)Ò)ñ .ô ˜m˜_¨N¸;È½?Ð:KÈ;ÐW_ÐV`ÐaÓbÐbñ *øÜô /Ø�ØÔ(Ø&¨!¨w­,Õ7�EÜ—N‘NÐ#RÐTX×TaÑTaÐchÐtuÕjuØ#(ô/ä!Ÿ-š-¨Ó.×.×.õ	 )ûð/üsJ   ‚C	›
A
¥A¦A
©C	ÁA
Á
CÁACÂ/B2Â0CÂ5C	ÃCÃC	c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   rd   r   r_   Úbytesrc   r   ry   r   r   r   )r   s   "r   r   r†   Ñ   s8   € ÷ Zñ Z¨sð Z¸%ð ZÈSð ZÐ_bð ZÐgkñ Zr   c              ƒ  ó”   a aaaa"  € R VVV VV3R llpS P                  V\        RRS RS 2RS RS R2R7      G R	j  x€L
  R	#  L5i)
z1PUT part data to a pre-signed COS URL with retry.c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   Ú;ChunkedUploader._put_to_presigned_url.<locals>.__annotate__Ô   s   € ÷ 	Mñ 	M ñ 	Mr   c               “  óž  <"  € \         P                  ! SP                  SSR \        \	        S4      4      /R7      \
        R7      G Rj  x€L
 p \        V R^ 4      p^ÈTu;8:  d   R8  d)   M M%\        P                  RSP                  SSV4       R#  \        V RR4      R	,          p\        R
V RV 24      h Ln  \         d    Rp L"i ; i5i)zContent-Length)r_   Úheaders)r’   NÚstatus_codei,  z[%s] PUT part %d/%d: %d OKÚtextr;   r`   zCOS PUT returned z: )r©   Úwait_forrŠ   r   r°   Ú_PART_UPLOAD_TIMEOUTÚgetattrr§   rÌ   r‹   rÛ   rÃ   )ÚrespÚstatusÚbody_previewr_   rc   r#   ry   rd   s      €€€€€r   Ú_attemptÚ7ChunkedUploader._put_to_presigned_url.<locals>._attemptÔ   sË   øé € Ü ×)Ò)¨$¯.©.¸À4ÐRbÔdgÔhkÐlpÓhqÓdrÐQs¨.Ó*tÜ2FôH÷ HˆDä˜T =°!Ó4ˆFØ�fÖ"˜s×"Ü—‘Ð9¸4¿=¹=È*ÐVaÐciÔjÙð"Ü& t¨V°RÓ8¸Õ>�ô Ð!2°6°(¸"¸\¸NÐKÓLÐLñHøô ô "Ø!’ð"üs7   ƒACÁ	B8Á
ACÂB: Â'CÂ:C
ÃCÃ	C
Ã
Cr   z	PUT part rt   zPart z upload©rÕ   rÖ   r×   rØ   N)rá   Ú_PART_UPLOAD_MAX_RETRIES)r#   rd   r_   rc   ry   rò   s   fffff r   rÍ   Ú%ChunkedUploader._put_to_presigned_urlÑ   s_   üé € ÷	Mô 	Mð × Ñ  Ô7OÐ\_Ø)2°:°,¸aÀ¸}Ð'MØ16°z°lÀ!ÀKÀ=ÐPWÐ/Xð !ó Z÷ 	Zô 	Zùs   ‡8A¿AÁ Ac          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   rŽ   rw   rc   r   rP   r¿   r   r   r   r   )r   s   "r   r   r†   å   s9   € ÷ Añ A°ð AÀ3ð AÐTWð AÐ^að AÐfjñ Ar   c           	   ƒ  óH  "  € RVP                   RVRVRV/p\        P                  ! 4       pVP                  4       ^ r‡  V P	                  VRV4      G Rj  x€L
  R#  L  \
         d·   p	\         \        T	4      9  d   h TP                  4       T,
          p
Y¡P                  8¼  d!   \        RTP                  R R	T R
T	 24      T	hT^,          p\        P                  RT P                  TY©4       \        P                  ! \        4      G Rj  x€L 
   Rp	?	KÝ  Rp	?	ii ; i5i)zWCall ``upload_part_finish``, retrying on biz_code 40093001 until ``job.retry_timeout``.rT   rc   rP   r¿   Úupload_part_finishNz4upload_part_finish persistent retry timed out after z.0fzs (z retries): z?[%s] part_finish retryable error, attempt %d, elapsed=%.1fs: %s)rT   r©   rª   Útimer“   rÃ   Ú_BIZ_CODE_PART_RETRYABLEr   rY   r§   rÌ   r‹   rÝ   Ú_PART_FINISH_RETRY_INTERVAL)r#   rŽ   rc   rP   r¿   r�   ÚloopÚstartrß   rÅ   Úelapseds   &&&&&      r   rÎ   Ú'ChunkedUploader._part_finish_with_retryå   s  é € à˜SŸ]™]¨L¸*ÀlÐT^Ð`eÐgjÐkˆÜ×'Ò'Ó)ˆØŸ™› aˆwØðAØ—j‘j Ð&:¸DÓA×AÐAÙñ Bøäô 
AÜ.Ð/¼¸C»Ô@ØØŸ)™)›+¨Õ-�Ø×/Ñ/Ô/Ü&Ð)]Ø*-×*;Ñ*;¸CÐ)@ÀÀGÀ9ÈKÐX[ÐW\ð(^ó _Ødgðhà˜1•�Ü—‘Ð^Ð`d×`mÑ`mÐovØ$ô+ä—m’mÔ$?Ó@×@×@ûð
AüsM   ‚<D"¿A ÁAÁA ÁD"ÁA ÁDÁ)B%DÄDÄDÄD"ÄDÄD"c               ó    € V ^8„  d   QhRRRR/# )r   rŽ   rw   r   r]   r   )r   s   "r   r   r†   ú   s   € ÷ nñ n 4ð n¨Nñ nr   c              ƒ  óh   a a"  € S P                  VV 3R l\        \        RRR7      G Rj  x€L
 #  L5i)u¤   Call ``complete_upload`` with retry â€” the ``/files`` endpoint (same as the simple URL upload)
selects the chunked-completion path when only ``upload_id`` is sent.c                 óB   <€ SP                  S R RS P                  /4      # )ÚfilesrT   )r“   rT   )rŽ   r#   s   €€r   Ú<lambda>Ú+ChunkedUploader._complete.<locals>.<lambda>þ   s   ø€ �D—J‘J˜s G¨k¸3¿=¹=Ð-IÔJr   Úcomplete_uploadrô   N)rá   Ú_COMPLETE_UPLOAD_MAX_RETRIESÚ_COMPLETE_UPLOAD_BASE_DELAY)r#   rŽ   s   ffr   r¶   ÚChunkedUploader._completeú   s=   ùé € ð ×'Ñ'ÝJÔXtÜ2Ð:KÐ[lð (ó n÷ nð 	nñ nùs   „'2«0¬2rˆ   N)ÚQQBot)r-   r.   r/   r0   r<   r!   r“   rº   r­   rœ   rá   rÍ   rÎ   r¶   r2   r   r   r   r�   r�   {   s@   † ñU÷
 õkõ)õ8	,õ"õ cõ Zõ(A÷*nñ nr   r�   c               ó    € V ^8„  d   QhRRRR/# )r   Ú
size_bytesr   r   r   r   )r   s   "r   r   r     s   € ÷ ñ ˜Cð  Cñ r   c                ój   € \        V 4      pR F  pVR8  d   VR RV 2u # VR,          pK  	  VR R2# )z>Return a human-readable file size string (e.g. ``'12.3 MB'``).g      �@z.1fÚ z TB)ÚBÚKBÚMBÚGB)rX   )r  ÚsizeÚunits   &  r   r)   r)     sJ   € ä�Ó€DÛ'ˆØ�&Œ=Ø˜3�Z˜q  Ð'Ò'Ø��Šñ (ð �3ˆZ�sÐÐr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rx   r   rÏ   r   rÐ   r   rä   r   )r   s   "r   r   r     s(   € ÷ ñ  ð ¨Sð ¸#ð À%ñ r   c                ó  € \        V R4      ;_uu_ 4       pVP                  V4       VP                  V4      pRRR4       \        X4      V8w  d"   \	        RV  RV RV R\        V4       R2	4      hV#   + '       g   i     LC; i)zQRead *length* bytes at *offset*; raises IOError on a short read (truncated file).ÚrbNzShort read from z: expected z bytes at offset z, got z (file may be truncated))ÚopenÚseekÚreadr°   ÚOSError)rx   rÏ   rÐ   Úfhr_   s   &&&  r   rÉ   rÉ     s‡   € ä	ˆi˜×	Ô	 "Ø
�‰�ŒØ�w‰w�v‹ˆ÷ 
ô ˆ4ƒy�FÔÜÐ(¨¨°;¸v¸hÐFWÐX^ÐW_Ð_eÔfiÐjnÓfoÐepð q0ð 1ó 2ð 	2à€K÷ 
×	ús   •#A3Á3B	c               ó$   € V ^8„  d   QhRRRRRR/# )r   rx   r   r   r   r   r½   r   )r   s   "r   r   r     s&   € ÷ qñ q Cð q°Cð q¸Nñ qr   c                ór  € \         P                  ! 4       \         P                  ! 4       \         P                  ! 4       rCpV\        8„  p^ p\	        V R4      ;_uu_ 4       pVP                  R4      ;p'       dg   VP                  V4       VP                  V4       V'       d)   \        V,
          ;p	^ 8”  d   VP                  VRV	 4       V\        V4      ,          pK   RRR4       VP                  4       p
RT
RVP                  4       RV'       d   VP                  4       /# T
/#   + '       g   i     LO; i)z_Compute md5, sha1, and md5_10m in a single pass (for small files md5_10m is just the full md5).r  i   Nr¿   rÀ   rÁ   )	rÊ   r¿   rÀ   Ú_MD5_10M_SIZEr  r  Úupdater°   rË   )rx   r   r¿   rÀ   rÁ   Úneed_10mÚ
bytes_readr  ÚchunkÚ	remainingÚfull_md5s   &&         r   r¬   r¬     sì   € ä Ÿš›¬¯ª«¼¿º»ˆw€CØœ=Ñ(€HØ€JÜ	ˆi˜×	Ô	 "Ø—w‘w˜u“~Ð%ˆeÖ%Ø�J‰J�uÔØ�K‰K˜Ôß¬-¸*Õ*DÐD˜YÈÔIØ—‘˜u Z iÐ0Ô1Øœ#˜e›*Õ$ŠJð &÷ 
ð �}‰}‹€HØ�8˜V T§^¡^Ó%5°y×YaÀ'×BSÑBSÓBUÐpÐpÐgoÐpÐp÷ 
×	ús   ÁD&Á8)D&Â"<D&Ä&D6	).r<   Ú
__future__r   r©   rÊ   ÚloggingÚdataclassesr   Úpathlibr   Útypingr   r   r   r   r	   Ú	constantsr
   Ú	getLoggerr-   r§   rÄ   rû   rZ   r¯   rí   rõ   rü   r±   r²   r  r	  r   rÛ   r   r6   r>   rM   rS   rm   ru   rw   r�   r)   rÉ   r¬   r   r   r   Ú<module>r.     s  ðñõ #ã Û Û Ý !Ý ß 7Õ 7å *à	×	Ò	˜8Ó	$€à Ð Ø#Ð ØÐ ØÐ ØÐ ØÐ Ø!Ð Ø$Ð Ø Ð Ø Ð Ø!Ð Ø€ô+�9ô +ôl Lô lôP˜lô Pð ÷ð ó ðð ÷ð ó ðõCõ&[ð ÷Cð Có ðC÷ Dnñ DnõNõ÷qr   