+
    {s»jL7  ã                   ó°  € R t ^ RIt^ RIt^ RIt^ RIHtHtHt ^ RIHt ]! ]	4      P                  4       P                  P                  P                  t]R,          R,          t]R,          R,          t]R,          R,          R	,          t]P                   P#                  ^ ]! ]R,          4      4       ^ RItRtR
 tR tRR ltRR ltR tR t]! 4        R# )u¹  Собрать когорты статей портала из реестра текстов и своего счётчика.

Когорта - статьи, вышедшие на одной неделе. Смотрим не суммарный трафик,
а жизнь статьи по месяцам после публикации.

Зачем скрипт. 14.09.2026 руководитель сверяла панель с эталоном PR Factory
и заметила, что раздел «Когортный анализ» пуст. Он писал «пока не вышла
ни одна статья», хотя на портале было шестнадцать статей с 03.09. Блок
показывал только демо-данные, а боевых не собирал никто.

Про разбивку. Раньше здесь стояло «счётчик хранит только текущую сумму,
истории по месяцам нет». Это была неправда: в сайт/данные/просмотры.json
у каждой статьи лежит поле «по_дням» с 04.09.2026 (найдено 15.09.2026).
Поэтому считаем не одну сумму, а жизнь когорты по неделям после выхода -
месяцы для статей возрастом в пару недель всё равно бессмысленны.

Чего счёт правда не умеет: до 11.09 просмотры собирала своя служба портала,
после переезда на WordPress она умерла, и с 11.09 счёт идёт разбором логов
nginx. Шов виден в данных, и про него сказано в оговорке.

Порядок: после обновить-статьи.py, до обновить-фолбэк.py.

Запуск: python3 панель/данные/обновить-когорты.py
N)ÚdateÚdatetimeÚ	timedelta)ÚPathu   панельu   данныеu
   заводu    реестр-текстов.jsonu   сайтu   просмотры.jsonc           	      óþ  € \         P                  ! R T ;'       g    R4      pV'       dV   \        \        VP	                  ^4      4      \        VP	                  ^4      4      \        VP	                  ^4      4      4      # \         P                  ! RT ;'       g    R4      pV'       dV   \        \        VP	                  ^4      4      \        VP	                  ^4      4      \        VP	                  ^4      4      4      # R# )z(\d{4})-(\d{2})-(\d{2})Ú z(\d{2})\.(\d{2})\.(\d{4})N)ÚreÚsearchr   ÚintÚgroup)ô   статусô   мs   & ô"   обновить-когорты.pyô   дата_публикацииr   ,   s©   € Ü	�ŠÐ-¨|×/AÐ/A¸rÓ	B€Bß	Ü”C˜Ÿ™ ›Ó$¤c¨"¯(©(°1«+Ó&6¼¸B¿H¹HÀQ»KÓ8HÓIÐIÜ	�ŠÐ/°×1CÐ1CÀÓ	D€Bß	Ü”C˜Ÿ™ ›Ó$¤c¨"¯(©(°1«+Ó&6¼¸B¿H¹HÀQ»KÓ8HÓIÐIÙó    c                ó¦  a€ \        V3R lV  4       4      p^ .V,          pV  F—  pVR,          ;'       g    / P                  4        Fo  w  rV \        P                  ! V4      pYtR,          ,
          P
                  ^,          p^ Tu;8:  d
   T8  g   KM  M KQ  Y8;;,          T;'       g    ^ ,          uu&   Kq  	  K™  	  W23#   \         d     Kˆ  i ; i)uÎ  Просмотры когорты по неделям жизни: 1-я неделя после выхода, 2-я и так далее.

Считаем от даты выхода каждой статьи, а не от календаря: в одной когорте
статьи вышли в разные дни, и календарная неделя смешала бы первый день
жизни одной статьи с шестым днём другой.

Неделя, которую прожили не все статьи когорты, в итог не идёт: иначе
последний столбик всегда проседает просто потому, что он неполный.
c              3   ót   <"  € T F-  pSVR ,          ,
          P                   ^,           ^,          x € K/  	  R# 5i)õ   датаN©Údays)Ú.0ô   сô   сегодняs   & €r   Ú	<genexpr>ô1   жизнь_по_неделям.<locals>.<genexpr>C   s/   øé € ÐbÑUaÈr˜>¨B¨z­NÕ:×@Ñ@À1ÕDÈ×JÒJÓUaùs   ƒ58õ   по_днямr   )ÚminÚitemsr   ÚfromisoformatÚ
ValueErrorr   )	ô   списокr   ô   прожитоô   неделиr   ô   деньô   сколькоô   дô   иs	   &f       r   ô   жизнь_по_неделямr'   6   sÃ   ø€ ô ÔbÑUaÓbÓb€NØ�3˜Õ'€LÛˆØ)+¨OÕ)<×)BÐ)BÀ×(IÑ(IÖ(KÑ$ˆHðÜ×'Ò'¨Ó1�ð ˜*•~Õ%×+Ñ+¨qÕ0ˆBØ�BÖ'˜×'Ò'Ø×  N×$7Ð$7°aÕ7Õ ó )Lñ ð Ð'Ð'øô ô Úðús   ÁCÃCÃCc                óê   € V P                  R4      ^ ,          P                  4       ;'       g    T p\        V4      V8:  d   V# VRV P                  R^4      ^ ,          pT;'       g    VRV R,           # )u_  Название до первого двоеточия или до предела - по границе слова.

Раньше заголовок резали ровно на 18 знаков, и в панели стояло
«Бизнес-план: струк, Договор франшизы: , Защита прав предпр» (15.09.2026).
Ú:NÚ u   …)ÚsplitÚstripÚlenÚrsplit)ô   заголовокô   пределô   головаô
   обрезs   &&  r   ô   краткоr3   Q   sv   € ð &×+Ñ+¨CÓ0°Õ3×9Ñ9Ó;×QÐQÐ?Q€LÜ
ˆ<Ó˜LÔ(ØÐØ˜m˜|Ð,×3Ñ3°C¸Ó;¸AÕ>€JØ×5Ð5˜, }¨Ð5¸Õ>Ð>r   c                óÐ   € V RV  Uu. uF  p\        V4      NK  	  pp\        V 4      \        V4      ,
          pRP                  V4      V^ 8”  d   RV 2,           # R,           # u upi )ur   Названия статей когорты, коротко и без обрубков посреди слова.Nz, u    и ещё r   )r3   r-   Újoin)ô   заголовкиr$   ô   зô
   видноô
   хвостs   &&   r   ô   переченьr:   ^   sh   € à-?ÀÀÑ-PÓQÑ-P r”,˜rÖ"Ñ-P€JÐQÜÐ'Ó(¬3¨z«?Õ:€JØ�9‰9�ZÓ À*ÈqÄ. k°*°Ð$>ÕYÐYÐVXÕYÐYùò Rs   ˆA#c                   óþ	  € \         P                  ! \        P                  R R7      4      p \        P
                  ! 4        \        P                  ! 4       R,          p\        P                  4       '       d2   \         P                  ! \        P                  R R7      4      R,          M/ p. pV R,           EFW  pR\        VP                  R4      ;'       g    R4      P                  4       9   p\        VP                  R4      4      pV'       g   K]  V'       g   Kg  VP                  R4      ;'       g    RP                  R4      pVP                  V4      ;'       g    / p\        Y‚P                  V4      ;'       g    / P                  R	4      ;'       g    / R
7      pWq9   p	TP                  RTRVP                  R4      ;'       g    RRV	'       d   VP                  R^ 4      MRRT	RTR	VP                  R	4      ;'       g    / /4       EKZ  	  V'       g   . # / p
V FS  pVR,          \!        VR,          P#                  4       R7      ,
          pV
P%                  V. 4      P                  V4       KU  	  \&        P(                  ! 4       p. p\+        \-        V
P/                  4       4      ^4       EF:  w  pw  ppV\!        ^R7      ,           pV Uu. uF  q»R,          '       g   K  VNK  	  ppV Uu. uF  q»R,          '       d   K  VNK  	  ppV'       d   \1        R V 4       4      MRpWÜ,
          P2                  pVP4                  VP4                  8X  dH   VP6                   RVP6                   R\8        VP4                  ^,
          ,           RVP:                   2MXVP6                   R\8        VP4                  ^,
          ,           RVP6                   R\8        VP4                  ^,
          ,           2p\=        VV4      w  pp\-        R V 4       4      pTP                  RRV RV 2R\?        V4      R\A        V4      RV^8:  d   V.MRV.RTRTRTRRR V'       d    Ve   \C        V\?        V4      ,          4      MRR!\?        V4      R"V Uu. uF  q»R,          NK  	  upR#V'       g   RM1V'       g   R$\?        V4       R%2MR&\?        V4       R'\?        V4       R(2R)VR*R+/4       EK=  	  V# u upi u upi u upi ),úutf-8©Úencodingu   статьиu   текстыu,   опубликовано на порталеu   статусr   u   слагÚ/r   )r   r   õ   заголовокõ   просмотрыõ
   всегоNu   мерилиr   c              3   ó2   "  € T F  qR ,          x € K  	  R# 5i)rA   N© ©r   r   s   & r   r   ô!   собрать.<locals>.<genexpr>”   s   é € ÐI¹L°bÐ0×1Ò1»Lùó   ‚Ú-r*   z - c              3   ó2   "  € T F  qR ,          x € K  	  R# 5i)r@   NrD   rE   s   & r   r   rF   š   s   é € Ð#TÁ|ÀÐ';×$<Ò$<Ã|ùrG   õ   когортаu   Неделя u    · õ   статейu   кластерыu   по_месяцамu   по_неделямõ   недель_прожитоu   в_топ10õ   на_статьюu   мерили_статейu   без_замераu   нота_замераu,   замера нет ни у одной из u    статей когортыu   замер есть у u    из uM   : у остальных статья ещё не попадала в логиu   возраст_днейu   демоF)"ÚjsonÚloadsô   РЕЕСТРÚ	read_textô   счётô   загрузитьô   сводкаô   ПРОСМОТРЫÚexistsÚstrÚgetÚlowerr   r,   ÚdictÚappendr   ÚweekdayÚ
setdefaultr   ÚtodayÚ	enumerateÚsortedr   Úsumr   ÚmonthÚdayô   МЕСЯЦЫÚyearr'   r-   r:   Úround)ô   рô   по_слагамô
   сырыеô   статьиô   тô   если_порталô   если_нетô   слагô   записьô   есть_замерô   группыr   ô   началоr   ô   итогô   нr    ô
   конецô   мерилиô   не_мерилиô
   всегоô   возрастô   подписьô   по_неделямr!   r6   s                             r   ô   собратьr|   e   sÉ  € Ü	�Š”L×*Ñ*°GÐ*Ó<Ó	=€BÜ×ÒÔ!Ü ×-Ò-Ó/°Õ?Ðô ×$Ñ$×&Ò&ô —’Ô.×8Ñ8À'Ð8ÓJÓKÈNÖ[Ø,.ð ð €LØ�× Ñ ˆØ NÔRUÐVX×V\ÑV\Ð]kÓVl×VrÐVrÐprÓRs×RyÑRyÓR{Ñ {ÐÜ7¸¿¹¸~Ó8NÓOˆß Ñ §_¡_ØŸ™˜zÓ*×0Ð0¨b×7Ñ7¸Ó<ˆHØ,×0Ñ0°Ó:×@Ð@¸bˆLÜ ¿^¹^ÈHÓ=U×=[Ð=[ÐY[×<`Ñ<`ÐapÓ<q×<wÐ<wÐuwÔxˆLð
 #+Ñ"?ÐØ×ÑØ˜OØ$ b§f¡fÐ-AÓ&B×&HÐ&HÀbØ$×K^ l×&6Ñ&6°|ÀQÔ&GÐdhØÐ 3Ø˜HØ ×!1Ñ!1°/Ó!B×!HÐ!HÀbð!÷ ñ !÷( Øˆ	ð €LÛˆØ˜*•~¬	°r¸*µ~×7MÑ7MÓ7OÔ(PÕPˆØ×Ñ ¨bÓ1×8Ñ8¸Ö<ñ ô —Z’Z“\€NØ€HÜ,5´f¸\×=OÑ=OÓ=QÓ6RÐTU×,VÑ(ˆÑ(ˆ\˜<Ø!¤I°1Ô$5Õ5ˆ
Ù%1ÓH¡\˜r¸×5GÑ5GŸ˜¡\ˆÐHÙ*6ÓQ©, BÀ×>PÑ>PŸR˜R©,ÐÐQ÷ NZ”SÑI¹LÓIÔIÐ_cˆ
Ø(Õ7×=Ñ=ˆà"×(Ñ(¨J×,<Ñ,<Ô<ð *×-Ñ-Ð.¨a°
·±Ð/?¸qÄÈj×N^ÑN^ÐabÕNbÕAcÐ@dÐdeÐfp×fuÑfuÐevÑwà"×&Ñ&Ð' q¬°l×6HÑ6HÈ1Õ6LÕ)MÐ(NÈcÐR\×R`ÑR`ÐQaÐabÔcoÐpz÷  qAñ  qAð  DEõ  qEõ  dFð  cGð  Hð 	ô /MÈ\Ð[iÓ.jÑ+Ð˜^Ü#Ñ#TÁ|Ó#TÓTÐØ�‰Ø ¨b¨T°°nÐ5EÐFØœC Ó-ØÔ 0Ð1CÓ DØ!°>ÀRÔ3G J¡<ÈdÐT^ÐM_Ø!Ð#6Ø)¨>Ø˜*Ø˜4ØÏ<Ð\fÒ\r¤%¨
´S¸Ó5FÕ(FÔ"GØ#Ø'¬¨\Ó):Ø!ÑGXÓ#YÑGXÀÐ';×$<Ð$<ÑGXÑ#YØ#×0A¡bç$0ð  LÌCÐP\ÓL]ÐK^Ð^zÑ{à6´s¸<Ó7HÐ6IÈÔPSÐT`ÓPaÐObð ckð là% ~Ø˜ð'
÷ 	ñ -WðD €OùòA IùÚQùò, $Zs   ËS0Ë%S0Ë1S5ÌS5ÒS:4c                  ó’  € \        4       p \        R ,          p\        P                  ! VP	                  RR7      4      pVR,          pV '       dP   WR&   RVR&   \        R V  4       ^ R7      p\        V4       Uu. uF  qU^,            R	2NK  	  upVR
&   RVR&   RVR&   MRVR&   VP                  \        P                  ! VR^R7      RR7       \        R\        V 4       24       V  FX  pVR,          f   RMVR,          pVR,          f   RMVR,          p\        RVR,          R RVR,          R RVR RV R 2	4       KZ  	  R# u upi )!zreport.jsonr<   r=   Úseou   когортыr   u   когорты_пустоc              3   ó2   "  € T F  qR ,          x € K  	  R# 5i)rL   NrD   )r   ô   кs   & r   r   ô!   главная.<locals>.<genexpr>»   s   é € ÐWÉÀ"Ð<×=Ò=ËùrG   )Údefaultu   -я неделяu   когорты_неделиu  Когорта это статьи, вышедшие на одной неделе. Смотрим не суммарный трафик, а жизнь статьи после выхода: первые дни уходят на индексацию, дальше статья набирает вес или встаёт. Пока всем статьям меньше месяца, поэтому шаг недельный; на месяцы перейдём, когда первой когорте исполнится два.u   когорты_подписьu¯  Просмотры считает свой счётчик портала с 04.09.2026: до 11.09 их собирала служба портала, после переезда на WordPress она перестала работать, и с 11.09 счёт идёт разбором логов nginx. Столбцы - недели жизни статьи, а не календарь: отсчёт от дня выхода каждой статьи. Неполная неделя в счёт не идёт, поэтому у свежей когорты столбцов меньше. Судить по первым неделям рано - они уходят на индексацию.u   когорты_оговоркаuC   Пока не вышла ни одна статья портала.F)Úensure_asciiÚindentu   когорт собрано: rB   NrH   rM   z  rJ   Ú34u    статей rK   Ú2u     просмотров z>4z  (u   /ст.))r|   ô   ДАННЫЕrN   rO   rQ   ÚmaxÚrangeÚ
write_textÚdumpsÚprintr-   )	ô   когортыô   файлô
   отчётr~   ô   недельr&   r€   rx   ô   на_статьюs	            r   ô   главнаяr’   ³   sx  € Ü#Ó%€NÜ˜mÕ+€HÜ—’˜H×.Ñ.¸Ð.Ó@ÓA€JØ
�UÕ
€CßØ .ÐÑØ+-ˆÐ'Ñ(ÜÑWÉÓWÐabÔcˆÜTYÐZfÔTgÓ-hÑTgÈb°aµ°Ð8HÓ.IÑTgÑ-hˆÐ)Ñ*ð+ð 	Ð+Ñ,ðDð 	Ð-Ò.ð ,qˆÐ'Ñ(Ø×ÑœŸ
š
 :¸EÈ!ÔLÐW^ÐÔ_Ü	Ð)¬#¨nÓ*=Ð)>Ð
?Ô@ó
 ˆØ˜|Õ,Ò4‘S¸"¸\Õ:Jˆ
Ø#%Ð&9Õ#:Ò#B™CÈÐK^ÕH_ÐÜ��2Ð&Õ'¨Ð+¨>¸"¸^Õ:LÈQÐ9OÐOfÐgqÐrtÐfuØÐ%Ð& gð/ö 	0ó ùò/ .is   Á9E)u   январяu   февраляu
   мартаu   апреляu   маяu   июняu   июляu   августаu   сентябряu   октябряu   ноябряu   декабря)é&   )é   )Ú__doc__rN   r   Úsysr   r   r   Úpathlibr   Ú__file__ÚresolveÚparentô   КОРЕНЬr‡   rP   rU   ÚpathÚinsertrW   ô   просмотрыrR   rd   r   r'   r3   r:   r|   r’   rD   r   r   Ú<module>rŸ      sÈ   ðñó2 Û 	Û 
ß .Ñ .Ý á�H‹~×%Ñ%Ó'×.Ñ.×5Ñ5×<Ñ<€Ø˜nÕ,¨~Õ=€Ø˜lÕ*Ð-OÕO€Ø! JÕ.°Õ?ÐB[Õ[Ð Ø ‡�‡��‘3�| jÕ0Ó1Ô 2Û %ðp€òò(ô6
?ôZòKò\$0ñN Ö r   