§
   \�­n4õ¨ßã                   ó¾   — d Z ddlZddlZddlZddlmZ ddlZdZdZdZdZ	dZ
 ej        ¦   «         Zej        fd	„Zd
„ Zd„ Zd„ Zd„ Zdd„Zdd„ZdZd„ Zdd„Zdd„ZdS )uÉ  Pro tebe in the service: when to rebuild the snapshot, and the manual rebuild (docs/plan/pro-tebe/030 Â§2).

A rebuild runs when there is no snapshot, the day or the time-of-day slot changed, it is older than REBUILD_AFTER, or
the household's signals changed (a play ended, feedback) and the last build is at least SIGNAL_GAP old. One build at a
time (a lock file), rows are told through the row revisions (wcs/skin/refresh.py), never by touching controls.
é    N)Údatetimeé-   i,  i`T  i°  i„  c                 óV   — t          j        d                     | ¦  «        |¦  «         d S )Nu   [MilionÃ¡Å™ ProTebe] {})ÚxbmcÚlogÚformat)ÚmessageÚlevels     ú`/Users/chudy/Library/Application Support/Kodi/addons/plugin.video.milionar/wcs/foryou/service.pyÚ_logr      s)   € Ý„HÐ&×-Ò-¨gÑ6Ô6¸Ñ>Ô>Ð>Ð>Ð>ó    c                  ó¬   — ddl m}  t          j                             t          j                             |                      ¦   «         ¦  «        d¦  «        S )Nr   ©Ústorezforyou.lock)Úwcs.library2r   ÚosÚpathÚjoinÚdirnameÚdb_pathr   s    r   Ú
_lock_pathr      s@   € Ø"Ð"Ð"Ð"Ð"Ð"ÝŒ7�<Š<�œŸš¨¯ª©¬Ñ8Ô8¸-ÑHÔHÐHr   c                  óH  — t          ¦   «         } 	 t          j                             | ¦  «        rPt	          j        ¦   «         t          j                             | ¦  «        z
  t          k    rt          j        | ¦  «         t          j        | t          j	        t          j
        z  t          j        z  ¦  «        }t          j        |t          t          j        ¦   «         ¦  «                             ¦   «         ¦  «         t          j        |¦  «         dS # t"          $ r Y dS w xY w)zBCross-process lock (service and a manual rebuild from the plugin).TF)r   r   r   ÚexistsÚtimeÚgetmtimeÚ
LOCK_STALEÚremoveÚopenÚO_CREATÚO_EXCLÚO_WRONLYÚwriteÚstrÚgetpidÚencodeÚcloseÚOSError)r   Úfds     r   Ú_acquirer)       sÙ   € å‰<Œ<€DðÝŒ7�>Š>˜$ÑÔð 	¥D¤I¡K¤Kµ"´'×2BÒ2BÀ4Ñ2HÔ2HÑ$HÍ:Ò$UÐ$UÝŒI�d‰OŒOˆOÝŒW�T�2œ:­¬	Ñ1µB´KÑ?Ñ@Ô@ˆÝ
Œ�•S�œ™œÑ%Ô%×,Ò,Ñ.Ô.Ñ/Ô/Ð/Ý
Œ�‰ŒˆØˆtøÝð ð ð Øˆuˆuðøøøs   �DD Ä
D!Ä D!c                  ój   — 	 t          j        t          ¦   «         ¦  «         d S # t          $ r Y d S w xY w©N)r   r   r   r'   © r   r   Ú_releaser-   .   sC   € ðÝ
Œ	•*‘,”,ÑÔÐÐÐøÝð ð ð Øˆˆðøøøs   ‚ $ ¤
2±2c                  óì  — ddl m}  |                      ¦   «         }	 |                     d¦  «                             ¦   «         }|                     d¦  «                             ¦   «         }|                     d¦  «                             ¦   «         }|                     ¦   «          n# |                     ¦   «          w xY w dj        t          |¦  «        t          |¦  «        z   t          |¦  «        z   Ž S )zXChanges when the household's signals change: plays, finished plays, feedback, the lists.r   r   zBSELECT COUNT(*), MAX(COALESCE(ended_at, started_at)) FROM play_logz&SELECT COUNT(*), MAX(at) FROM feedbackz3SELECT SUM(in_list), MAX(list_added_at) FROM titlesz{}:{}|{}:{}|{}:{})r   r   ÚconnectÚexecuteÚfetchoner&   r   Útuple)r   ÚconnÚplaysÚfeedbackÚlistss        r   Úsignals_stampr7   5   sÎ   € à"Ð"Ð"Ð"Ð"Ð"Ø�=Š=‰?Œ?€DðØ—’ÐaÑbÔb×kÒkÑmÔmˆØ—<’<Ð HÑIÔI×RÒRÑTÔTˆØ—’ÐRÑSÔS×\Ò\Ñ^Ô^ˆà�
Š
‰Œˆˆøˆ�
Š
‰ŒˆˆøøøØ%ÐÔ%­¨e©¬µu¸X±´Ñ(FÍÈuÉÌÑ(UÐWÐWs   œA5B& Â&B<Ú c           
      ó  — ddl m}m} t                               d¦  «        sdS 	 t          ¦   «         s+t          d¦  «         	 t                               ¦   «          dS 	 t          j        ¦   «         }t          ¦   «         }	 | 
                    t          ¬¦  «        }nl# |j        $ r_}t          d                     |¦  «        t          j        ¦  «         Y d}~t          ¦   «          t                               ¦   «          dS d}~ww xY w||d<   |                     |¦  «         dd	lm} |                     |j        ¦  «         t          d
                     | pdt+          |d         ¦  «        t+          |d         d         ¦  «        t          j        ¦   «         |z
  |d         d         ¦  «        ¦  «         |t          ¦   «          t                               ¦   «          S # t          ¦   «          w xY w# t,          $ rd}t          d                     t/          |¦  «        j        |¦  «        t          j        ¦  «         Y d}~t                               ¦   «          dS d}~ww xY w# t                               ¦   «          w xY w)zbBuild and store a new snapshot, then tell the rows. Returns the snapshot, or None (busy / failed).r   )ÚengineÚwidgetsFNz)rebuild skipped: another build is running)r   z!rebuild kept the old snapshot: {}Úsignals)Úrefreshz:snapshot built ({}): {} titles, {} rows, {:.1f} s, TMDb {}ÚmanualÚitemsÚmodesÚallÚstatsÚtmdbzrebuild failed: {}: {})Ú
wcs.foryour:   r;   Ú_lockÚacquirer)   r   Úreleaser   r7   ÚbuildÚ	NotEnoughr   r   Ú
LOGWARNINGr-   ÚsaveÚwcs.skinr=   ÚchangedÚALL_ROWSÚlenÚ	ExceptionÚtypeÚ__name__ÚLOGERROR)Úreasonr:   r;   ÚstartedÚstampÚsnapshotÚexcr=   s           r   Ú	build_nowrY   B   se  € à*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ý�=Š=˜ÑÔð ØˆtðÝ‰zŒzð 	ÝÐ<Ñ=Ô=Ð=Øõ. 	�Š‰Œˆˆˆð-	Ý”i‘k”kˆGÝ!‘O”OˆEðØ!Ÿ<š<­D˜<Ñ1Ô1��øØÔ#ð ð ð ÝÐ8×?Ò?ÀÑDÔDÅdÄoÑVÔVÐVØ�t�t�tõ ‰JŒJˆJõ
 	�Š‰Œˆˆˆøøøøð#øøøð #(ˆH�YÑØ�KŠK˜Ñ!Ô!Ð!Ø(Ð(Ð(Ð(Ð(Ð(Ø�OŠO˜GÔ,Ñ-Ô-Ð-ÝÐM×TÒTØÐ"˜(¥C¨°Ô(9Ñ$:Ô$:½CÀÈÔ@QÐRWÔ@XÑ<YÔ<YÕ[_Ô[dÑ[fÔ[fÐipÑ[pØ˜Ô! &Ô)ñ+ô +ñ ,ô ,ð ,ð å‰JŒJˆJõ
 	�Š‰Œˆˆøõ ‰JŒJˆJˆJøøøøÝð ð ð ÝÐ%×,Ò,­T°#©Y¬YÔ-?ÀÑEÔEÅtÄ}ÑUÔUÐUØˆtˆtˆtå�Š‰Œˆˆˆøøøøð	øøøøõ 	�Š‰Œˆˆøøøss   ¦G4 Á !G! ÂB ÂG! Â
DÂ(-DÃG! ÃG4 ÄDÄB2G! Æ9G4 Ç!G1Ç1G4 Ç4
I"Ç>A IÈ>I% ÉI"É"I% É%J c                 ó  — ddl m} |pt          j        ¦   «         }| sdS |t          |                      d¦  «        pd¦  «        z
  }t          j        |¦  «        }|                      d¦  «        |                     ¦   «                              ¦   «         k    rdS |                      d¦  «        | 	                    |j
        ¦  «        k    rdS |t          k    rd	S |t          k    r'|                      d
¦  «        t          ¦   «         k    rd
S dS )z)Why a rebuild is due ('' when it is not).r   )ÚcomposeÚmissingÚbuilt_atÚdayznew dayÚslotztime of dayÚager<   r8   )rD   r[   r   ÚintÚgetr   ÚfromtimestampÚdateÚ	isoformatÚslot_ofÚhourÚREBUILD_AFTERÚ
SIGNAL_GAPr7   )rW   Únowr[   r`   Úmoments        r   Úduerl   d   sý   € à"Ð"Ð"Ð"Ð"Ð"Ø
Ð
•”‘”€CØð ØˆyØ
•�H—L’L Ñ,Ô,Ð1°Ñ2Ô2Ñ
2€CÝÔ# CÑ(Ô(€FØ‡|‚|�EÑÔ˜fŸkšk™mœm×5Ò5Ñ7Ô7Ò7Ð7ØˆyØ‡|‚|�FÑÔ˜wŸš¨v¬{Ñ;Ô;Ò;Ð;Øˆ}Ø
�mÒÐØˆuØ
�jÒÐ˜XŸ\š\¨)Ñ4Ô4½¹¼ÒGÐGØˆyØˆ2r   éx   c                  ó´   — t          j        d¦  «        rdS t          j        d¦  «        } | o,t          j        d                     t          ¦  «        ¦  «         S )z¼Not now: a video is playing (no network next to the stream), or the user is moving around Pro tebe (the rows
    must not reshuffle under the cursor). The rebuild waits for the next check.zPlayer.HasVideoTzXWindow.IsActive(home) + String.IsEqual(Container(9000).ListItem.Property(id),mil_foryou)zSystem.IdleTime({}))r   ÚgetCondVisibilityr   ÚIDLE_BEFORE_REBUILD)Úbrowsings    r   Úbusyrr   z   s]   € õ ÔÐ/Ñ0Ô0ð ØˆtÝÔ%ð '4ñ 5ô 5€HàÐe�DÔ2Ð3H×3OÒ3OÕPcÑ3dÔ3dÑeÔeÐeÐer   c                 ó¬  — ddl m} ddlm} |                     ¦   «          | pt          j        ¦   «         } |                      t          ¦  «        rdS |  	                    ¦   «         sî	 ddlm
} |                     d¦  «        rdn t          |                     ¦   «         ¦  «        }|r#|dk    st          ¦   «         st          |¦  «         nW# t           $ rJ}t#          d                     t'          |¦  «        j        |¦  «        t
          j        ¦  «         Y d}~nd}~ww xY w|                      t,          ¦  «        rdS |  	                    ¦   «         ¯ìdS dS )	zService thread.r   )r:   )Ú	userfirstN)ÚwarmÚforyour\   zcheck failed: {}: {})rD   r:   rL   rt   Úbackground_threadr   ÚMonitorÚwaitForAbortÚFIRST_DELAYÚabortRequestedru   Úhiddenrl   Úloadrr   rY   rP   r   r   rQ   rR   rJ   ÚCHECK_EVERY)Úmonitorr:   rt   ru   rT   rX   s         r   Úrunr€   „   s†  € à!Ð!Ð!Ð!Ð!Ð!Ø"Ð"Ð"Ð"Ð"Ð"Ø×ÒÑ!Ô!Ð!ØÐ'�œ™œ€GØ×Ò�KÑ(Ô(ð ØˆØ×$Ò$Ñ&Ô&ð 	ð	ZØ%Ð%Ð%Ð%Ð%Ð%Ø!Ÿ[š[¨Ñ2Ô2ÐJ�T�T½¸F¿KºK¹M¼MÑ8JÔ8JˆFØð "˜6 YÒ.Ð.µd±f´fÐ.Ý˜&Ñ!Ô!Ð!øøÝð 	Zð 	Zð 	ZÝÐ'×.Ò.­t°C©y¬yÔ/AÀ3ÑGÔGÍÌÑYÔYÐYÐYÐYÐYÐYÐYøøøøð	Zøøøà×Ò¥Ñ,Ô,ð 	ØˆFð ×$Ò$Ñ&Ô&ð 	ð 	ð 	ð 	ð 	s   Á'A#C Ã
DÃA DÄDc                 óÆ   ‡‡‡‡— ddl }ddlŠddlmŠmŠ |                     d¦  «        Šˆˆˆˆfd„} |dd¦  «         t          d¦  «        } ||rd	nd
|rdnd¦  «         dS )zÇPlugin action `foryou_build`: rebuild now (the empty-state button). A first build with the Webshare check
    takes a while, so it only tells the user; the rows refresh by themselves when it is done.r   N)Ú	S_SECTIONÚ_textzplugin.video.milionarc                 ó¤   •— ‰                      ¦   «                               ‰‰¦  «        ‰                     | ¦  «        p|‰j        dd¦  «         d S )Ni   F)ÚDialogÚnotificationÚgetLocalizedStringÚNOTIFICATION_INFO)Ú	string_idÚfallbackr‚   rƒ   ÚaddonÚxbmcguis     €€€€r   Únotezmanual.<locals>.note    sa   ø€ Ø�ŠÑÔ×%Ò% e e¨IÑ&6Ô&6¸×8PÒ8PÐQZÑ8[Ô8[Ð8gÐ_gØ&-Ô&?ÀÀuñ	Nô 	Nð 	Nð 	Nð 	Nr   i Š  u   PÅ™ipravuji doporuÄ�enÃ­â€¦r>   iŠ  iŠ  u   DoporuÄ�enÃ­ jsou pÅ™ipravenÃ¡u+   DoporuÄ�enÃ­ se teÄ� nepodaÅ™ilo pÅ™ipravit)Ú	xbmcaddonrŒ   Úwcs.foryou.widgetsr‚   rƒ   ÚAddonrY   )ÚparamsrŽ   r�   rW   r‚   rƒ   r‹   rŒ   s       @@@@r   r>   r>   ˜   sÜ   øøøø€ ð ÐÐÐØ€N€N€NØ3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ø�OŠOÐ3Ñ4Ô4€EðNð Nð Nð Nð Nð Nð Nð Nð 	€DˆÐ-Ñ.Ô.Ð.Ý˜Ñ"Ô"€HØ€D�(Ð	%ˆˆ È8ð  (GÐ'GÐ'Gð  ZGñ  Hô  Hð  Hð  Hð  Hr   )r8   r+   )Ú__doc__r   Ú	threadingr   r   r   rz   r~   rh   ri   r   ÚLockrE   ÚLOGINFOr   r   r)   r-   r7   rY   rl   rp   rr   r€   r>   r,   r   r   ú<module>r–      sJ  ððð ð 
€	€	€	Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð à €€€à€Ø€Ø€Ø€
Ø€
Øˆ	ŒÑÔ€ð œð ?ð ?ð ?ð ?ðIð Ið Ið
ð ð ðð ð ð
Xð 
Xð 
Xðð ð ð ðDð ð ð ð& Ð ðfð fð fðð ð ð ð(Hð Hð Hð Hð Hð Hr   