
    Ncj                         S r SSKrSSKrSSKrSSKJrJr  SSKrSrSS0r	Sr
S rS	 rS
 rS rS rSS jrSrSr " S S\5      rS rS rSS jrg)ur   Сбор постов Telegram-каналов: веб-превью t.me/s (без ключей) или TGStat API.    N)datetimetimezonezhttps://t.me/s/{}z
User-AgentzqMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36u   веб-превью недоступно (канал скрытый, приватный или не существует) — попробуй источник tgstatc                    U c  gU R                  5       R                  SS5      R                  SS5      R                  SS5      n USS R                  5       S:X  a  [        [	        USS 5      S	-  5      $ USS R                  5       S
:X  a  [        [	        USS 5      S-  5      $ [        [	        U5      5      $ ! [
         a     gf = f)uH   '13K' → 13000, '1.2M' → 1200000, '419' → 419. Мусор → None.N      ,.ki  mi@B )stripreplacelowerintfloat
ValueError)textts     &/home/rasp/mars-trendwatch/fetch_tg.pyparse_countr      s    |

VR(00b9AA#sKARS6<<>S uQsV}t+,,RS6<<>S uQsV}w.//58} s   0B< 70B< (B< <
C	C	c                     [         R                  " SSU 5      n[         R                  " SSU5      n[        R                  " U5      R	                  5       $ )Nz	<br\s*/?>
z<[^>]+>r   )resubhtml_moduleunescaper   )fragmentr   s     r   _strip_htmlr       s@    66,h/D66*b$'D%++--    c                    / Sp2U R                  S5      SS  GH  n[        R                  " SU5      n[        R                  " SU5      nU(       a  U(       d  MB  [        UR	                  S5      5      nUc  UO
[        X75      n[        R                  " SU[        R                  5      n[        R                  " SU5      n	/ n
[        R                  " SU[        R                  5       HC  n[        R                  " S	U5      nU(       d  M#  U
R                  UR	                  S5      5        ME     SnU
(       a-  U
 Vs/ s H  n[        U5      PM     nn[        S
 U 5       5      nUR                  SR                  X5      USU(       a  [        UR	                  S5      5      OSUR	                  S5      USU	(       a  [        U	R	                  S5      5      OSSR                  X5      S.	5        GM     X#4$ s  snf )u~   Одна страница t.me/s → (records, min_post_id). Платные реакции (звёзды) не считаем.Nzclass="tgme_widget_message_wrap   zdata-post="[^"/]+/(\d+)"z<time datetime="([^"]+)"z)tgme_widget_message_text[^>]*>(.*?)</div>z#tgme_widget_message_views">([^<]+)<z(<span class="tgme_reaction">(.*?)</span>z([\d.,KMkm\xa0]+)\s*$c              3   .   #    U  H  oc  M  Uv   M     g 7fN ).0vs     r   	<genexpr>parse_page.<locals>.<genexpr>:   s     ;6a6s   	tg:{}:{}telegramr   zhttps://t.me/{}/{}	post_idaccountplatformcaption	posted_atlikescommentsviews	permalink)splitr   searchr   groupminSfindallappendr   sumformatr   )	page_htmlchannelrecordsmin_idblockr   time_mr-   text_mviews_m	reactionsspanrmr2   rparseds                   r   
parse_pagerL   &   s   $V!BCABGII1596>aggaj/"NF0DGPRPTPTU))BEJ	JJJESUSWSWXD3T:Br  !- Y .78ik!niF8;6;;E!((:"7={6<<?32a6=[q!124-44WF

 
	% H: ? 9s   =G8c                 v    [         R                  " SU 5      nU(       a  [        UR                  S5      5      $ S $ )NzEcounter_value">([^<]+)</span>\s*<span class="counter_type">subscriberr"   )r   r7   r   r8   )r?   r   s     r   parse_subscribersrN   I   s2    
		P	A '(;qwwqz"1T1r    c                    U R                  [        R                  U5      [        SS9nUR	                  5         [        UR                  U5      u  pE[        UR                  5      nU(       a  [        U5      U:  a  U(       a  US:  a  U R                  [        R                  U5      SU0[        SS9nUR	                  5         [        UR                  U5      u  pxU V	s1 s H  oS   iM	     n
n	U V	s/ s H  oS   U
;  d  M  U	PM     nn	U(       d   XF4$ XG-  nUnU(       a  [        U5      U:  a  U(       a  US:  a  M  XF4$ s  sn	f s  sn	f )N   )headerstimeoutr"   before)paramsrQ   rR   r-   )	get
TG_WEB_URLr>   HEADERSraise_for_statusrL   r   rN   len)httpr@   limitresprA   rB   subsmorenew_minrJ   knowns              r   _fetch_channel_webra   P   s(   88J%%g.8LD G4OGTYY'D
c'lU*v&1*xx
))'2Hf;M '  5"499g6'./w!9w/=4aY<u#<4= = 	 c'lU*v&1* = 0=s    E4E
E
c                 .   U=(       d    [         n/ 0 0 penU  HC  nUR                  5       n [        X7U5      u  pU(       d
  [
        XW'   M3  XHSU -  nU	c  M?  XU'   ME     XEU4$ ! [         R                   a  n
SR	                  U
5      XW'    Sn
A
Mx  Sn
A
ff = f)uP   Посты каналов из веб-превью. → (records, errors, subs).u   сеть/HTTP: {}N)requestsr   ra   RequestExceptionr>   PREVIEW_UNAVAILABLE)channelsr[   sessionrZ   rA   errorsr]   r@   chan_records	chan_subsexcs              r   	fetch_webrl   c   s    hDBTG--/	&8&N#L 1FO'' %M  D   (( 	188=FO	s   A""B6BBzhttps://api.tgstat.rug      ?c                       \ rS rSrSrSrg)TGStatError{   u2   TGStat вернул status=error или не-JSON.r%   N)__name__
__module____qualname____firstlineno____doc____static_attributes__r%   r    r   rn   rn   {   s    <r    rn   c                    [         R                  " SR                  [        U 5      [	        XS9SS9n UR                  5       nUR                  S5      S:X  a  UR                  S5      =(       d    0 $ [        [        UR                  S	5      =(       d    U5      5      e! [         a    [        SR                  U 5      5      ef = f)
Nz{}/{})token<   )rT   rR   u$   не-JSON ответ от TGStat /{}statusokresponseerror)	rc   rU   r>   TGSTAT_BASEdictjsonr   rn   str)methodrT   rw   r\   datas        r   _tgstat_requestr      s    <<{F;#F8"FDQyy{ xxT!xx
#)r)
c$((7+3t4
55	  Q@GGOPPQs   B %Cc                 P   SR                  XS   5      U S[        UR                  S5      =(       d    S5      [        R                  " US   [
        R                  S9R                  5       S S UR                  S5      UR                  S	5      =(       d    S
R                  U 5      S.	$ )Nr*   idr+   r   r   date)tzr4   linkzhttps://t.me/{}r,   )r>   r   rU   r   fromtimestampr   utc	isoformat)r@   items     r   normalize_tgstatr      s    $$W4j9txx/526++DLX\\JTTV'"XXf%J):)A)A')J
 
r    c                    / 0 0 pen[        U 5       H  u  pxUS:  a  [        R                  " [        5        UR	                  5       n	 [        SSU-   USS.U5      n
U
R                  S/ 5       HC  nUR                  S5      b  UR                  S	5      c  M)  UR                  [        X5      5        ME     U(       d  M   [        S
SSU-   0U5      nUR                  S5      b	  US   Xi'   M  M     XEU4$ ! [        [        R                  4 a  n[        U5      XY'    SnAGM  SnAff = f! [        [        R                  4 a     GM6  f = f)u   Посты каналов из TGStat API (лёгкий режим: только channels/posts
[+ channels/get при subscribers=True]). → (records, errors, subs).r   zchannels/posts@r"   )	channelIdr[   hideDeletedNitemsr   r   zchannels/getr   participants_count)	enumeratetimesleepTGSTAT_REQUEST_DELAYr   r   rn   rc   rd   r   rU   r<   r   )rf   r[   rw   subscribersrA   rh   r]   ir@   keyr\   rk   r   infos                 r   fetch_tgstatr      sF    BTG)
q5JJ+,mmo	" !GmeAND HHWb)Dxx~%&)9)ANN+C67 * ;&~S7]7SUZ[8801= $%9 :DI >' *. D   X667 	c(FK	  !:!:; s*   C3>+D)3D&D!!D&)EEr$   )F)rt   htmlr   r   r   r   r   rc   rV   rW   re   r   r   rL   rN   ra   rl   r}   r   	Exceptionrn   r   r   r   r%   r    r   <module>r      s{    x  	  '  
 7 9a . F2&!( & =) =	6!r    