§
   n+JYJîEvã                   ó\   — d Z ddlZddlZdZdZd\  ZZZd\  ZZ	Z
dZdZd	Zd
„ Zdd„Zdd„ZdS )u"  Taste signals from the addon library (docs/plan/pro-tebe/010 Â§2).

`seeds(...)` is pure (unit-tested with plain dicts); `load()` reads library.db. A seed is a title the household
showed interest in, with a weight (negative = dislike) and the kind of interest, which picks the reason text.
é    Ni€Q éð   )g       @çš™™™™™ù?g       À)ç      ð?gš™™™™™á?ç¸…ëQ¸¾?i„  g333333Ó?g      Ð?c                 ó†   — | sdS t          d|| z
  t          z  ¦  «        }ddt          j        d|t          z  ¦  «        z  z   S )Ng333333ã?g        gffffffÖ?gÍÌÌÌÌÌä?g      à?)ÚmaxÚDAYÚmathÚpowÚHALF_LIFE_DAYS)ÚatÚnowÚdayss      ú`/Users/chudy/Library/Application Support/Kodi/addons/plugin.video.milionar/wcs/foryou/signals.pyÚ_decayr      sH   € Øð ØˆsÝˆs�S˜2‘X¥Ñ$Ñ%Ô%€DØ�$�œ # t­nÑ'<Ñ=Ô=Ñ=Ñ=Ð=ó    c           
      ó	  ‡— |pt          j         ¦   «         }|pi }i Št          ¦   «         }ˆfd„}|                      ¦   «         D ]’\  \  }	}
}|                     d¦  «        s|                     d¦  «        r$|                     |	t          |
¦  «        f¦  «         |                     d¦  «        r' ||	|
t          d|                     d¦  «        ¦  «         Œ“|                     ¦   «         D �]·\  }
}|                     d¦  «        }t          |                     d¦  «        pd¦  «        dk    rh |d	|
t          t          ||¦  «        z  t          |d         ¦  «        d
k    rdndz  d|¦  «         |                     d	t          |
¦  «        f¦  «         Œ«|                     d	t          |
¦  «        ft          |                     d¦  «        pd¦  «        ¦  «        t          k    rK |d	|
t          t          ||¦  «        z  d|¦  «         |                     d	t          |
¦  «        f¦  «         �ŒFt          |                     d¦  «        pd¦  «        dk    rI |d	|
t          t          ||¦  «        z  d|¦  «         |                     d	t          |
¦  «        f¦  «         �Œ¹|                     ¦   «         D ]·\  }\  }}}|rat          ddd|z  z   d|z  z   ¦  «        t          ||¦  «        z  } |d||d|¦  «         |                     dt          |¦  «        f¦  «         Œl|rI |d|t          t          ||¦  «        z  d|¦  «         |                     dt          |¦  «        f¦  «         Œ¸|                     ¦   «         D ]-\  \  }	}
} ||	|
t          t          ||¦  «        z  d|¦  «         Œ.|                     ¦   «         D ]˜\  \  }	}
\  }}|	t          |
¦  «        f}|dk    r,|                     |¦  «         ‰                     |d¦  «         ŒN|                     |¦  «         t           t"          t$          dœ|         }|	t          |
¦  «        |||pddœ‰|<   Œ™t'          ‰                     ¦   «         d„ ¬¦  «        }||fS )a^  Weighted seeds and the titles never to recommend.

    titles          {(media, id): {'in_list', 'last_activity_at'}}
    movie_states    {id: {'playcount', 'resume_pos', 'last_played_at'}}
    episode_counts  {show_id: (watched_episodes, started_episodes, last_played_at)}
    short_plays     {(media, id): last_started_at} plays that ended under the resume threshold
    feedback        {(media, id): (value, at)} like / dislike / hide / pick
    watched_seconds {(media, id): seconds really played} from the play log; a resume point alone can come from a
                    seek, so a film counts as seen by what was played (titles without a log keep their resume point)

    Returns (seeds, exclude): seeds = [{'media', 'id', 'weight', 'kind', 'at'}] sorted by weight,
    exclude = {(media, id)} (watched, in progress, in the lists, disliked, hidden).
    c                 óÜ   •— | t          |¦  «        f}‰                     |¦  «        }|�&t          |¦  «        t          |d         ¦  «        k    r| t          |¦  «        |||pddœ‰|<   d S d S )NÚweightr   ©ÚmediaÚidr   Úkindr   )ÚintÚgetÚabs)r   Útmdb_idr   r   r   ÚkÚoldÚfounds          €r   Úaddzseeds.<locals>.add-   st   ø€ Ø•C˜‘L”LÐ!ˆØ�iŠi˜‰lŒlˆØˆ;�#˜f™+œ+­¨C°¬MÑ(:Ô(:Ò:Ð:Ø!&­c°'©l¬lÀfÐVZÐbdÐbiÐhiÐjÐjˆE�!‰HˆHˆHð ;Ð:r   Úin_listÚlast_activity_atÚlistÚlist_added_atÚlast_played_atÚ	playcountr   Úmovieé   gffffffò?r   ÚwatchedÚ
resume_posÚstartedr   gÍÌÌÌÌÌÜ?r   gš™™™™™©?ÚtvÚtriedÚhideN)ÚlikeÚpickÚdisliker   c                 ó4   — | d          | d          | d         fS )Nr   r   r   © )Úss    r   ú<lambda>zseeds.<locals>.<lambda>W   s   € °A°h´K°<À!ÀDÄ'ÀÈ1ÈTÌ7Ð2S€ r   )Úkey)ÚtimeÚsetÚitemsr   r!   r   ÚW_LISTÚW_MOVIE_WATCHEDr   ÚfloatÚWATCHED_SECONDSÚW_MOVIE_STARTEDÚ	W_STARTEDÚminÚW_SHORTÚpopÚW_LIKEÚW_PICKÚ	W_DISLIKEÚsortedÚvalues)ÚtitlesÚmovie_statesÚepisode_countsÚshort_playsÚfeedbackr   Úwatched_secondsÚexcluder!   r   r   ÚrowÚstr   Úshow_idr*   r,   r   Úvaluer   Úresultr    s                        @r   ÚseedsrU      s¬  ø€ ð Ð
•”‘”€CØ%Ð+¨€OØ€EÝ‰eŒe€Gðkð kð kð kð kð "(§¢¡¤ð Jð JÑÑˆ�˜#Ø�7Š7�9ÑÔð 	/ §¢Ð);Ñ!<Ô!<ð 	/Ø�KŠK˜¥ G¡¤Ð-Ñ.Ô.Ð.Ø�7Š7�9ÑÔð 	JØˆC��w¥¨°·²¸Ñ0HÔ0HÑIÔIÐIøØ#×)Ò)Ñ+Ô+ð 1ñ 1‰ˆ�Ø�VŠVÐ$Ñ%Ô%ˆÝˆr�vŠv�kÑ"Ô"Ð' aÑ(Ô(¨1Ò,Ð,ØˆC�˜¥/µF¸2¸s±O´OÑ"CÍsÐSUÐVaÔSbÑOcÔOcÐfgÒOgÐOgÀtÀtÐmpÑ"qØ˜2ñô ð à�KŠK˜¥# g¡,¤,Ð/Ñ0Ô0Ð0Ð0Ø× Ò  '­3¨w©<¬<Ð!8½%ÀÇÂÀ|Ñ@TÔ@TÐ@YÐXYÑ:ZÔ:ZÑ[Ô[Õ_nÒnÐnØˆC�˜¥/µF¸2¸s±O´OÑ"CÀYÐPRÑSÔSÐSØ�KŠK˜¥# g¡,¤,Ð/Ñ0Ô0Ð0Ñ0Ý�2—6’6˜,Ñ'Ô'Ð,¨1Ñ-Ô-°Ò1Ð1ØˆC�˜¥)­f°R¸©o¬oÑ"=¸yÈ"ÑMÔMÐMØ�KŠK˜¥# g¡,¤,Ð/Ñ0Ô0Ð0ùØ+9×+?Ò+?Ñ+AÔ+Að .ð .Ñ'ˆÑ'�'˜7 BØð 	.Ý˜˜d T¨G¡^Ñ3°d¸W±nÑDÑEÔEÍÈrÐSVÉÌÑWˆFØˆC��g˜v y°"Ñ5Ô5Ð5Ø�KŠK˜�s 7™|œ|Ð,Ñ-Ô-Ð-Ð-Øð 	.ØˆC��g�y­6°"°c©?¬?Ñ:¸IÀrÑJÔJÐJØ�KŠK˜�s 7™|œ|Ð,Ñ-Ô-Ð-øØ +× 1Ò 1Ñ 3Ô 3ð Dð DÑÑˆ�˜"ØˆˆE�7�G¥f¨R°¡o¤oÑ5°wÀÑCÔCÐCÐCØ)1¯ªÑ)9Ô)9ð hð hÑ%Ñˆ�™+˜5 "Ø•C˜‘L”LÐ!ˆØ�FŠ?ˆ?Ø�KŠK˜‰NŒNˆNØ�IŠI�a˜ÑÔÐØØ�Š�A‰ŒˆÝ ­&½YÐGÐGÈÔNˆØ"­#¨g©,¬,À&ÐRWÐ_aÐ_fÐefÐgÐgˆˆa‰ˆÝ�E—L’L‘N”NÐ(SÐ(SÐTÑTÔT€FØ�7ˆ?Ðr   c           	      óú  — ddl m} |                     ¦   «         }	 d„ |                     d¦  «        D ¦   «         }d„ |                     d¦  «        D ¦   «         }i }|                     d¦  «        D ]@}t	          |d         pd¦  «        t	          |d	         pd¦  «        |d
         f||d         <   ŒAi }|                     d¦  «        D ]}|d
         ||d         |d         f<   Œi }|                     d¦  «        D ]*}t          |d	         pd¦  «        ||d         |d         f<   Œ+	 |                     ¦   «          n# |                     ¦   «          w xY wt          |||||                     ¦   «         | |¦  «        S )zseeds(...) over library.db.r   )Ústorec                 óJ   — i | ] }|d          |d         ft          |¦  «        “Œ!S )Ú
media_typer   ©Údict©Ú.0Úrs     r   ú
<dictcomp>zload.<locals>.<dictcomp>`   s-   € ÐiÐiÐi¸q�1�\”? A i¤LÐ1µ4¸±7´7ÐiÐiÐir   zSELECT * FROM titlesc                 ó:   — i | ]}|d          t          |¦  «        “ŒS )r   rZ   r\   s     r   r_   zload.<locals>.<dictcomp>a   s$   € ÐaÐaÐa°!˜˜)œ¥d¨1¡g¤gÐaÐaÐar   zSELECT * FROM movie_statez‰SELECT show_id, SUM(playcount > 0) w, SUM(playcount = 0 AND resume_pos > 0) s, MAX(last_played_at) at FROM episode_state GROUP BY show_idÚwr5   r   rR   zoSELECT media_type, tmdb_id, MAX(started_at) at FROM play_log WHERE outcome='short' GROUP BY media_type, tmdb_idrY   r   z�SELECT media_type, tmdb_id, SUM(MIN(COALESCE(position, 0), MAX(0, COALESCE(ended_at, started_at) - started_at))) s FROM play_log GROUP BY media_type, tmdb_id)	Úwcs.library2rW   ÚconnectÚexecuter   r=   ÚcloserU   Úget_feedback)	r   rW   ÚconnrI   rJ   Úepisodesr^   ÚshortÚplayeds	            r   Úloadrk   [   s¸  € à"Ð"Ð"Ð"Ð"Ð"Ø�=Š=‰?Œ?€DðØiÐiÀDÇLÂLÐQgÑDhÔDhÐiÑiÔiˆØaÐa°t·|²|ÐD_Ñ7`Ô7`ÐaÑaÔaˆØˆØ—’ð [ñ \ô \ð 	Sð 	SˆAå&)¨!¨C¬&¨+°AÑ&6Ô&6½¸A¸c¼F¸KÀaÑ8HÔ8HÈ!ÈDÌ'Ð%RˆH�Q�y”\Ñ"Ð"ØˆØ—’ð =ñ >ô >ð 	=ð 	=ˆAà56°t´WˆE�1�\”? A i¤LÐ1Ñ2Ð2àˆØ—’ð =ñ >ô >ð 	Ið 	IˆAõ 7<¸A¸c¼F¸KÀaÑ6HÔ6HˆF�A�l”O Q y¤\Ð2Ñ3Ð3ð	Ið
 	�
Š
‰Œˆˆøˆ�
Š
‰ŒˆˆøøøÝ�˜ x°¸×8JÒ8JÑ8LÔ8LÈcÐSYÑZÔZÐZs   œDD= Ä=E)NN)N)Ú__doc__r
   r8   r	   r   rD   rE   rF   r<   r?   rB   r>   r@   r;   r   rU   rk   r4   r   r   ú<module>rm      sœ   ððð ð
 €€€Ø €€€à€Ø€Ø*Ñ €ˆ�	Ø,;Ñ )€� 'Ø€Ø€	Ø	€ð>ð >ð >ð>ð >ð >ð >ðB[ð [ð [ð [ð [ð [r   