§
    Ù�jv~ ã                   óØ  — U d dl mZmZmZmZmZmZmZmZm	Z	 d dl
mZ d dlmZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZ d dlmZ d	d
lm Z  d	dl!m"Z" d	dl#m$Z$ d	dl%m&Z& d	dl'm(Z(m)Z)m*Z*m+Z+ d	dl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 d	dl5m6Z6 d	dl7m8Z8 d	dl9m:Z: d	dl;m<Z< d dl=Z=d dl>Z>d dl?Z?d dl@m@Z@mAZA d	dlBmBZB  eddg¬¦  «        ZCi ZDeEeFeEf         eGd<    ejH        ¦   «         ZIdedeFfd„ZJde	dedee         fd„ZKde"deEfd „ZLd!eFdeFfd"„ZMdeNfd#„ZOdeNfd$„ZPeC Q                    d%ee*         ¬&¦  «        d d' ee ¦  «         ee1¦  «        fd(eRd)eRd*ed+ee$         fd,„¦   «         ZSeC Q                    d-¦  «        d. ee ¦  «         ee1¦  «        fde	d)eRd*ed+ee$         fd/„¦   «         ZTeC Q                    d0¦  «        d. ee ¦  «         ee1¦  «        fde	d)eRd*ed+ee$         fd1„¦   «         ZUeC Q                    d2¦  «        d. ee ¦  «         ee1¦  «        fde	d)eRd*ed+ee$         fd3„¦   «         ZVeC Q                    d4ee*         ¬&¦  «        d d' ee ¦  «         ee.¦  «        fd(eRd)eRd*ed+e$fd5„¦   «         ZWeC Q                    d6ee*         ¬&¦  «        d7 ee ¦  «         ee1¦  «        fd8eFd)eRd*ed+ee$         fd9„¦   «         ZXeC Q                    d:e*¬&¦  «         ee ¦  «         ee1¦  «        fd;ed*ed+ee$         fd<„¦   «         ZYeC Z                    d=e*¬&¦  «         ee ¦  «         ee1¦  «        fd;ed*ed+ee$         fd>„¦   «         Z[eC Z                    d%e*ej\        ¬?¦  «         ee ¦  «         e e3d@¦  «        ¦  «        fdAe(d*ed+e$fdB„¦   «         Z]eC ^                    d:e*¬&¦  «         ee ¦  «         e e4dCdDg¦  «        ¦  «        fd;edAe)d*ed+e$fdE„¦   «         Z_eC ^                    dFe*¬&¦  «         ee ¦  «         ee.¦  «        fd;edGeEd*ed+e$fdH„¦   «         Z`eC a                    d:ejb        ¬I¦  «         ee ¦  «         e e4dJdKg¦  «        ¦  «        dfd;ed*ed+e$dLefdM„¦   «         ZcdNeFd!eFdOeFd;eFfdP„ZdeC Z                    dQ¦  «         edR¦  «         ee ¦  «         e e3d@¦  «        ¦  «        fd;edSed*ed+e$fdT„¦   «         ZeeC Z                    dUe*ej\        ¬?¦  «        dddVdV ee ¦  «         e e3d@¦  «        ¦  «        fdWeFdXeeF         dYeeF         dZeNd[eNd*ed+e$fd\„¦   «         Zf G d]„ d^e¦  «        ZgeC Z                    d_e*¬&¦  «         ee ¦  «         ee-¦  «        fd;edegd*ed+e$fd`„¦   «         ZheC Z                    dae*¬&¦  «         edR¦  «         ee ¦  «         ee-¦  «        fd;edbed*ed+e$fdc„¦   «         ZieC Q                    dd¦  «         ee ¦  «        fd;ed*efde„¦   «         ZjeC Q                    df¦  «         ee ¦  «        fd;ed*efdg„¦   «         ZkeC Z                    dh¦  «        di ee ¦  «         ee0¦  «        fd;edjeNd*efdk„¦   «         ZleC Q                    dl¦  «         ee ¦  «        fd;eFdmeRd*efdn„¦   «         ZmeC Q                    do¦  «         ee ¦  «        fd;eFd*efdp„¦   «         ZneC Q                    dq¦  «         ee ¦  «         ee.¦  «        fd;ed*ed+e$fdr„¦   «         Zod;eFdseFfdt„ZpeC Z                    du¦  «        di ee ¦  «         ee/¦  «        fd;ede	djeNd*ed+e$f
dv„¦   «         ZqeC Z                    dw¦  «         ee ¦  «         ee/¦  «        fd;ede	d*ed+e$fdx„¦   «         ZreC Z                    dy¦  «         edR¦  «         ee ¦  «         ee/¦  «        fd;edSed*ed+e$fdz„¦   «         ZseC Z                    d{e*¬&¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         edi¦  «         ed¦  «         ee ¦  «         e e3d@¦  «        ¦  «        fdXeeF         dYeeF         d!eeF         d|eet         d}eNdbee         d*ed+e$fd~„¦   «         ZudS )é    )	Ú	APIRouterÚDependsÚHTTPExceptionÚstatusÚ
UploadFileÚFileÚBackgroundTasksÚFormÚRequest)ÚResponse)Ú	BaseModelN)ÚOAuth2PasswordBearer)ÚSession)ÚListÚOptional)ÚUUIDé   )Úget_db)ÚStream)ÚUser)ÚProcessingJob)ÚStreamCreateÚStreamUpdateÚStreamResponseÚStreamManualCreate)Úget_current_active_userÚget_current_admin_userÚget_current_creator_userÚget_current_userÚget_current_user_optionalÚverify_passwordÚrequire_permissionÚrequire_any_permission©Úsettings©ÚTwitchService)ÚChatService)ÚChatJsonService)ÚdatetimeÚtimezone)Úredis_clientz/api/streamsÚstreams)ÚprefixÚtagsÚthumbnail_progressÚdataÚreturnc                 ó²   — t          j        d„ | D ¦   «         d¬¦  «        }t          j        |                     ¦   «         ¦  «                             ¦   «         S )z$Generate ETag hash from stream data.c                 óˆ   — g | ]?}t          |j        ¦  «        |j        r|j                             ¦   «         nd |j        dœ‘Œ@S )N)ÚidÚ
updated_atr   )Ústrr5   r6   Ú	isoformatr   ©Ú.0Úss     ú/app/app/api/streams.pyú
<listcomp>z!generate_etag.<locals>.<listcomp>*   s^   € ð ð ð ð õ �!”$‰iŒiØ23´,ÐH�a”l×,Ò,Ñ.Ô.Ð.ÀDØ”(ðð ð ð ð ó    T)Ú	sort_keys)ÚjsonÚdumpsÚhashlibÚmd5ÚencodeÚ	hexdigest)r1   Údata_strs     r<   Úgenerate_etagrG   (   sc   € åŒzð ð ð ð	ñ ô ð !%ð	&ñ &ô &€Hõ
 Œ;�x—’Ñ(Ô(Ñ)Ô)×3Ò3Ñ5Ô5Ð5r>   Úrequestc                 ó„   — t          |¦  «        }| j                             d¦  «        }||k    rt          d¬¦  «        S dS )z*Check ETag and return 304 if not modified.zif-none-matchi0  ©Ústatus_codeN)rG   ÚheadersÚgetr   )rH   r1   ÚetagÚif_none_matchs       r<   Ú
check_etagrP   2   sE   € å˜ÑÔ€DØ”O×'Ò'¨Ñ8Ô8€MØ˜ÒÐÝ CÐ(Ñ(Ô(Ð(Øˆ4r>   Ústreamc                 ó²  — i dt          | j        ¦  «        “d| j        “d| j        “d| j        “d| j        rt          | j        ¦  «        nd“d| j        r| j                             ¦   «         nd“d| j        r| j                             ¦   «         nd“d	| j	        “d
| j
        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “| j        r| j                             ¦   «         nd| j        | j        | j        | j        | j        | j        | j        | j        r| j                             ¦   «         nd| j        dœ
¥S )z9Convert SQLAlchemy Stream to dict for JSON serialization.r5   ÚtitleÚdescriptionr   Ú
created_byNÚ
created_atr6   Úduration_secondsÚthumbnail_urlÚhls_pathÚhls_urlÚhls_availableÚthumbnails_availableÚ	dash_pathÚ	file_pathÚ
view_countÚ	is_public)
Ústream_dateÚtwitch_vod_idÚstreamerÚstream_metadataÚthumbnail_progress_generatedÚthumbnail_progress_totalÚthumbnail_progress_messageÚthumbnail_progress_errorÚthumbnail_progress_updated_atÚstream_number)r7   r5   rS   rT   r   rU   rV   r8   r6   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   )rQ   s    r<   Ústream_to_responserk   ;   sÛ  € ðØ�c�&”)‰nŒnðà�”ðð 	�vÔ)ðð 	�&”-ð	ð
 	°Ô0AÐK•c˜&Ô+Ñ,Ô,Ð,Àtðð 	°vÔ7HÐR�fÔ'×1Ò1Ñ3Ô3Ð3Èdðð 	°vÔ7HÐR�fÔ'×1Ò1Ñ3Ô3Ð3Èdðð 	˜FÔ3ðð 	˜Ô-ðð 	�F”Oðð 	�6”>ðð 	˜Ô-ðð 	 Ô ;ðð 	�VÔ%ðð 	�VÔ%ðð  	�fÔ'ð!ð" 	�VÔ%ð#ð$ :@Ô9KÐU�vÔ)×3Ò3Ñ5Ô5Ð5ÐQUØÔ-Ø”OØ!Ô1Ø(.Ô(KØ$*Ô$CØ&,Ô&GØ$*Ô$CØ]cô  ^Bð  *L¨Ô)M×)WÒ)WÑ)YÔ)YÐ)Yð  HLØÔ-ð7ð ð ð r>   rY   c                 ó  — | sdS |                       t          j        d¦  «        }|                     d¦  «        s|                     d¦  «        › d�}|                     d¦  «        st          j        rdt          j        › |› �n|}|S )z´Build consistent HLS URL from path.

    Handles both directory paths (appends /index.m3u8) and direct .m3u8 files.
    Converts to absolute HTTPS URL if DOMAIN is configured.
    Nz/hlsú.m3u8ú/z/index.m3u8Úhttpúhttps://)Úreplacer%   ÚFFMPEG_CACHE_PATHÚendswithÚrstripÚ
startswithÚDOMAIN)rY   Úurl_paths     r<   Ú_build_hls_urlrx   \   s�   € ð ð Øˆtð ×Ò¥Ô :¸FÑCÔC€Hð ×Ò˜WÑ%Ô%ð 8Ø—o’o cÑ*Ô*Ð7Ð7Ð7ˆð ×Ò˜vÑ&Ô&ð [Ý=E¼_ÐZÐ9�hœoÐ9¨xÐ9Ð9Ð9ÐRZˆà€Or>   c                 ó2  — | j         sdS | j        dvrdS | j         }|                     d¦  «        r|                     dd¦  «        }n8|                     d¦  «        r#|                     dt          j        dz   ¦  «        }t          j                             |¦  «        rBt          j         	                    |d¦  «        }t          j         
                    |¦  «        rdS n6|                     d	¦  «        r!t          j         
                    |¦  «        rdS dS )
z0Check if HLS playlist is available for playback.F)ÚreadyÚ
segmentingÚresegmentingz	/uploads/z/app/uploads/z/hls/rn   z
index.m3u8Trm   )rY   r   ru   rq   r%   rr   ÚosÚpathÚisdirÚjoinÚexistsrs   )rQ   rY   Ú	m3u8_paths      r<   Ú_is_hls_availablerƒ   s   s  € àŒ?ð Øˆuà„}ÐCÐCÐCØˆuð Œ€Hà×Ò˜;Ñ'Ô'ð OØ×#Ò# K°ÑAÔAˆˆØ	×	Ò	˜WÑ	%Ô	%ð OØ×#Ò# G­XÔ-GÈ#Ñ-MÑNÔNˆõ 
„w‡}‚}�XÑÔð å”G—L’L ¨<Ñ8Ô8ˆ	ÝŒ7�>Š>˜)Ñ$Ô$ð 	Ø�4ð	ð 
×	Ò	˜7Ñ	#Ô	#ð ­¬¯ª°xÑ(@Ô(@ð Øˆtàˆ5r>   c                 óŽ  — | j         sdS t          j                             t          j        dt          | j         ¦  «        ¦  «        }t          j                             t          j                             |d¦  «        ¦  «        rdS t          j                             t          j                             |d¦  «        ¦  «        rdS dS )z[Check if thumbnail sprite(s) are available (legacy single sprite or multi-sprite via JSON).FÚvideoszthumbnails_sprite.jpgTzthumbnails_sprite.json)r5   r}   r~   r€   r%   ÚUPLOAD_PATHr7   r�   )rQ   Ú	video_dirs     r<   Ú_is_thumbnails_availablerˆ   �   s�   € àŒ9ð Øˆuå”—’�XÔ1°8½SÀÄ¹^¼^ÑLÔL€Iå	„w‡~‚~•b”g—l’l 9Ð.EÑFÔFÑGÔGð Øˆtå	„w‡~‚~•b”g—l’l 9Ð.FÑGÔGÑHÔHð ØˆtØˆ5r>   Ú )Úresponse_modelé2   ÚskipÚlimitÚdbÚcurrent_userc              ƒ   ó$  K  — |rŠ|                      t          ¦  «                             t          j        dk    t          j        |j        k    z  ¦  «                             | ¦  «                             |¦  «                             ¦   «         }ns|                      t          ¦  «                             t          j        dk    ¦  «                             | ¦  «                             |¦  «                             ¦   «         }|D �]
}t          |j
        ¦  «        |_        t          |¦  «        |_        t          |¦  «        |_        |j        rH|j                             d¦  «        s.t$          j        rdt$          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd¦  «        }|                     d¦  «        st$          j        rdt$          j        › |› �n|}||_        �Œ|S )NTro   rp   ú/app/uploadsú/uploads)Úqueryr   Úfilterr`   rU   r5   Úoffsetr�   Úallrx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   ©rŒ   r�   rŽ   r�   r-   rQ   r^   s          r<   Úlist_streamsr˜   Ÿ   sÜ  è è € ð ð dØ—(’(�6Ñ"Ô"×)Ò)ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ç
Š&�‰,Œ,—u’u˜U‘|”|§C¢C¡E¤Eð 	ˆð —(’(�6Ñ"Ô"×)Ò)­&Ô*:¸dÒ*BÑCÔC×JÒJÈ4ÑPÔP×VÒVÐW\Ñ]Ô]×aÒaÑcÔcˆð ð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùà€Nr>   z/latesté   c              ƒ   ó  K  — |rÕ|                      t          ¦  «                             t          j        dk    t          j        |j        k    z  ¦  «                             t          j                             ¦   «          	                    ¦   «         t          j
                             ¦   «         ¦  «                             |¦  «                             ¦   «         }n¾|                      t          ¦  «                             t          j        dk    ¦  «                             t          j                             ¦   «          	                    ¦   «         t          j
                             ¦   «         ¦  «                             |¦  «                             ¦   «         }|D �]
}t          |j        ¦  «        |_        t!          |¦  «        |_        t%          |¦  «        |_        |j        rH|j                             d¦  «        s.t,          j        rdt,          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd¦  «        }|                     d¦  «        st,          j        rdt,          j        › |› �n|}||_        �Œt5          | |¦  «        }|r|S t7          |¦  «        }d„ |D ¦   «         }	t9          t;          j        |	¦  «        d¬¦  «        }
||
j        d	<   |
S )
z=Get latest streams by stream_date (or created_at as fallback)Tro   rp   r‘   r’   c                 ó,   — g | ]}t          |¦  «        ‘ŒS © ©rk   r9   s     r<   r=   z&get_latest_streams.<locals>.<listcomp>å   ó!   € Ð<Ð<Ð<¨qÕ'¨Ñ*Ô*Ð<Ð<Ð<r>   úapplication/json©ÚcontentÚ
media_typeÚETag) r“   r   r”   r`   rU   r5   Úorder_byra   ÚdescÚ
nulls_lastrV   r�   r–   rx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   rP   rG   r   r@   rA   rL   ©rH   r�   rŽ   r�   r-   rQ   r^   Úetag_responserN   Úresponse_dataÚresponses              r<   Úget_latest_streamsr«   ¿   s©  è è € ð ð Ø—(’(�6Ñ"Ô"×)Ò)ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ç
Š(•6Ô%×*Ò*Ñ,Ô,×7Ò7Ñ9Ô9½6Ô;L×;QÒ;QÑ;SÔ;SÑ
TÔ
T×UZÒUZÐ[`ÑUaÔUa×beÒbeÑbgÔbgð 	ˆð —(’(�6Ñ"Ô"×)Ò)­&Ô*:¸dÒ*BÑCÔC×LÒLÝÔ×#Ò#Ñ%Ô%×0Ò0Ñ2Ô2µFÔ4E×4JÒ4JÑ4LÔ4Lñ
ô 
ç
Š%�‰,Œ,—s’s‘u”uð 	ð ð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùõ ˜w¨Ñ0Ô0€MØð ØÐõ ˜Ñ!Ô!€DØ<Ð<°GÐ<Ñ<Ô<€MÝ¥¤
¨=Ñ 9Ô 9ÐFXÐYÑYÔY€HØ#€HÔ�VÑØ€Or>   z/popularc              ƒ   óL  K  — |r¦|                      t          ¦  «                             t          j        dk    t          j        |j        k    z  ¦  «                             t          j                             ¦   «         ¦  «         	                    |¦  «         
                    ¦   «         }n�|                      t          ¦  «                             t          j        dk    ¦  «                             t          j                             ¦   «         ¦  «         	                    |¦  «         
                    ¦   «         }|D �]
}t          |j        ¦  «        |_        t          |¦  «        |_        t!          |¦  «        |_        |j        rH|j                             d¦  «        s.t(          j        rdt(          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd¦  «        }|                     d¦  «        st(          j        rdt(          j        › |› �n|}||_        �Œt1          | |¦  «        }|r|S t3          |¦  «        }d„ |D ¦   «         }	t5          t7          j        |	¦  «        d¬¦  «        }
||
j        d	<   |
S )
z!Get popular streams by view_countTro   rp   r‘   r’   c                 ó,   — g | ]}t          |¦  «        ‘ŒS rœ   r�   r9   s     r<   r=   z'get_popular_streams.<locals>.<listcomp>  rž   r>   rŸ   r    r£   )r“   r   r”   r`   rU   r5   r¤   r_   r¥   r�   r–   rx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   rP   rG   r   r@   rA   rL   r§   s              r<   Úget_popular_streamsr®   ë   sf  è è € ð ð Ø—(’(�6Ñ"Ô"×)Ò)ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ç
Š(•6Ô$×)Ò)Ñ+Ô+Ñ
,Ô
,¯UªU°5©\¬\¿#º#¹%¼%ð 	ˆð —(’(�6Ñ"Ô"×)Ò)­&Ô*:¸dÒ*BÑCÔC×LÒLÝÔ×"Ò"Ñ$Ô$ñ
ô 
ç
Š%�‰,Œ,—s’s‘u”uð 	ð ð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùõ ˜w¨Ñ0Ô0€MØð ØÐõ ˜Ñ!Ô!€DØ<Ð<°GÐ<Ñ<Ô<€MÝ¥¤
¨=Ñ 9Ô 9ÐFXÐYÑYÔY€HØ#€HÔ�VÑØ€Or>   z/randomc           	   ƒ   ó¤  K  — |rd|                      t          ¦  «                             t          j        dk    t          j        |j        k    z  ¦  «                             ¦   «         }nM|                      t          ¦  «                             t          j        dk    ¦  «                             ¦   «         }t          j        |t          |t          |¦  «        ¦  «        ¦  «        }|D �]
}t          |j        ¦  «        |_        t          |¦  «        |_        t!          |¦  «        |_        |j        rH|j                             d¦  «        s.t(          j        rdt(          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd¦  «        }|                     d¦  «        st(          j        rdt(          j        › |› �n|}||_        �Œt1          | |¦  «        }|r|S t3          |¦  «        }	d„ |D ¦   «         }
t5          t7          j        |
¦  «        d¬¦  «        }|	|j        d	<   |S )
z Get random streams for discoveryTro   rp   r‘   r’   c                 ó,   — g | ]}t          |¦  «        ‘ŒS rœ   r�   r9   s     r<   r=   z&get_random_streams.<locals>.<listcomp>>  rž   r>   rŸ   r    r£   )r“   r   r”   r`   rU   r5   r–   ÚrandomÚsampleÚminÚlenrx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   rP   rG   r   r@   rA   rL   )rH   r�   rŽ   r�   Úall_streamsr-   rQ   r^   r¨   rN   r©   rª   s               r<   Úget_random_streamsr¶     s9  è è € ð ð NØ—h’h�vÑ&Ô&×-Ò-ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ç
Š#‰%Œ%ð 	ˆð —h’h�vÑ&Ô&×-Ò-­fÔ.>À$Ò.FÑGÔG×KÒKÑMÔMˆõ Œm˜K­¨UµC¸Ñ4DÔ4DÑ)EÔ)EÑFÔF€Gàð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùõ ˜w¨Ñ0Ô0€MØð ØÐõ ˜Ñ!Ô!€DØ<Ð<°GÐ<Ñ<Ô<€MÝ¥¤
¨=Ñ 9Ô 9ÐFXÐYÑYÔY€HØ#€HÔ�VÑØ€Or>   z
/admin/allc              ƒ   óÊ  K  — |                      t          ¦  «                             | ¦  «                             |¦  «                             ¦   «         }|D �]
}t          |j        ¦  «        |_        t          |¦  «        |_	        t          |¦  «        |_        |j        rH|j                             d¦  «        s.t          j        rdt          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd¦  «        }|                     d¦  «        st          j        rdt          j        › |› �n|}||_        �Œ|S )z4Admin-only endpoint to see all streams for dashboardro   rp   r‘   r’   )r“   r   r•   r�   r–   rx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   r—   s          r<   Úlist_all_streams_adminr¸   D  s[  è è € ð �hŠh•vÑÔ×%Ò% dÑ+Ô+×1Ò1°%Ñ8Ô8×<Ò<Ñ>Ô>€Gàð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùà€Nr>   z/searché   Úqc              ƒ   óV  K  — | r%t          |                      ¦   «         ¦  «        dk     rg S d|                      ¦   «                              ¦   «         › d�}|rR|                     t          ¦  «                             t          j        dk    t          j        |j        k    z  ¦  «        }n;|                     t          ¦  «                             t          j        dk    ¦  «        }|                     t          j	         
                    |¦  «        t          j         
                    |¦  «        z  ¦  «        }|                     |¦  «                             ¦   «         }ddlm} |r�|                     t          ¦  «                             |¦  «                             t          j        dk    t          j        |j        k    z  ¦  «                             |j         
                    |¦  «        ¦  «        }ny|                     t          ¦  «                             |¦  «                             t          j        dk    ¦  «                             |j         
                    |¦  «        ¦  «        }|                     |¦  «                             ¦   «         }	d„ |D ¦   «         }
|	D ]:}|j        |
vr/|                     |¦  «         |
                     |j        ¦  «         Œ;|                     t          ¦  «        }|r:|                     t          j        dk    t          j        |j        k    z  ¦  «        }n#|                     t          j        dk    ¦  «        }|                     ¦   «         }|D �]!}|j        |
v rŒ|j        �r|j        }d}d}|                     dd¦  «                             ¦   «                              |                     dd¦  «        ¦  «        d	k    rd}|sw|                     d
¦  «        rb|d
         D ]Y}|                     dd¦  «                             ¦   «                              |                     dd¦  «        ¦  «        d	k    rd} nŒZ|s|r/|                     |¦  «         |
                     |j        ¦  «         �Œ#|d|…         }|D �]
}t1          |j        ¦  «        |_        t7          |¦  «        |_        t;          |¦  «        |_        |j        rH|j                              d¦  «        s.tB          j"        rdtB          j"        › |j        › �n|j        |_        |j#        rp|j#                              d¦  «        sV|j#                             dd¦  «        }|                      d¦  «        stB          j"        rdtB          j"        › |› �n|}||_#        �Œ|S )zFSearch streams by title, streamer, or game (from chapters or metadata)r   ú%T©ÚChapterc                 ó   — h | ]	}|j         ’Œ
S rœ   )r5   r9   s     r<   ú	<setcomp>z!search_streams.<locals>.<setcomp>Š  s   € Ð(Ð(Ð(˜1�!”$Ð(Ð(Ð(r>   FÚgamer‰   éÿÿÿÿÚchaptersÚgameDisplayNameNro   rp   r‘   r’   )$r´   ÚstripÚlowerr“   r   r”   r`   rU   r5   rS   Úilikerc   r�   r–   Úmodels.chapterr¾   r€   Úgame_display_nameÚappendÚaddrd   rM   Úfindrq   rx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   )rº   r�   rŽ   r�   Úsearch_termr“   r-   r¾   Úchapter_queryÚchapter_streamsÚ
stream_idsrQ   Úall_streams_queryrµ   ÚmetadataÚ
game_matchÚchapter_matchÚchapterr^   s                      r<   Úsearch_streamsrÖ   _  sn  è è € ð ð •�A—G’G‘I”I‘” Ò"Ð"Øˆ	à*�a—g’g‘i”i—o’oÑ'Ô'Ð*Ð*Ð*€Kð ð BØ—’�Ñ Ô ×'Ò'ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ˆˆð —’�Ñ Ô ×'Ò'­Ô(8¸DÒ(@ÑAÔAˆð �LŠLÝ	Œ×	Ò	˜KÑ	(Ô	(Ý	Œ×	Ò	˜{Ñ	+Ô	+ñ	-ñô €Eð
 �kŠk˜%Ñ Ô ×$Ò$Ñ&Ô&€Gð )Ð(Ð(Ð(Ð(Ð(Øð ?ØŸš¥Ñ(Ô(×-Ò-¨gÑ6Ô6×=Ò=ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ç
Š&�Ô*×0Ò0°Ñ=Ô=Ñ
>Ô
>ð 	ˆð Ÿš¥Ñ(Ô(×-Ò-¨gÑ6Ô6×=Ò=ÝÔ Ò$ñ
ô 
ç
Š&�Ô*×0Ò0°Ñ=Ô=Ñ
>Ô
>ð 	ð $×)Ò)¨%Ñ0Ô0×4Ò4Ñ6Ô6€Oð )Ð( Ð(Ñ(Ô(€JØ!ð &ð &ˆØŒ9˜JÐ&Ð&Ø�NŠN˜6Ñ"Ô"Ð"Ø�NŠN˜6œ9Ñ%Ô%Ð%øð Ÿš¥Ñ(Ô(ÐØð OØ-×4Ò4ÝÔ Ò%­&Ô*;¸|¼Ò*NÑOñ
ô 
ÐÐð .×4Ò4µVÔ5EÈÒ5MÑNÔNÐà#×'Ò'Ñ)Ô)€Kàð *ñ *ˆØŒ9˜
Ð"Ð"Øð Ô!ñ 	*ØÔ-ˆHØˆJØ!ˆMð �|Š|˜F BÑ'Ô'×-Ò-Ñ/Ô/×4Ò4°[×5HÒ5HÈÈbÑ5QÔ5QÑRÔRÐVXÒXÐXØ!�
ð ð  (§,¢,¨zÑ":Ô":ð Ø'¨
Ô3ð ð �GØ—{’{Ð#4°bÑ9Ô9×?Ò?ÑAÔA×FÒFÀ{×GZÒGZÐ[^Ð`bÑGcÔGcÑdÔdÐhjÒjÐjØ(,˜Ø˜ð kð ð *˜]ð *Ø—’˜vÑ&Ô&Ð&Ø—’˜vœyÑ)Ô)Ð)ùð �f�u�fŒo€Gàð )ñ )ˆÝ'¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔÝ&>¸vÑ&FÔ&FˆÔ#àÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àÔð 	) FÔ$4×$?Ò$?ÀÑ$GÔ$Gð 	)ØÔ(×0Ò0°ÀÑLÔLˆIØ×'Ò'¨Ñ/Ô/ð fÝGOÄÐeÐC¥x¤ÐC¸	ÐCÐCÐCÐ\e�	Ø(ˆFÔùà€Nr>   z/{stream_id}Ú	stream_idc              ƒ   óª  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        sX|st          t          j	        d¬¦  «        ‚|j
        |j        k    r+|j        j        dk    rt          t          j        d¬¦  «        ‚t          |j        ¦  «        |_        t#          |¦  «        |_        t'          |¦  «        |_        |j        rH|j                             d¦  «        s.t.          j        rdt.          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd	¦  «        }|                     d¦  «        st.          j        rdt.          j        › |› �n|}||_        |S )
NúStream not found©rK   Údetailz+Authentication required for private streamsÚadminúAccess deniedro   rp   r‘   r’   )r“   r   r”   r5   Úfirstr   r   ÚHTTP_404_NOT_FOUNDr`   ÚHTTP_401_UNAUTHORIZEDrU   ÚroleÚnameÚHTTP_403_FORBIDDENrx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   ©r×   rŽ   r�   rQ   r^   s        r<   Ú
get_streamrå   É  sâ  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð Ôð 
Øð 	ÝÝ"Ô8ØDðñ ô ð ð Ô ¤Ò/Ð/°LÔ4EÔ4JÈgÒ4UÐ4UÝÝ"Ô5Ø&ðñ ô ð õ $ F¤OÑ4Ô4€F„NÝ,¨VÑ4Ô4€FÔÝ":¸6Ñ"BÔ"B€FÔð Ôð  FÔ$8×$CÒ$CÀFÑ$KÔ$Kð ÝU]ÔUdÐ~ÐQ­(¬/ÐQ¸6Ô;OÐQÐQÐQÐjpÔj~ˆÔð Ôð % Ô 0× ;Ò ;¸FÑ CÔ Cð %ØÔ$×,Ò,¨^¸ZÑHÔHˆ	Ø×#Ò# FÑ+Ô+ð 	bÝCKÄ?ÐaÐ?¥8¤?Ð?°IÐ?Ð?Ð?ÐXaˆIØ$ˆÔà€Mr>   z/{stream_id}/playc              ƒ   ó  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        sX|st          t          j	        d¬¦  «        ‚|j
        |j        k    r+|j        j        dk    rt          t          j	        d¬¦  «        ‚|xj        dz  c_        |                     ¦   «          |                     |¦  «         t!          |j        ¦  «        |_        t'          |¦  «        |_        t+          |¦  «        |_        |j        rH|j                             d¦  «        s.t2          j        rdt2          j        › |j        › �n|j        |_        |j        rp|j                             d¦  «        sV|j                             dd	¦  «        }|                     d¦  «        st2          j        rdt2          j        › |› �n|}||_        |S )
z4Increment view count when a video is actually playedrÙ   rÚ   rÝ   rÜ   é   ro   rp   r‘   r’   )r“   r   r”   r5   rÞ   r   r   rß   r`   rã   rU   rá   râ   r_   ÚcommitÚrefreshrx   rY   rZ   rƒ   r[   rˆ   r\   rX   ru   r%   rv   r^   rq   rä   s        r<   Úincrement_view_countrê   ÷  s  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð Ôð 
Øð 	ÝÝ"Ô5Ø&ðñ ô ð ð Ô ¤Ò/Ð/°LÔ4EÔ4JÈgÒ4UÐ4UÝÝ"Ô5Ø&ðñ ô ð ð ÐÔ˜ÑÐÔØ‡I‚I�K„K€KØ‡J‚JˆvÑÔÐõ $ F¤OÑ4Ô4€F„NÝ,¨VÑ4Ô4€FÔÝ":¸6Ñ"BÔ"B€FÔð Ôð  FÔ$8×$CÒ$CÀFÑ$KÔ$Kð ÝU]ÔUdÐ~ÐQ­(¬/ÐQ¸6Ô;OÐQÐQÐQÐjpÔj~ˆÔð Ôð % Ô 0× ;Ò ;¸FÑ CÔ Cð %ØÔ$×,Ò,¨^¸ZÑHÔHˆ	Ø×#Ò# FÑ+Ô+ð 	bÝCKÄ?ÐaÐ?¥8¤?Ð?°IÐ?Ð?Ð?ÐXaˆIØ$ˆÔà€Mr>   )rŠ   rK   zstream:createÚstream_datac              ƒ   óB  K  — t          | j        | j        |j        | j        ¬¦  «        }|                     |¦  «         |                     ¦   «          	 ddlm}  |¦   «          d S # t          $ r.}t          j                             d|› d�¦  «         Y d }~d S d }~ww xY w)N)rS   rT   rU   r`   r   ©Úrenumber_all_streamsz3[NUMBERING ERROR] Failed to renumber after create: ú
)r   rS   rT   r5   r`   rË   rè   Ú!services.stream_numbering_servicerî   Ú	ExceptionÚsysÚstderrÚwrite)rë   rŽ   r�   Ú
new_streamrî   Úes         r<   Úcreate_streamr÷   +  sØ   è è € õ ØÔØÔ+Ø”?ØÔ'ð	ñ ô €Jð ‡F‚Fˆ:ÑÔÐØ‡I‚I�K„K€KðVØLÐLÐLÐLÐLÐLØÐÑÔÐÐÐøÝð Vð Vð VÝŒ
×ÒÐTÈqÐTÐTÐTÑUÔUÐUÐUÐUÐUÐUÐUÐUøøøøðVøøøs   ÁA& Á&
BÁ0#BÂBzstream:updatezstream:update:ownc              ƒ   ó"  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dvr+|j
        |j        k    rt          t          j        d¬¦  «        ‚|j        j	        dk    r+|j
        |j        k    rt          t          j        d¬¦  «        ‚|j        �|j        |_        |j        �|j        |_        |j        �|j        |_        |j        �;|j        }d|v r)ddlm}  |¦   «         }|                     |¦  «        }|r|}||_        |j        �|j        |_        |j        �|j        |_        |j        �J|j        |_        |j        rd	nd
|_        |j        d	k    r#d|_        d|_        d |_        d |_        d |_        |j        ��t9          t;          j        t>          j         ¦  «         !                    ¦   «         ¦  «        }	d| › d|	› �|_        t;          j        t>          j         ¦  «        |_"        | #                    ¦   «          |j        �L	 ddl$m%}
  |
¦   «          n:# tL          $ r-}tN          j(         )                    d|› d�¦  «         Y d }~nd }~ww xY w| *                    |¦  «         	 ddl+m,}  |¦   «          n:# tL          $ r-}tN          j(         )                    d|› d�¦  «         Y d }~nd }~ww xY w|S )NrÙ   rÚ   ©rÜ   ÚcreatorrÝ   rú   útwitch.tv/videos/r   r&   rz   Úpendingr   ú/uploads/thumbnails/ú.jpg?t=©Úregenerate_master_ffconcatz4[FFCONCAT ERROR] Failed to regenerate after update: rï   rí   z3[NUMBERING ERROR] Failed to renumber after update: )-r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   rS   rT   r`   rb   Úservices.twitch_servicer'   Úextract_vod_idrc   r_   rY   re   rf   rg   rh   ri   rX   Úintr*   Únowr+   ÚutcÚ	timestampÚthumbnail_updated_atrè   Úservices.ffconcat_servicer   rñ   rò   ró   rô   ré   rð   rî   )r×   rë   rŽ   r�   rQ   rb   r'   Útwitch_serviceÚextracted_idr  r   rö   rî   s                r<   Úupdate_streamr  A  s—  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%9Ð9Ð9¸fÔ>OÐS_ÔSbÒ>bÐ>bÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð ÔÔ Ò*Ð*¨vÔ/@ÀLÄOÒ/SÐ/SÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð ÔÐ$Ø"Ô(ˆŒØÔÐ*Ø(Ô4ˆÔØÔÐ(Ø&Ô0ˆÔØÔ Ð,à#Ô1ˆØ -Ð/Ð/Ø?Ð?Ð?Ð?Ð?Ð?Ø*˜]™_œ_ˆNØ)×8Ò8¸ÑGÔGˆLØð -Ø ,�Ø,ˆÔØÔÐ'Ø%Ô.ˆŒØÔÐ)Ø'Ô2ˆÔð ÔÐ'Ø%Ô.ˆŒà#.Ô#7ÐF˜˜¸YˆŒØŒ=˜GÒ#Ð#Ø23ˆFÔ/Ø./ˆFÔ+Ø04ˆFÔ-Ø.2ˆFÔ+Ø37ˆFÔ0ð Ô Ð,Ý�œ¥X¤\Ñ2Ô2×<Ò<Ñ>Ô>Ñ?Ô?ˆ	ØS°iÐSÐSÈ	ÐSÐSˆÔÝ&.¤lµ8´<Ñ&@Ô&@ˆÔ#Ø
�	Š	‰Œˆð ÔÐ'ð	[ØNÐNÐNÐNÐNÐNØ&Ð&Ñ(Ô(Ð(Ð(øÝð 	[ð 	[ð 	[ÝŒJ×ÒÐYÐTUÐYÐYÐYÑZÔZÐZÐZÐZÐZÐZÐZøøøøð	[øøøð ‡J‚JˆvÑÔÐðVØLÐLÐLÐLÐLÐLØÐÑÔÐÐøÝð Vð Vð VÝŒ
×ÒÐTÈqÐTÐTÐTÑUÔUÐUÐUÐUÐUÐUÐUøøøøðVøøøð €Ms0   É#I4 É4
J+É>#J&Ê&J+ËK Ë
LË#LÌLz/{stream_id}/metadatarÒ   c              ƒ   ó  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚||_        t          j
        t          j        ¦  «        |_        |                     ¦   «          |                     |¦  «         	 ddlm}  |¦   «          n:# t$          $ r-}t&          j                             d|› d�¦  «         Y d }~nd }~ww xY w|S )NrÙ   rÚ   r   rí   z<[NUMBERING ERROR] Failed to renumber after metadata update: rï   )r“   r   r”   r5   rÞ   r   r   rß   rd   r*   r  r+   r  r6   rè   ré   rð   rî   rñ   rò   ró   rô   )r×   rÒ   rŽ   r�   rQ   rî   rö   s          r<   Úupdate_stream_metadatar  ›  s%  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð &€FÔÝ œ¥X¤\Ñ2Ô2€FÔØ‡I‚I�K„K€KØ‡J‚JˆvÑÔÐð_ØLÐLÐLÐLÐLÐLØÐÑÔÐÐøÝð _ð _ð _ÝŒ
×ÒÐ]ÐXYÐ]Ð]Ð]Ñ^Ô^Ð^Ð^Ð^Ð^Ð^Ð^øøøøð_øøøð €Ms   ÃC Ã
D	Ã#DÄD	rJ   zstream:deletezstream:delete:ownÚbackground_tasksc              ƒ   óÂ  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dk    rnW|j        j	        dk    r,|j
        |j        k    rt          t          j        d¬¦  «        ‚nt          t          j        d¬¦  «        ‚|j        }|j        }|j        }t          |j        ¦  «        } |                     |¦  «         |                     ¦   «          	 ddlm}  |¦   «          n:# t(          $ r-}	t*          j                             d|	› d	�¦  «         Y d }	~	nd }	~	ww xY w|r|                     t2          |||| ¦  «         	 dd
lm}
  |
¦   «          d S # t(          $ r.}	t*          j                             d|	› d	�¦  «         Y d }	~	d S d }	~	ww xY w)NrÙ   rÚ   rÜ   rú   rÝ   r   rÿ   z4[FFCONCAT ERROR] Failed to regenerate after delete: rï   rí   z3[NUMBERING ERROR] Failed to renumber after delete: )r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   r^   rY   rb   r7   Údeleterè   r  r   rñ   rò   ró   rô   Úadd_taskÚdelete_stream_filesrð   rî   )r×   rŽ   r�   r  rQ   r^   rY   rb   r   rö   rî   s              r<   Údelete_streamr  º  sS  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔ Ò(Ð(Øà	Ô	Ô	 9Ò	,Ð	,ØÔ ¤Ò/Ð/ÝÝ"Ô5Ø&ðñ ô ð ð 0õ ÝÔ1Ø"ð
ñ 
ô 
ð 	
ð Ô €IØŒ€HØÔ(€MÝ�F”I‘”€Ið ‡I‚IˆfÑÔÐØ‡I‚I�K„K€KðWØJÐJÐJÐJÐJÐJØ"Ð"Ñ$Ô$Ð$Ð$øÝð Wð Wð WÝŒ
×ÒÐUÐPQÐUÐUÐUÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøð ð fØ×!Ò!Õ"5°yÀ(ÈMÐ[dÑeÔeÐeðVØLÐLÐLÐLÐLÐLØÐÑÔÐÐÐøÝð Vð Vð VÝŒ
×ÒÐTÈqÐTÐTÐTÑUÔUÐUÐUÐUÐUÐUÐUÐUøøøøðVøøøs0   Ä(D9 Ä9
E0Å#E+Å+E0ÆF& Æ&
GÆ0#GÇGr^   rb   c           	      óÄ	  — ddl }ddl}ddl}ddlm} d}| r�|j                             | ¦  «        ru	  |j        | ¦  «         nc# t          $ rV}	|j	         
                    d| › d|	› d�¦  «         |j	                             ¦   «          dt          |	¦  «        › �}Y d}	~	nd}	~	ww xY w|r“|j                             |¦  «        ry	  |j        |d	¬
¦  «         ne# t          $ rX}	|j	         
                    d|› d|	› d�¦  «         |j	                             ¦   «          |sdt          |	¦  «        › �}Y d}	~	nd}	~	ww xY w|r¯|j                             d|› d�¦  «        }
|j                             |
¦  «        rw	  |j        |
¦  «         ne# t          $ rX}	|j	         
                    d|
› d|	› d�¦  «         |j	                             ¦   «          |sdt          |	¦  «        › �}Y d}	~	nd}	~	ww xY w|�r|j                             d|› d�¦  «        |j                             d|› d�¦  «        |j                             dd|› �¦  «        g}|D ]À}|j                             |¦  «        r¤	 |j                             |¦  «        r |j        |d	¬
¦  «         n |j        |¦  «         Œ[# t          $ rX}	|j	         
                    d|› d|	› d�¦  «         |j	                             ¦   «          |sdt          |	¦  «        › �}Y d}	~	Œ¸d}	~	ww xY wŒÁ|j                             |j        |¦  «        }|j                             |¦  «        ry	  |j        |d	¬
¦  «         ne# t          $ rX}	|j	         
                    d|› d|	› d�¦  «         |j	                             ¦   «          |sdt          |	¦  «        › �}Y d}	~	nd}	~	ww xY w|j                             |j        d|¦  «        }|j                             |¦  «        ry	  |j        |d	¬
¦  «         ne# t          $ rX}	|j	         
                    d|› d|	› d�¦  «         |j	                             ¦   «          |sdt          |	¦  «        › �}Y d}	~	nd}	~	ww xY w|r9|j	         
                    d|› d�¦  «         |j	                             ¦   «          dS |j	         
                    d¦  «         |j	                             ¦   «          dS )z!Delete stream files in backgroundr   Nr   r$   z$[DELETE] Failed to delete file_path ú: rï   zFailed to delete video file: T©Úignore_errorsz#[DELETE] Failed to delete hls_path z Failed to delete HLS directory: z/app/twitch_cachez
_chat.jsonz$[DELETE] Failed to delete chat file zFailed to delete chat file: ú.mp4z.partÚ	download_z$[DELETE] Failed to delete temp file zFailed to delete temp files: z%[DELETE] Failed to delete upload dir z#Failed to delete upload directory: r…   z%[DELETE] Failed to delete videos dir z#Failed to delete videos directory: z0[DELETE] Stream deletion completed with errors: z0[DELETE] Stream deletion completed successfully
)r}   Úshutilrò   Úconfigr%   r~   r�   Úremoverñ   ró   rô   Úflushr7   Úrmtreer€   r   r†   )r^   rY   rb   r×   r}   r  rò   r%   Údelete_errorrö   Ú	chat_fileÚ
temp_filesÚ	temp_fileÚstream_upload_dirÚstream_videos_dirs                  r<   r  r  ÷  s  € à€I€I€IØ€M€M€MØ€J€J€JØ!Ð!Ð!Ð!Ð!Ð!à€Lð ð D�R”W—^’^ IÑ.Ô.ð Dð	DØˆBŒI�iÑ Ô Ð Ð øÝð 	Dð 	Dð 	DØŒJ×ÒÐVÀIÐVÐVÐQRÐVÐVÐVÑWÔWÐWØŒJ×ÒÑÔÐØC½3¸q¹6¼6ÐCÐCˆLˆLˆLˆLˆLˆLøøøøð	Døøøð ð K�B”G—N’N 8Ñ,Ô,ð Kð	KØˆFŒM˜(°$Ð7Ñ7Ô7Ð7Ð7øÝð 	Kð 	Kð 	KØŒJ×ÒÐTÀ8ÐTÐTÈqÐTÐTÐTÑUÔUÐUØŒJ×ÒÑÔÐØð KØJÅ#ÀaÁ&Ä&ÐJÐJ�øøøøøøøøøð		Køøøð ð 	KØ”G—L’LÐ!4¸Ð6RÐ6RÐ6RÑSÔSˆ	ØŒ7�>Š>˜)Ñ$Ô$ð 	KðKØ�”	˜)Ñ$Ô$Ð$Ð$øÝð Kð Kð KØ”
× Ò Ð!ZÈ	Ð!ZÐ!ZÐUVÐ!ZÐ!ZÐ!ZÑ[Ô[Ð[Ø”
× Ò Ñ"Ô"Ð"Ø#ð KØ#JÅ#ÀaÁ&Ä&Ð#JÐ#J�Løøøøøøøøøð	Køøøð ñ PàŒG�LŠLÐ,°Ð.DÐ.DÐ.DÑEÔEØŒG�LŠLÐ,°Ð.EÐ.EÐ.EÑFÔFØŒG�LŠLÐ,Ð.I¸-Ð.IÐ.IÑJÔJð
ˆ
ð
 $ð 	Pð 	PˆIØŒw�~Š~˜iÑ(Ô(ð 
Pð	PØ”w—}’} YÑ/Ô/ð -Ø%˜œ i¸tÐDÑDÔDÐDÐDà!˜œ	 )Ñ,Ô,Ð,øøÝ ð Pð Pð PØ”J×$Ò$Ð%^ÈIÐ%^Ð%^ÐYZÐ%^Ð%^Ð%^Ñ_Ô_Ð_Ø”J×$Ò$Ñ&Ô&Ð&Ø'ð PØ'OÅsÈ1ÁvÄvÐ'OÐ'O˜øøøøøøøøøð	Pøøøð
Pð œŸš XÔ%9¸9ÑEÔEÐØ	„w‡~‚~Ð'Ñ(Ô(ð Nð	NØˆFŒMÐ+¸4Ð@Ñ@Ô@Ð@Ð@øÝð 	Nð 	Nð 	NØŒJ×ÒÐ_ÐEVÐ_Ð_ÐZ[Ð_Ð_Ð_Ñ`Ô`Ð`ØŒJ×ÒÑÔÐØð NØMÅSÈÁVÄVÐMÐM�øøøøøøøøøð		Nøøøð œŸš XÔ%9¸8ÀYÑOÔOÐØ	„w‡~‚~Ð'Ñ(Ô(ð Nð	NØˆFŒMÐ+¸4Ð@Ñ@Ô@Ð@Ð@øÝð 	Nð 	Nð 	NØŒJ×ÒÐ_ÐEVÐ_Ð_ÐZ[Ð_Ð_Ð_Ñ`Ô`Ð`ØŒJ×ÒÑÔÐØð NØMÅSÈÁVÄVÐMÐM�øøøøøøøøøð		Nøøøð ð ØŒ
×ÒÐ\ÈLÐ\Ð\Ð\Ñ]Ô]Ð]ØŒ
×ÒÑÔÐÐÐàŒ
×ÒÐLÑMÔMÐMØŒ
×ÒÑÔÐÐÐs•   ²A Á
B#ÁABÂB#ÃC Ã
D8Ã AD3Ä3D8Å6F Æ
G)ÆAG$Ç$G)É'=J%Ê%
LÊ/ALÌLÍM Í
N;Í#AN6Î6N;Ï:P Ð
Q/ÐAQ*Ñ*Q/z/{stream_id}/upload.Úfilec              ƒ   ó¼  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dk    r+|j
        |j        k    rt          t          j        d¬¦  «        ‚t          j        t          j        d¬¦  «         |j                             d¦  «        d         }t          j                             t          j        | › d|› �¦  «        }t)          |d	¦  «        5 }t+          j        |j        |¦  «         d d d ¦  «         n# 1 swxY w Y   ||_        d
|_        t3          j        t6          j        ¦  «        |_        |                     ¦   «          t?          | dd¬¦  «        }|                      |¦  «         |                     ¦   «          d|dœS )NrÙ   rÚ   rú   rÝ   T©Úexist_okú.rÂ   ÚwbÚ
processingÚ	transcoderü   )r×   Újob_typer   zFile uploaded successfully)Úmessager^   )!r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   r}   Úmakedirsr%   ÚSTORAGE_PATHÚfilenameÚsplitr~   r€   Úopenr  Úcopyfileobjr%  r^   r*   r  r+   r  r6   rè   r   rË   )	r×   r%  rŽ   r�   rQ   Úfile_extensionr^   ÚbufferÚprocessing_jobs	            r<   Úupload_videor8  Q  s÷  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔ Ò*Ð*¨vÔ/@ÀLÄOÒ/SÐ/SÝÝÔ1Ø"ð
ñ 
ô 
ð 	
õ „K•Ô%°Ð5Ñ5Ô5Ð5ð ”]×(Ò(¨Ñ-Ô-¨bÔ1€NÝ”—’�XÔ2°yÐ4SÐ4SÀ>Ð4SÐ4SÑTÔT€Iå	ˆi˜Ñ	Ô	ð . &ÝÔ˜4œ9 fÑ-Ô-Ð-ð.ð .ð .ñ .ô .ð .ð .ð .ð .ð .ð .øøøð .ð .ð .ð .ð !€FÔØ €F„MÝ œ¥X¤\Ñ2Ô2€FÔØ‡I‚I�K„K€Kõ #ØØØðñ ô €Nð
 ‡F‚Fˆ>ÑÔÐØ‡I‚I�K„K€Kà3À)ÐLÐLÐLs   Ä'EÅEÅEz/twitch-importTÚ
twitch_urlrS   rT   Údownload_videoÚembed_emotesc              ƒ   ó®  ‡ ‡‡‡K  — t          ¦   «         Št          |¦  «        }	 ‰                     ‰ ¦  «        }|st          t          j        d¬¦  «        ‚‰                     ‰ ¦  «        ƒ d{V —†}	ddlm}
 d}|	                     d¦  «        r3	  |
j	        |	d          
                    dd¦  «        ¦  «        }n#  Y nxY wt          |p|	                     d	d
|› �¦  «        |p|	                     dd¦  «        |j        dd|	                     dd¦  «        d|	                     d¦  «        ||	                     dd¦  «        |¬¦  «        Š|                     ‰¦  «         |                     ¦   «          |                     ‰¦  «         	 ‰                     ‰ |d¬¦  «        ƒ d{V —†}|                     dg ¦  «        }|                     d¦  «        }t"          j                             dt)          |¦  «        › d�¦  «         t"          j                             ¦   «          |D ]G}|                     ‰j        |d         |d         |d         |d         |d         |d         ¬¦  «         ŒH|r_|‰_        |                     d¦  «        r/‰                     t3          ‰j        ¦  «        |d         |¦  «         |                     ¦   «          nX# t4          $ rK}t"          j                             d |› d!�¦  «         t"          j                             ¦   «          Y d}~nd}~ww xY w|�rS	 t6          j                             t<          j        d"t3          ‰j        ¦  «        ¦  «        }t7          j         |d¬#¦  «         t6          j                             |‰j        › d$�¦  «        Šˆˆˆˆ fd%„}tC          j"        |¬&¦  «        }d|_#        | $                    ¦   «          t"          j                             d'‰j        › d!�¦  «         t"          j                             ¦   «          n¿# t4          $ rK}t"          j                             d(|› d!�¦  «         t"          j                             ¦   «          Y d}~nod}~ww xY wd)‰_        |                     ¦   «          	 d*d+l%m&}  |¦   «          n:# t4          $ r-}t"          j                             d,|› d!�¦  «         Y d}~nd}~ww xY w	 d*d-l'm(}  |¦   «          n:# t4          $ r-}t"          j                             d.|› d!�¦  «         Y d}~nd}~ww xY w‰S # tR          $ r-}t          t          j        t3          |¦  «        ¬¦  «        ‚d}~wtT          $ r-}t          t          j+        t3          |¦  «        ¬¦  «        ‚d}~wt4          $ r0}t          t          j+        d/t3          |¦  «        › �¬¦  «        ‚d}~ww xY w)0z,Import a stream from Twitch using Twitch APIzInvalid Twitch URL or IDrÚ   Nr   )r*   rV   ÚZz+00:00rS   zTwitch Stream rT   r‰   TÚdownloadingrW   rX   rc   )rS   rT   rU   r`   r   rW   r_   rX   rb   rc   ra   ©r;  Úinclude_metadataÚmessagesrÒ   ú[CHAT] Downloaded z chat messages
Úusernamer.  Útimestamp_offsetÚcolorÚemotesÚbadges©r×   rC  r.  rD  rE  rF  rG  rÃ   z#[CHAT ERROR] Chat download failed: rï   r…   r'  rm   c            	      ól  •— dd l }  | j        ¦   «         } | j        |¦  «         	 |                     ‰                     ‰‰
t          ‰	j        ¦  «        ¦  «        ¦  «        }ddlm}  |¦   «         }	 | 	                    t          ¦  «                             t          j        ‰	j        k    ¦  «                             ¦   «         }|r>|d                              dd¦  «        }||_        d|_        |                     ¦   «          |                     ¦   «          n# |                     ¦   «          w xY w	 ddlm}  |¦   «          n:# t(          $ r-}t*          j                             d	|› d
�¦  «         Y d }~nd }~ww xY w�n# t(          $ rù}t*          j                             d|› d
�¦  «         t*          j                             ¦   «          ddlm}  |¦   «         }	 | 	                    t          ¦  «                             t          j        ‰	j        k    ¦  «                             ¦   «         }|rd|_        |                     ¦   «          |                     ¦   «          n# |                     ¦   «          w xY wY d }~nd }~ww xY w|                     ¦   «          d S # |                     ¦   «          w xY w)Nr   r   ©ÚSessionLocalr^   r‘   r’   rz   rÿ   ú'[FFCONCAT ERROR] Failed to regenerate: rï   z1[DOWNLOAD ERROR] VOD download/processing failed: Úerror)ÚasyncioÚnew_event_loopÚset_event_loopÚrun_until_completer:  r7   r5   ÚdatabaserK  r“   r   r”   rÞ   rq   rY   r   rè   Úcloser  r   rñ   rò   ró   rô   r  )rN  ÚloopÚresultrK  Ú	db_threadrQ   rY   r   rö   rõ   Úoutput_pathr	  r9  s            €€€€r<   Údownload_and_processz0import_from_twitch.<locals>.download_and_processâ  sß  ø€ Ø"�N�N�NØ1˜7Ô1Ñ3Ô3�DØ*�GÔ*¨4Ñ0Ô0Ð0ð)%à!%×!8Ò!8Ø*×9Ò9¸*ÀkÕSVÐWaÔWdÑSeÔSeÑfÔfñ"ô "˜ð
 <Ð;Ð;Ð;Ð;Ð;Ø$0 L¡N¤N˜	ð	.Ø%.§_¢_µVÑ%<Ô%<×%CÒ%CÅFÄIÐQ[ÔQ^ÒD^Ñ%_Ô%_×%eÒ%eÑ%gÔ%g˜FØ%ð 3à+1°+Ô+>×+FÒ+FÀ~ÐWaÑ+bÔ+b Ø2: ¤Ø07 ¤Ø )× 0Ò 0Ñ 2Ô 2Ð 2à%ŸOšOÑ-Ô-Ð-Ð-ø˜IŸOšOÑ-Ô-Ð-Ð-øøøð^Ø^Ð^Ð^Ð^Ð^Ð^Ø6Ð6Ñ8Ô8Ð8Ð8øÝ(ð ^ð ^ð ^ÝœJ×,Ò,Ð-\ÐWXÐ-\Ð-\Ð-\Ñ]Ô]Ð]Ð]Ð]Ð]Ð]Ð]øøøøð^øøøùøõ %ð .ð .ð .Ýœ
×(Ò(Ð)bÐ]^Ð)bÐ)bÐ)bÑcÔcÐcÝœ
×(Ò(Ñ*Ô*Ð*à;Ð;Ð;Ð;Ð;Ð;Ø$0 L¡N¤N˜	ð.Ø%.§_¢_µVÑ%<Ô%<×%CÒ%CÅFÄIÐQ[ÔQ^ÒD^Ñ%_Ô%_×%eÒ%eÑ%gÔ%g˜FØ%ð 3Ø07 ¤Ø )× 0Ò 0Ñ 2Ô 2Ð 2à%ŸOšOÑ-Ô-Ð-Ð-ø˜IŸOšOÑ-Ô-Ð-Ð-øøøÐ-Ð-Ð-Ð-Ð-øøøøð.øøøð Ÿ
š
™œ˜˜˜ø˜Ÿ
š
™œ˜˜øøøs�   ¦AF Á3BD ÄF ÄD0Ä0F Ä4E ÅF Å
E<Å#E7Å2F Å7E<Å<F Å?J Æ
JÆAI?ÇA/I!ÉI?É!I7É7I?É:J É?JÊJ ÊJ3©Útargetz9[DOWNLOAD] Started VOD download in background for stream z/[DOWNLOAD ERROR] Failed to start VOD download: rz   r   rÿ   rL  rí   z:[NUMBERING ERROR] Failed to renumber after twitch import: zUnexpected error: ),r'   r(   r  r   r   ÚHTTP_400_BAD_REQUESTÚget_stream_infor*   rM   Úfromisoformatrq   r   r5   rË   rè   ré   Údownload_chatrò   ró   rô   r´   r  Úcreate_chat_messagerd   Úsave_chapters_to_dbr7   rñ   r}   r~   r€   r%   r†   r/  Ú	threadingÚThreadÚdaemonÚstartr  r   rð   rî   Ú
ValueErrorÚRuntimeErrorÚHTTP_500_INTERNAL_SERVER_ERROR)r9  rS   rT   r:  r;  rŽ   r�   Úchat_serviceÚvod_idÚstream_infor*   ra   Ú	chat_dataÚchat_messagesrÒ   Úmsgrö   Ú
stream_dirrX  Úthreadr   rî   rõ   rW  r	  s   `                     @@@r<   Úimport_from_twitchrp  ƒ  s·  øøøøè è € õ #‘_”_€NÝ˜r‘?”?€Lðn
à×.Ò.¨zÑ:Ô:ˆØð 	ÝÝ"Ô7Ø1ðñ ô ð ð +×:Ò:¸:ÑFÔFÐFÐFÐFÐFÐFÐFˆð 	&Ð%Ð%Ð%Ð%Ð%ØˆØ�?Š?˜<Ñ(Ô(ð 	ðØ4˜hÔ4°[ÀÔ5N×5VÒ5VÐWZÐ\dÑ5eÔ5eÑfÔf��øðØ�øøøåØÐN˜;Ÿ?š?¨7Ð4MÀVÐ4MÐ4MÑNÔNØ#ÐI {§¢°}ÀbÑ'IÔ'IØ#”ØØ Ø(Ÿ_š_Ð-?ÀÑCÔCØØ%Ÿ/š/¨/Ñ:Ô:Ø Ø —_’_ Z°Ñ4Ô4Ø#ð
ñ 
ô 
ˆ
ð 	�ŠˆzÑÔÐØ
�	Š	‰ŒˆØ
�
Š
�:ÑÔÐð	Ø,×:Ò:¸:ÐT`ÐswÐ:ÑxÔxÐxÐxÐxÐxÐxÐxˆIØ%ŸMšM¨*°bÑ9Ô9ˆMØ —}’} ZÑ0Ô0ˆHÝŒJ×ÒÐVµ#°mÑ2DÔ2DÐVÐVÐVÑWÔWÐWÝŒJ×ÒÑÔÐð %ð 	ð 	�Ø×0Ò0Ø(œmØ  œ_Ø 	œNØ%(Ð);Ô%<Ø˜gœ,Ø˜xœ=Ø˜xœ=ð 1ñ ô ð ð ð ð Ø-5�
Ô*à—<’< 
Ñ+Ô+ð eØ"×6Ò6µs¸:¼=Ñ7IÔ7IÈ8ÐT^ÔK_ÐacÑdÔdÐdØ—	’	‘”�øøåð 	ð 	ð 	ÝŒJ×ÒÐHÀ1ÐHÐHÐHÑIÔIÐIÝŒJ×ÒÑÔÐÐÐÐÐÐøøøøð	øøøð
 ñ M	RðB#õ  œWŸ\š\­(Ô*>ÀÍ#ÈjÌmÑJ\ÔJ\Ñ]Ô]�
Ý”˜J°Ð6Ñ6Ô6Ð6Ý œgŸlšl¨:¸*¼-Ð7NÐ7NÐ7NÑOÔO�ð.%ð .%ð .%ð .%ð .%ð .%ð .%ð .%õb #Ô)Ð1EÐFÑFÔF�Ø $�”Ø—’‘”�å”
× Ò Ð!nÐ]gÔ]jÐ!nÐ!nÐ!nÑoÔoÐoÝ”
× Ò Ñ"Ô"Ð"Ð"øåð #ð #ð #Ý”
× Ò Ð!XÐSTÐ!XÐ!XÐ!XÑYÔYÐYÝ”
× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð#øøøð
 !(ˆJÔØ�IŠI‰KŒKˆKðRØRÐRÐRÐRÐRÐRØ*Ð*Ñ,Ô,Ð,Ð,øÝð Rð Rð RÝ”
× Ò Ð!PÈ1Ð!PÐ!PÐ!PÑQÔQÐQÐQÐQÐQÐQÐQøøøøðRøøøð	aØPÐPÐPÐPÐPÐPØ Ð Ñ"Ô"Ð"Ð"øÝð 	að 	að 	aÝŒJ×ÒÐ_ÐZ[Ð_Ð_Ð_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`øøøøð	aøøøð Ðøåð 
ð 
ð 
ÝÝÔ3Ý�q‘6”6ð
ñ 
ô 
ð 	
øøøøõ ð 
ð 
ð 
ÝÝÔ=Ý�q‘6”6ð
ñ 
ô 
ð 	
øøøøõ ð 
ð 
ð 
ÝÝÔ=Ø0­¨A©¬Ð0Ð0ð
ñ 
ô 
ð 	
øøøøð
øøøsõ   ¥A*T0 Â*B; Â:T0 Â;B?Â=CT0 Æ
EK ËT0 Ë
L"ËALÌT0 ÌL"Ì"T0 Ì)C9P# Ð"T0 Ð#
Q8Ð-AQ3Ñ.T0 Ñ3Q8Ñ8T0 ÒR( Ò'T0 Ò(
SÒ2#SÓT0 ÓSÓT0 Ó#S4 Ó3T0 Ó4
T+Ó>#T&Ô!T0 Ô&T+Ô+T0 Ô0
WÔ:(U"Õ"WÕ/(VÖWÖ$+W×Wc                   óF   — e Zd ZU dZeed<   dZeed<   dZee	         ed<   dS )ÚReDownloadRequestFr:  Tr^  Nrb   )
Ú__name__Ú
__module__Ú__qualname__r:  ÚboolÚ__annotations__r^  rb   r   r7   rœ   r>   r<   rr  rr  B  sF   € € € € € € Ø €N�DÐ Ð Ñ Ø€M�4ÐÐÑØ#'€M�8˜C”=Ð'Ð'Ñ'Ð'Ð'r>   rr  z/{stream_id}/re-downloadc              ƒ   óŒ  ‡ ‡‡‡K  — |                      t          ¦  «                             t          j        ‰ k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dvr+|j
        |j        k    rt          t          j        d¬¦  «        ‚|j        j	        dk    r+|j
        |j        k    rt          t          j        d¬¦  «        ‚|j        p|j        }|st          t          j        d¬¦  «        ‚t          ¦   «         Št          |¦  «        }	 d|v r‰                     |¦  «        }d|› �Š|j        �rÞ	 ‰                     ‰d	d	¬
¦  «        ƒ d{V —†}|                     dg ¦  «        }|                     d¦  «        }	t&          j                             dt-          |¦  «        › d�¦  «         t&          j                             ¦   «          |                     ‰ ¦  «         |D ]B}
|                     ‰ |
d         |
d         |
d         |
d         |
d         |
d         ¬¦  «         ŒC|	r_|	|_        |	                     d¦  «        r/‰                     t9          |j        ¦  «        |	d         |¦  «         |                     ¦   «          |j        r+|j        |j        k    r||_        |                     ¦   «          nX# t<          $ rK}t&          j                             d|› d�¦  «         t&          j                             ¦   «          Y d}~nd}~ww xY w|j        �rì	 t@          j!         "                    tF          j$        dt9          ‰ ¦  «        ¦  «        }t@          j!         %                    |¦  «        r¯ddl&}t&          j                             d|› d�¦  «         t&          j                             ¦   «          	  |j'        |¦  «         nX# t<          $ rK}t&          j                             d|› d�¦  «         t&          j                             ¦   «          Y d}~nd}~ww xY wtA          j(        |d	¬¦  «         t@          j!         "                    |‰ › d�¦  «        Šˆˆ ˆˆfd „}tS          j*        |¬!¦  «        }d	|_+        | ,                    ¦   «          d"|_        |                     ¦   «          nX# t<          $ rK}t&          j                             d#|› d�¦  «         t&          j                             ¦   «          Y d}~nd}~ww xY w| -                    |¦  «         	 d$d%l.m/}  |¦   «          n:# t<          $ r-}t&          j                             d&|› d�¦  «         Y d}~nd}~ww xY w|S # t<          $ r0}t          t          j0        d't9          |¦  «        › �¬¦  «        ‚d}~ww xY w)(zJRe-download chat and optionally video for an existing stream with metadatarÙ   rÚ   rù   rÝ   rú   zZNo Twitch VOD ID provided. Please enter a Twitch VOD ID or URL in the form and save first.rû   zhttps://www.twitch.tv/videos/Tr?  NrA  rÒ   rB  z chat messages with metadata
rC  r.  rD  rE  rF  rG  rH  rÃ   z&[CHAT ERROR] Chat re-download failed: rï   r…   r   z&[CLEANUP] Removing old HLS directory: z.[CLEANUP WARNING] Failed to remove directory: r'  rm   c            	      óN  •— dd l }  | j        ¦   «         } | j        |¦  «         	 |                     ‰                     ‰‰	t          ‰
¦  «        ¦  «        ¦  «        }ddlm}  |¦   «         }	 |                     t          ¦  «         
                    t          j        ‰
k    ¦  «                             ¦   «         }|r>|d                              dd¦  «        }||_        d|_        |                     ¦   «          |                     ¦   «          n# |                     ¦   «          w xY w	 ddlm}  |¦   «          n:# t(          $ r-}t*          j                             d	|› d
�¦  «         Y d }~nd }~ww xY w�n# t(          $ rô}t*          j                             d|› d
�¦  «         t*          j                             ¦   «          ddlm}  |¦   «         }	 |                     t          ¦  «         
                    t          j        ‰
k    ¦  «                             ¦   «         }|rd|_        |                     ¦   «          |                     ¦   «          n# |                     ¦   «          w xY wY d }~nd }~ww xY w|                     ¦   «          d S # |                     ¦   «          w xY w)Nr   r   rJ  r^   r‘   r’   rz   rÿ   rL  rï   z4[DOWNLOAD ERROR] VOD re-download/processing failed: rM  )rN  rO  rP  rQ  r:  r7   rR  rK  r“   r   r”   r5   rÞ   rq   rY   r   rè   rS  r  r   rñ   rò   ró   rô   r  )rN  rT  rU  rK  rV  rQ   rY   r   rö   rW  r×   r	  r9  s            €€€€r<   rX  z0re_download_stream.<locals>.download_and_process¶  sÖ  ø€ Ø"�N�N�NØ1˜7Ô1Ñ3Ô3�DØ*�GÔ*¨4Ñ0Ô0Ð0ð(%à!%×!8Ò!8Ø*×9Ò9¸*ÀkÕSVÐW`ÑSaÔSaÑbÔbñ"ô "˜ð
 <Ð;Ð;Ð;Ð;Ð;Ø$0 L¡N¤N˜	ð	.Ø%.§_¢_µVÑ%<Ô%<×%CÒ%CÅFÄIÐQZÒDZÑ%[Ô%[×%aÒ%aÑ%cÔ%c˜FØ%ð 3à+1°+Ô+>×+FÒ+FÀ~ÐWaÑ+bÔ+b Ø2: ¤Ø07 ¤Ø )× 0Ò 0Ñ 2Ô 2Ð 2à%ŸOšOÑ-Ô-Ð-Ð-ø˜IŸOšOÑ-Ô-Ð-Ð-øøøð^Ø^Ð^Ð^Ð^Ð^Ð^Ø6Ð6Ñ8Ô8Ð8Ð8øÝ(ð ^ð ^ð ^ÝœJ×,Ò,Ð-\ÐWXÐ-\Ð-\Ð-\Ñ]Ô]Ð]Ð]Ð]Ð]Ð]Ð]øøøøð^øøøùøõ %ð .ð .ð .Ýœ
×(Ò(Ð)eÐ`aÐ)eÐ)eÐ)eÑfÔfÐfÝœ
×(Ò(Ñ*Ô*Ð*Ø;Ð;Ð;Ð;Ð;Ð;Ø$0 L¡N¤N˜	ð.Ø%.§_¢_µVÑ%<Ô%<×%CÒ%CÅFÄIÐQZÒDZÑ%[Ô%[×%aÒ%aÑ%cÔ%c˜FØ%ð 3Ø07 ¤Ø )× 0Ò 0Ñ 2Ô 2Ð 2à%ŸOšOÑ-Ô-Ð-Ð-ø˜IŸOšOÑ-Ô-Ð-Ð-øøøÐ-Ð-Ð-Ð-Ð-øøøøð.øøøð Ÿ
š
™œ˜˜˜ø˜Ÿ
š
™œ˜˜øøøs�   ¦AE7 Á.BD Ã;E7 ÄD&Ä&E7 Ä*D; Ä:E7 Ä;
E2Å#E-Å(E7 Å-E2Å2E7 Å5J Å7
I5ÆAI0ÇA*IÈ=I0ÉI(É(I0É+J É0I5É5J ÊJ$rY  r>  z2[DOWNLOAD ERROR] Failed to start VOD re-download: r   rí   z8[NUMBERING ERROR] Failed to renumber after re-download: zRe-download failed: )1r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   rb   r[  r'   r(   r  r^  rM   rò   ró   rô   r´   r  Údelete_chat_messagesr_  rd   r`  r7   rè   rñ   r:  r}   r~   r€   r%   r†   r�   r  r  r/  ra  rb  rc  rd  ré   rð   rî   rg  )r×   rH   rŽ   r�   rQ   Úvod_id_to_userh  rk  rl  rÒ   rm  rö   rn  r  rX  ro  rî   rW  r	  r9  s   `                @@@r<   Úre_download_streamr|  G  so  øøøøè è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%9Ð9Ð9¸fÔ>OÐS_ÔSbÒ>bÐ>bÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð ÔÔ Ò*Ð*¨vÔ/@ÀLÄOÒ/SÐ/SÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð Ô)ÐA¨VÔ-A€Màð 
ÝÝÔ3Øoð
ñ 
ô 
ð 	
õ
 #‘_”_€NÝ˜r‘?”?€LðO
à -Ð/Ð/Ø*×9Ò9¸-ÑHÔHˆMð E°]ÐDÐDˆ
ð Ô ñ &	#ð%#Ø"0×">Ò">¸zÐX\ÐosÐ">Ñ"tÔ"tÐtÐtÐtÐtÐtÐt�	Ø )§¢¨j¸"Ñ =Ô =�Ø$Ÿ=š=¨Ñ4Ô4�Ý”
× Ò Ð!hµc¸-Ñ6HÔ6HÐ!hÐ!hÐ!hÑiÔiÐiÝ”
× Ò Ñ"Ô"Ð"ð ×1Ò1°)Ñ<Ô<Ð<ð )ð 	ð 	�CØ ×4Ò4Ø"+Ø!$ Z¤Ø # I¤Ø),Ð-?Ô)@Ø! 'œlØ" 8œ}Ø" 8œ}ð 5ñ ô ð ð ð ð  Ø-5�FÔ*à—|’| JÑ/Ô/ð eØ&×:Ò:½3¸v¼y¹>¼>È8ÐT^ÔK_ÐacÑdÔdÐdØ—I’I‘K”K�Kð Ô(ð  ¨WÔ-BÀfÔFZÒ-ZÐ-ZØ+8�FÔ(Ø—I’I‘K”K�Køøåð #ð #ð #Ý”
× Ò Ð!OÈ!Ð!OÐ!OÐ!OÑPÔPÐPÝ”
× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð#øøøð
 Ô!ñ L	#ðK#åœWŸ\š\­(Ô*>ÀÍ#ÈiÉ.Ì.ÑYÔY�
Ý”7—>’> *Ñ-Ô-ð +Ø!�M�M�MÝ”J×$Ò$Ð%\ÈjÐ%\Ð%\Ð%\Ñ]Ô]Ð]Ý”J×$Ò$Ñ&Ô&Ð&ð+Ø%˜œ jÑ1Ô1Ð1Ð1øÝ$ð +ð +ð +Ýœ
×(Ò(Ð)_ÐZ[Ð)_Ð)_Ð)_Ñ`Ô`Ð`Ýœ
×(Ò(Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*øøøøð+øøøõ
 ”˜J°Ð6Ñ6Ô6Ð6Ý œgŸlšl¨:¸)Ð7JÐ7JÐ7JÑKÔK�ð-%ð -%ð -%ð -%ð -%ð -%ð -%ð -%õ` #Ô)Ð1EÐFÑFÔF�Ø $�”Ø—’‘”�à -�”Ø—	’	‘”��øåð #ð #ð #Ý”
× Ò Ð![ÐVWÐ![Ð![Ð![Ñ\Ô\Ð\Ý”
× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð#øøøð 	�
Š
�6ÑÔÐð	_ØPÐPÐPÐPÐPÐPØ Ð Ñ"Ô"Ð"Ð"øÝð 	_ð 	_ð 	_ÝŒJ×ÒÐ]ÐXYÐ]Ð]Ð]Ñ^Ô^Ð^Ð^Ð^Ð^Ð^Ð^øøøøð	_øøøð ˆøåð 
ð 
ð 
ÝÝÔ=Ø2­#¨a©&¬&Ð2Ð2ð
ñ 
ô 
ð 	
øøøøð
øøøsÆ   Ä.&V	 ÅFK ËV	 Ë
L/Ë$AL*Ì%V	 Ì*L/Ì/V	 Ì;BS ÏO) Ï(S Ï)
P>Ï3AP9Ð4S Ð9P>Ð>BS ÓV	 Ó
T#ÓATÔV	 ÔT#Ô#V	 Ô<U ÕV	 Õ
VÕ#U?Õ:V	 Õ?VÖV	 Ö	
WÖ+V>Ö>Wz/{stream_id}/import-chat-jsonÚchat_json_filec              ƒ   óä  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dvr+|j
        |j        k    rt          t          j        d¬¦  «        ‚|j        j	        dk    r+|j
        |j        k    rt          t          j        d¬¦  «        ‚	 |                     ¦   «         ƒ d{V —†}t          j        |                     d¦  «        ¦  «        }t!          |¦  «        }|                     |¦  «        }|                     d¦  «        |                     d	¦  «        |                     d
¦  «        |                     d¦  «        dœ}	|	|_        |                     ¦   «          |                     d¦  «        r„ddlm}
 |                      |
¦  «                             |
j        |j        k    ¦  «                             ¦   «          |                     ¦   «          |                     |j        |d         ¬¦  «         |                     d¦  «        r™ddlm} |                      |¦  «                             |j        |j        k    ¦  «                             ¦   «          |                     ¦   «          |                     |j        |d         |                     di ¦  «        ¬¦  «         |                     |¦  «         	 ddlm}  |¦   «          n:# t@          $ r-}tB          j"         #                    d|› d�¦  «         Y d}~nd}~ww xY w|S # t          j$        $ r t          dd¬¦  «        ‚t@          $ rg}tB          j"         #                    d|› d�¦  «         tB          j"         %                    ¦   «          t          ddtM          |¦  «        › �¬¦  «        ‚d}~ww xY w)zDImport chat.json (chapters and chat messages) for an existing streamrÙ   rÚ   rù   rÝ   rú   Núutf-8rÁ   Ústreamer_loginÚstreamer_idrÃ   ©rÁ   r€  r�  rÃ   r   r½   ©r×   Úchapters_dataÚcomments)ÚChatMessageÚembedded_data©r×   Úcomments_datar‡  rí   z:[NUMBERING ERROR] Failed to renumber after manual import: rï   é�  úInvalid chat.json filez4[IMPORT CHAT JSON ERROR] Error importing chat.json: éô  zError importing chat.json: )'r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   Úreadr@   ÚloadsÚdecoder)   Úparse_chat_jsonrM   rd   rè   rÈ   r¾   r×   r  Úimport_chapters_from_chat_jsonÚmodels.chat_messager†  Ú#import_chat_messages_from_chat_jsonré   rð   rî   rñ   rò   ró   rô   ÚJSONDecodeErrorr  r7   )r×   r}  rŽ   r�   rQ   Úchat_json_contentÚchat_json_dataÚchat_json_serviceÚparsed_datarÒ   r¾   r†  rî   rö   s                 r<   Úimport_chat_json_for_streamr™    s:  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%9Ð9Ð9¸fÔ>OÐS_ÔSbÒ>bÐ>bÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð ÔÔ Ò*Ð*¨vÔ/@ÀLÄOÒ/SÐ/SÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð
=\à"0×"5Ò"5Ñ"7Ô"7Ð7Ð7Ð7Ð7Ð7Ð7ÐÝœÐ$5×$<Ò$<¸WÑ$EÔ$EÑFÔFˆå+¨BÑ/Ô/ÐØ'×7Ò7¸ÑGÔGˆð  —O’O FÑ+Ô+Ø)ŸošoÐ.>Ñ?Ô?Ø&Ÿ?š?¨=Ñ9Ô9Ø#Ÿš¨
Ñ3Ô3ð	
ð 
ˆð "*ˆÔØ
�	Š	‰Œˆð �?Š?˜:Ñ&Ô&ð 
	à0Ð0Ð0Ð0Ð0Ð0Ø�HŠH�WÑÔ×$Ò$ WÔ%6¸&¼)Ò%CÑDÔD×KÒKÑMÔMÐMØ�IŠI‰KŒKˆKð ×<Ò<Ø œ)Ø)¨*Ô5ð =ñ ô ð ð �?Š?˜:Ñ&Ô&ð 	à9Ð9Ð9Ð9Ð9Ð9Ø�HŠH�[Ñ!Ô!×(Ò(¨Ô)>À&Ä)Ò)KÑLÔL×SÒSÑUÔUÐUØ�IŠI‰KŒKˆKð ×AÒAØ œ)Ø)¨*Ô5Ø)Ÿošo¨o¸rÑBÔBð Bñ ô ð ð 	�
Š
�6ÑÔÐð	aØPÐPÐPÐPÐPÐPØ Ð Ñ"Ô"Ð"Ð"øÝð 	að 	að 	aÝŒJ×ÒÐ_ÐZ[Ð_Ð_Ð_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`øøøøð	aøøøð ˆøåÔð Nð Nð NÝ¨Ð4LÐMÑMÔMÐMÝð \ð \ð \ÝŒ
×ÒÐUÐPQÐUÐUÐUÑVÔVÐVÝŒ
×ÒÑÔÐÝ¨Ð4ZÕRUÐVWÑRXÔRXÐ4ZÐ4ZÐ[Ñ[Ô[Ð[øøøøð\øøøsD   Ã"H/M ÌL# Ì"M Ì#
MÌ-#MÍM ÍMÍM Í)O/ÎA"O*Ï*O/z/{stream_id}/download-progressc              ƒ   óÄ   K  — 	 d| › �}t          j        |¦  «        }|sdddœS t          j        |¦  «        S # t          $ r}ddt          |¦  «        dœcY d}~S d}~ww xY w)z"Get download progress for a streamzdownload_progress:Ú	not_foundr   ©r   Ú
percentagerM  ©r   r�  rM  N©r,   rM   r@   rŽ  rñ   r7   ©r×   rŽ   Úprogress_keyÚprogress_datarö   s        r<   Úget_download_progressr£  a  s­   è è € ð
Ø7¨IÐ7Ð7ˆå$Ô(¨Ñ6Ô6ˆàð 	à%Øðð ð õ
 Œz˜-Ñ(Ô(Ð(øåð 
ð 
ð 
àØÝ˜‘V”Vð
ð 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
øøøøð
øøøó   „8 ¤8 ¸
AÁAÁAÁAz /{stream_id}/processing-progressc              ƒ   óÄ   K  — 	 d| › �}t          j        |¦  «        }|sdddœS t          j        |¦  «        S # t          $ r}ddt          |¦  «        dœcY d}~S d}~ww xY w)z$Get processing progress for a streamústream_progress:r›  r   rœ  rM  rž  NrŸ  r   s        r<   Úget_processing_progressr§  |  s­   è è € ð
Ø5¨)Ð5Ð5ˆå$Ô(¨Ñ6Ô6ˆàð 	à%Øðð ð õ
 Œz˜-Ñ(Ô(Ð(øåð 
ð 
ð 
àØÝ˜‘V”Vð
ð 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
øøøøð
øøør¤  z/{stream_id}/processFÚforcec           	   ƒ   ó¨  ‡ ‡K  — 	 t           j                             d‰ › d|› d�¦  «         t           j                             ¦   «          |                     t
          ¦  «                             t
          j        t          ‰ ¦  «        k    ¦  «         	                    ¦   «         }|st          dd¬¦  «        ‚t           j                             d|j        › d|j        › d	|j        › d�¦  «         t           j                             ¦   «          |j        st          d
d¬¦  «        ‚|j        dk    rD|sBt           j                             d¦  «         t           j                             ¦   «          dddœS d‰ › �}t          j        |¦  «        }|r|t!          j        |¦  «                             d¦  «        dk    rQt           j                             d¦  «         t           j                             ¦   «          t          j        |¦  «         |j        dk    rBt           j                             d¦  «         t           j                             ¦   «          dddœS d|_        |                     ¦   «          t           j                             d¦  «         t           j                             ¦   «          ddlmŠ ddl}ˆˆ fd„} |j        |¬¦  «        }	|	                     ¦   «          t           j                             d ¦  «         t           j                             ¦   «          d!t          ‰ ¦  «        d"œS # t          $ r ‚ t2          $ r‰}
t           j                             d#|
› d�¦  «         t           j                             ¦   «          ddl}|                     ¦   «          t          t          j        d$t          |
¦  «        › �¬¦  «        ‚d}
~
ww xY w)%z,Manually trigger HLS processing for a streamz.[PROCESSING] Triggering processing for stream z, force=rï   é”  rÙ   rÚ   z[PROCESSING] Stream found: z
, status: z, file_path: rŠ  z&No video file available for processingr+  z/[PROCESSING] Stream is already being processed
z!Stream is already being processedzSet force=true to restart)r.  Ú	use_forcezprocessing_state:r   Úinterruptedz9[PROCESSING] Processing was interrupted, auto-restarting
rz   z)[PROCESSING] Stream is already processed
zStream is already processedzSet force=true to reprocessz*[PROCESSING] Status updated to processing
r   )ÚVideoProcessorr   Nc                  óH  •— 	 t           j                             d‰› d�¦  «         t           j                             ¦   «           ‰¦   «         } |                      t          ‰¦  «        ¦  «         t           j                             d‰› d�¦  «         t           j                             ¦   «          d S # t          $ rd}t           j                             d|› d�¦  «         t           j                             ¦   «          dd l}|                     ¦   «          Y d }~d S d }~ww xY w)Nz2[PROCESSING] Background thread started for stream rï   z4[PROCESSING] Background thread completed for stream z1[PROCESSING ERROR] Background processing failed: r   )	rò   ró   rô   r  Úprocess_videor7   rñ   Ú	tracebackÚ	print_exc)Ú	processorrö   r°  r­  r×   s      €€r<   Úprocess_in_backgroundz1trigger_processing.<locals>.process_in_backgroundË  s)  ø€ ð&Ý”
× Ò Ð!cÐV_Ð!cÐ!cÐ!cÑdÔdÐdÝ”
× Ò Ñ"Ô"Ð"Ø*˜NÑ,Ô,�	Ø×'Ò'­¨I©¬Ñ7Ô7Ð7Ý”
× Ò Ð!eÐXaÐ!eÐ!eÐ!eÑfÔfÐfÝ”
× Ò Ñ"Ô"Ð"Ð"Ð"øÝð &ð &ð &Ý”
× Ò Ð!ZÐUVÐ!ZÐ!ZÐ!ZÑ[Ô[Ð[Ý”
× Ò Ñ"Ô"Ð"Ø Ð Ð Ð Ø×#Ò#Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Ð%Ð%øøøøð	&øøøs   ƒB.B3 Â3
D!Â=ADÄD!rY  z0[PROCESSING] Thread started, returning response
zProcessing started©r.  r×   z[PROCESSING ERROR] Error: zFailed to trigger processing: )rò   ró   rô   r  r“   r   r”   r5   r7   rÞ   r   rS   r   r^   r,   rM   r@   rŽ  r  rè   Úservices.video_processorr­  ra  rb  rd  rñ   r°  r±  rg  )r×   r¨  rŽ   r�   rQ   Ú	state_keyÚstatera  r³  ro  rö   r°  r­  s   `           @r<   Útrigger_processingr¸  —  sÌ  øøè è € ðK
ÝŒ
×ÒÐfÈ)ÐfÐfÐ]bÐfÐfÐfÑgÔgÐgÝŒ
×ÒÑÔÐð —’�&Ñ!Ô!×(Ò(­¬µc¸)±n´nÒ)DÑEÔE×KÒKÑMÔMˆØð 	LÝ¨CÐ8JÐKÑKÔKÐKåŒ
×ÒÐ°v´|ÐÐÈvÌ}ÐÐÐkqÔk{ÐÐÐñ  	Aô  	Að  	AÝŒ
×ÒÑÔÐàÔð 	bÝ¨CÐ8`ÐaÑaÔaÐaàŒ=˜LÒ(Ð(°Ð(ÝŒJ×ÒÐPÑQÔQÐQÝŒJ×ÒÑÔÐØBÐQlÐmÐmÐmð 4¨	Ð3Ð3ˆ	ÝÔ  Ñ+Ô+ˆØð 	+•T”Z Ñ&Ô&×*Ò*¨8Ñ4Ô4¸ÒEÐEÝŒJ×ÒÐZÑ[Ô[Ð[ÝŒJ×ÒÑÔÐåÔ 	Ñ*Ô*Ð*àŒ=˜GÒ#Ð#ÝŒJ×ÒÐJÑKÔKÐKÝŒJ×ÒÑÔÐØ<ÐKhÐiÐiÐið %ˆŒØ
�	Š	‰ŒˆÝŒ
×ÒÐGÑHÔHÐHÝŒ
×ÒÑÔÐð 	>Ð=Ð=Ð=Ð=Ð=ØÐÐÐð	&ð 	&ð 	&ð 	&ð 	&ð 	&ð "�Ô!Ð)>Ð?Ñ?Ô?ˆØ�Š‰ŒˆÝŒ
×ÒÐMÑNÔNÐNÝŒ
×ÒÑÔÐà/½cÀ)¹n¼nÐMÐMÐMøåð ð ð ØÝð 
ð 
ð 
ÝŒ
×ÒÐ;°aÐ;Ð;Ð;Ñ<Ô<Ð<ÝŒ
×ÒÑÔÐØÐÐÐØ×ÒÑÔÐÝÝÔ=Ø<µC¸±F´FÐ<Ð<ð
ñ 
ô 
ð 	
øøøøð
øøøs'   †E-L4 Å4C#L4 ÉCL4 Ì4OÍBOÏOz'/{stream_id}/thumbnail/{segment_number}Úsegment_numberc              ƒ   ó  K  — 	 |dk     rt          dd¬¦  «        ‚|                     t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          dd¬¦  «        ‚t          j        › d| › �}|› d| › d	|› d
�}t          j	         
                    |¦  «        s|› d| › d|dz   › �}t          j	         
                    |¦  «        st          dd¬¦  «        ‚|› d|d›d�}t          j	         
                    |¦  «        s$dd|ddddddd|g}t          j        |dd¬¦  «         t          |d¦  «        5 }|                     ¦   «         }	ddd¦  «         n# 1 swxY w Y   t          |	d¬¦  «        S # t           $ r ‚ t           $ rg}
t"          j                             d |
› d!�¦  «         t"          j                             ¦   «          t          d"d#t+          |
¦  «        › �¬¦  «        ‚d}
~
ww xY w)$z-Get thumbnail (first frame) of an HLS segmentr   rŠ  z#Segment number must be non-negativerÚ   rª  rÙ   ú/videos/rn   ú-ú.tsú.ts-Fragrç   zSegment not foundú/thumb_Ú03dú.jpgÚffmpegú-iú	-frames:vÚ1ú-q:vÚ2ú-strictú-2ú-yT)Úcapture_outputÚcheckÚrbNz
image/jpegr    z.[THUMBNAIL ERROR] Error generating thumbnail: rï   rŒ  úFailed to generate thumbnail: )r   r“   r   r”   r5   rÞ   r%   r†   r}   r~   r�   Ú
subprocessÚrunr3  r�  r   rñ   rò   ró   rô   r  r7   )r×   r¹  rŽ   rQ   Úhls_dirÚsegment_fileÚthumbnail_pathÚcmdÚfÚthumbnail_datarö   s              r<   Úget_segment_thumbnailr×  í  s£  è è € ð2_à˜AÒÐÝ¨CÐ8]Ð^Ñ^Ô^Ð^ð —’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	LÝ¨CÐ8JÐKÑKÔKÐKõ Ô)Ð>Ð>°9Ð>Ð>ˆà!ÐCÐC IÐCÐC°ÐCÐCÐCˆõ Œw�~Š~˜lÑ+Ô+ð 	PØ%ÐOÐO¨	ÐOÐO¸>ÈAÑ;MÐOÐOˆLõ Œw�~Š~˜lÑ+Ô+ð 	MÝ¨CÐ8KÐLÑLÔLÐLð $ÐDÐD¨NÐDÐDÐDÐDˆõ Œw�~Š~˜nÑ-Ô-ð 
	AàØ�lØ˜SØ˜Ø˜4ØØðˆCõ ŒN˜3¨t¸4Ð@Ñ@Ô@Ð@õ �. $Ñ'Ô'ð 	&¨1ØŸVšV™XœXˆNð	&ð 	&ð 	&ñ 	&ô 	&ð 	&ð 	&ð 	&ð 	&ð 	&ð 	&øøøð 	&ð 	&ð 	&ð 	&õ  ¸<ÐHÑHÔHÐHøåð ð ð ØÝð _ð _ð _ÝŒ
×ÒÐOÈ!ÐOÐOÐOÑPÔPÐPÝŒ
×ÒÑÔÐÝ¨Ð4]ÕUXÐYZÑU[ÔU[Ð4]Ð4]Ð^Ñ^Ô^Ð^øøøøð_øøøs=   „EF ÅE0Å$F Å0E4Å4F Å7E4Å8F ÆHÆ A"HÈHz/{stream_id}/thumbnail-progressc              ƒ   ó2  K  — 	 |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|sdS |j        rG|j        dk    r<|j        |j        |j        |j	        |j        r|j         
                    ¦   «         nddœS dS # t          $ rg}t          j                             d|› d�¦  «         t          j                             ¦   «          t!          ddt#          |¦  «        › �¬¦  «        ‚d}~ww xY w)	z.Get thumbnail generation progress for a streamNr   )Ú	generatedÚtotalr.  rM  r6   z4[THUMBNAIL ERROR] Error getting thumbnail progress: rï   rŒ  z"Failed to get thumbnail progress: rÚ   )r“   r   r”   r5   rÞ   ri   rf   re   rg   rh   r8   rñ   rò   ró   rô   r  r   r7   )r×   rŽ   rQ   rö   s       r<   Úget_thumbnail_progressrÛ  )  s;  è è € ðcØ—’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	Ø�4ð Ô/ð 		°FÔ4SÐVWÒ4WÐ4Wà#Ô@ØÔ8Ø!Ô<ØÔ8ØRXÔRvð  A˜fÔB×LÒLÑNÔNÐNð  }Aðð ð ð �4øÝð cð cð cÝŒ
×ÒÐUÐPQÐUÐUÐUÑVÔVÐVÝŒ
×ÒÑÔÐÝ¨Ð4aÕY\Ð]^ÑY_ÔY_Ð4aÐ4aÐbÑbÔbÐbøøøøðcøøøs    „AB% ÁAB% Â%
DÂ/A"DÄDz/{stream_id}/hls-filesc              ƒ   óø  K  — 	 |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          dd¬¦  «        ‚t          j        › d| › �}ddd|dœ}t          j	         
                    || › d�¦  «        }t          j	                             |¦  «        rd	| › d
| › d�|d<   t          j	         
                    || › d�¦  «        }t          j	                             |¦  «        rd	| › d
| › d�|d<   t          j	                             |¦  «        rOt          j	                             |¦  «        r0d„ t          j        |¦  «        D ¦   «         }t          |¦  «        |d<   |S # t          $ rg}	t           j                             d|	› d�¦  «         t           j                             ¦   «          t          ddt)          |	¦  «        › �¬¦  «        ‚d}	~	ww xY w)z1Get available HLS files for a stream (admin only)rª  rÙ   rÚ   r»  Nr   )Úm3u8Úmp4Úts_segmentsÚ	directoryrm   ú/uploads/videos/rn   rÝ  r  rÞ  c                 ó<   — g | ]}|                      d ¦  «        ¯|‘ŒS )r½  ©rs   ©r:   rÕ  s     r<   r=   z!get_hls_files.<locals>.<listcomp>g  s)   € ÐLÐLÐL˜a¸!¿*º*ÀUÑ:KÔ:KÐL˜ÐLÐLÐLr>   rß  z%[HLS ERROR] Error getting HLS files: rï   rŒ  zFailed to get HLS files: )r“   r   r”   r5   rÞ   r   r%   r†   r}   r~   r€   r�   r   Úlistdirr´   rñ   rò   ró   rô   r  r7   )
r×   rŽ   r�   rQ   rÑ  Úavailable_filesr‚   Úmp4_pathÚts_filesrö   s
             r<   Úget_hls_filesré  E  s  è è € ð"ZØ—’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	LÝ¨CÐ8JÐKÑKÔKÐKåÔ)Ð>Ð>°9Ð>Ð>ˆð ØØØ ð	
ð 
ˆõ ”G—L’L ¨YÐ*=Ð*=Ð*=Ñ>Ô>ˆ	ÝŒ7�>Š>˜)Ñ$Ô$ð 	VØ&U¸Ð&UÐ&UÀYÐ&UÐ&UÐ&UˆO˜FÑ#õ ”7—<’< ¨IÐ);Ð);Ð);Ñ<Ô<ˆÝŒ7�>Š>˜(Ñ#Ô#ð 	TØ%S¸	Ð%SÐ%SÀIÐ%SÐ%SÐ%SˆO˜EÑ"õ Œ7�>Š>˜'Ñ"Ô"ð 	;¥r¤w§}¢}°WÑ'=Ô'=ð 	;ØLÐL¥2¤:¨gÑ#6Ô#6ÐLÑLÔLˆHÝ-0°©]¬]ˆO˜MÑ*àÐøÝð Zð Zð ZÝŒ
×ÒÐFÀÐFÐFÐFÑGÔGÐGÝŒ
×ÒÑÔÐÝ¨Ð4XÕPSÐTUÑPVÔPVÐ4XÐ4XÐYÑYÔYÐYøøøøðZøøøs   „FF Æ
G9ÆA"G4Ç4G9rÑ  c           
   ƒ   ó¨  ‡ ‡‡(‡)‡*‡+‡,‡-‡.K  — t           j                             d‰ › d�¦  «         t           j                             d‰› d�¦  «         t           j                             ¦   «          ddlŠ+d‰ › �Š,t          t          ¦   «         ¦  «        Š(	 t          j         	                    ‰¦  «        �rŒ‰ 
                    d¦  «        �rvt           j                             d¦  «         t           j                             ¦   «          t          j                             ‰¦  «        }t          ‰d	¦  «        5 }|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   g Š-|                     d¦  «        D ]t}|                     ¦   «         }|r\|                     d
¦  «        sG| 
                    d¦  «        r2‰-                     t          j                             |¦  «        ¦  «         Œu|Št           j                             dt'          ‰-¦  «        › d�¦  «         t           j                             ¦   «          �n3d„ t          j        ‰¦  «        D ¦   «         }t           j                             d‰› d�¦  «         t           j                             d‰ › d�¦  «         t           j                             dt'          |¦  «        › d�¦  «         t           j                             ¦   «          ˆ fd„|D ¦   «         }ˆ fd„|D ¦   «         }d„ |D ¦   «         }	t           j                             dt'          |¦  «        › d�¦  «         t           j                             dt'          |¦  «        › d�¦  «         t           j                             dt'          |	¦  «        › d�¦  «         t           j                             ¦   «          |r"|Š-t           j                             d¦  «         ni|r"|Š-t           j                             d¦  «         nE|	r"|	Š-t           j                             d¦  «         n!|Š-t           j                             d¦  «         t           j                             ¦   «          t           j                             dt'          ‰-¦  «        › d�¦  «         t           j                             ¦   «          ‰-s¤‰(                     t,          ¦  «                             t,          j        ‰ k    ¦  «                             ¦   «         }
|
r>d|
_        t7          j        t:          j        ¦  «        |
_        ‰(                      ¦   «          	 ‰( !                    ¦   «          dS d„ }‰- "                    |¬¦  «         tF          j$        }|d k    r‰-dd|…         Š-‰(                     t,          ¦  «                             t,          j        ‰ k    ¦  «                             ¦   «         }
|
r`t'          ‰-¦  «        |
_%        d|
_&        d!|
_'        d|
_        t7          j        t:          j        ¦  «        |
_        ‰(                      ¦   «          dŠ*tQ          j)        d"¦  «        Š.d#tT          d$tV          fˆ(ˆ*ˆˆ+ˆ,ˆ-ˆ.ˆ fd%„Š)ˆ)fd&„tY          ‰-¦  «        D ¦   «         }	 tQ          j-        |Ž ƒ d{V —† t           j                             d'‰*› d(t'          ‰-¦  «        › d�¦  «         t           j                             ¦   «          nl# t\          $ r_}t           j                             d)|› d�¦  «         t           j                             ¦   «          ddl/}| 0                    ¦   «          ‚ d}~ww xY wd*}d+„ t          j        ‰¦  «        D ¦   «         }d,„ }| "                    |¬¦  «         t'          |¦  «        }||z   d z
  |z  }|||d-d.d/d0œ}tc          |¦  «        D �]G}||z  }te          ||z   |¦  «        }|||…         }‰› d1|› �}t          j3        |d2¬3¦  «         tY          |d ¦  «        D ]]\  }}‰› d(|› �}|› d4|d5›d6�}t          j         4                    |¦  «        rt          j5        |¦  «         t          j6        ||¦  «         Œ^d-}te          |t'          |¦  «        ¦  «        } t'          |¦  «        | z   d z
  | z  }!‰› d7|d z   › d6�}"d8d9|› d:�d;d<| › d=|!› �d>d?d@|"g	}#tQ          j7        |#tP          j8        j9        tP          j8        j9        dAœŽƒ d{V —†}$|$ :                    ¦   «         ƒ d{V —†\  }%}&tw          j<        |d2¬B¦  «         |$j=        dk    rƒt           j                             dC|d z   › dD|& >                    ¦   «         › d�¦  «         t           j                             ¦   «          t          dE|d z   › dF|& >                    ¦   «         › �¦  «        ‚t           j                             dG|d z   › d(|› dD|"› d�¦  «         t           j                             ¦   «          �ŒI‰› dH�}'t          |'dI¦  «        5 } ‰+j@        ||¦  «         ddd¦  «         n# 1 swxY w Y   ‰(                     t,          ¦  «                             t,          j        ‰ k    ¦  «                             ¦   «         }
|
rmt'          ‰-¦  «        |
_&        t'          ‰-¦  «        |
_%        dJ|
_'        d|
_        t7          j        t:          j        ¦  «        |
_        ‰(                      ¦   «          �n	# t\          $ rü}t           j                             dK|› d�¦  «         t           j                             ¦   «          ‰(                     t,          ¦  «                             t,          j        ‰ k    ¦  «                             ¦   «         }
|
rbtW          |¦  «        |
_        dLtW          |¦  «        › �|
_'        t7          j        t:          j        ¦  «        |
_        ‰(                      ¦   «          Y d}~nd}~ww xY w‰( !                    ¦   «          dS # ‰( !                    ¦   «          w xY w)Mz;Background function to generate thumbnails and sprite sheetz6[THUMBNAILS] Starting thumbnail generation for stream rï   z[THUMBNAILS] HLS path: r   Nr¦  rm   z#[THUMBNAILS] Parsing m3u8 playlist
Úrú#r½  z[THUMBNAILS] Found z segments in m3u8 playlist
c                 óD   — g | ]}|                      d ¦  «        sd|v ¯|‘ŒS )r½  r¾  rã  rä  s     r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>š  s5   € ÐcÐcÐc !¸a¿jºjÈÑ>OÔ>OÐcÐS]ÐabÐSbÐSb˜AÐSbÐSbÐSbr>   z[THUMBNAILS] HLS directory: z[THUMBNAILS] Stream ID: z[THUMBNAILS] All TS files: c                 ón   •— g | ]1}|                      ‰› d �¦  «        ¯|                     d¦  «        ¯/|‘Œ2S )r¼  r½  ©ru   rs   ©r:   rÕ  r×   s     €r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>¢  sE   ø€ ÐkÐkÐk !°q·|²|ÀyÀOÀOÀOÑ7TÔ7TÐkÐYZ×YcÒYcÐdiÑYjÔYjÐk˜AÐkÐkÐkr>   c                 óD   •— g | ]}|                      ‰› d �¦  «        ¯|‘ŒS )r¾  ©ru   rð  s     €r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>£  s3   ø€ Ð_Ð_Ð_ Q¸!¿,º,È)ÐG]ÐG]ÐG]Ñ:^Ô:^Ð_˜qÐ_Ð_Ð_r>   c                 ó<   — g | ]}|                      d ¦  «        ¯|‘ŒS )Úsegment_rò  rä  s     r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>¤  s)   € ÐTÐTÐT a¸1¿<º<È
Ñ;SÔ;SÐT ÐTÐTÐTr>   z[THUMBNAILS] Standard HLS: z[THUMBNAILS] Twitch segments: z[THUMBNAILS] Segment segments: z0[THUMBNAILS] Using standard HLS format segments
z*[THUMBNAILS] Using Twitch format segments
z,[THUMBNAILS] Using standard segment_ format
z![THUMBNAILS] Using all .ts files
z segment files
zNo segments foundc                 ó¶  — dd l } |j        d| ¦  «        }|r"t          |                     d¦  «        ¦  «        S  |j        d| ¦  «        }|r"t          |                     d¦  «        ¦  «        S  |j        d| ¦  «        }|r"t          |                     d¦  «        ¦  «        S  |j        d| ¦  «        }|r"t          |                     d¦  «        ¦  «        S | S )Nr   z-(\d+)\.ts$rç   z
-Frag(\d+)zsegment[_-](\d+)z(\d+)©ÚreÚsearchr  Úgroup)r1  r÷  Ústandard_matchÚtwitch_matchÚsegment_matchÚnumeric_matchs         r<   Úextract_segment_numberz>generate_thumbnails_background.<locals>.extract_segment_numberÆ  só   € ØˆIˆIˆIà&˜RœY ~°xÑ@Ô@ˆNØð 4Ý˜>×/Ò/°Ñ2Ô2Ñ3Ô3Ð3à$˜2œ9 ]°HÑ=Ô=ˆLØð 2Ý˜<×-Ò-¨aÑ0Ô0Ñ1Ô1Ð1ð &˜BœIÐ&9¸8ÑDÔDˆMØð 3Ý˜=×.Ò.¨qÑ1Ô1Ñ2Ô2Ð2ð &˜BœI h°Ñ9Ô9ˆMØð 3Ý˜=×.Ò.¨qÑ1Ô1Ñ2Ô2Ð2ð ˆOr>   )Úkeyrç   zStarting thumbnail generationé   ÚirÒ  c              “   ó˜  •K  — ‰› d| dz   d›d�}t           j                             |¦  «        r²‰dz  Š‰                     t          ¦  «                             t          j        ‰k    ¦  «                             ¦   «         }|r\‰|_        d| dz   › dt          ‰¦  «        › d�|_
        t          j        t          j        ¦  «        |_        ‰                     ¦   «          d S ‰4 ƒd {V —† dd	‰› d
|› �ddddddddd|g}t#          j        |t"          j        j        t"          j        j        dœŽƒ d {V —†}|                     ¦   «         ƒ d {V —†\  }}|j        dk    r}t.          j                             d| dz   › d|                     ¦   «         › d�¦  «         t.          j                             ¦   «          t9          d|                     ¦   «         › �¦  «        ‚‰dz  Št          ‰¦  «        dk    rzd‰t          ‰¦  «        z  dz  z   }t;          t          ‰¦  «        ‰z
  dz  ¦  «        }	d|dd‰t          ‰¦  «        |	› d�d œd!œ}
t=          j        ‰d" ‰j         |
¦  «        ¦  «         ‰dk    s:‰t          ‰¦  «        k    s'‰tC          dt          ‰¦  «        dz  ¦  «        z  dk    rQt.          j                             d#‰› d
t          ‰¦  «        › d�¦  «         t.          j                             ¦   «          ‰                     t          ¦  «                             t          j        ‰k    ¦  «                             ¦   «         }|r[‰|_        d| dz   › dt          ‰¦  «        › �|_
        t          j        t          j        ¦  «        |_        ‰                     ¦   «          d d d ¦  «        ƒd {V —† d S # 1 ƒd {V —†swxY w Y   d S )$Nr¿  rç   rÀ  rÁ  zProcessing segment z of z (skipped, already exists)rÂ  rÃ  rn   rÄ  rÅ  rÆ  rÇ  rÈ  rÉ  z-threadsrÊ  ©Ústdoutró   r   z-[THUMBNAILS ERROR] FFmpeg failed for segment r  rï   z$FFmpeg thumbnail generation failed: é<   é
   g      à?r+  Úgenerating_thumbnailszGenerating thumbnailsr;   )Úcurrent_thumbnailÚtotal_thumbnailsÚeta)r   r�  ÚstepÚ	step_nameÚdetailsi  z![THUMBNAILS] Generated thumbnail )"r}   r~   r�   r“   r   r”   r5   rÞ   re   r´   rg   r*   r  r+   r  ri   rè   rN  Úcreate_subprocess_execrÏ  ÚPIPEÚcommunicateÚ
returncoderò   ró   rô   r�  r  rñ   r  r,   ÚsetexrA   Úmax)r  rÒ  rÓ  rQ   rÔ  Úprocessr  ró   r0   Úeta_secondsr¢  rŽ   Úgenerated_countrÑ  r@   r¡  Úsegment_filesÚ	semaphorer×   s              €€€€€€€€r<   Úgenerate_thumbnailz:generate_thumbnails_background.<locals>.generate_thumbnailó  sè  øè è € à 'Ð=Ð=°°!±Ð=Ð=Ð=Ð=ˆNõ Œw�~Š~˜nÑ-Ô-ð 	Ø 1Ñ$�àŸš¥&Ñ)Ô)×0Ò0µ´¸iÒ1GÑHÔH×NÒNÑPÔP�Øð  Ø:I�FÔ7ð 9HÈaÐRSÉeð  9Hð  9HÕY\Ð]jÑYkÔYkð  9Hð  9Hð  9H�FÔ5Ý;C¼<ÍÌÑ;UÔ;U�FÔ8Ø—I’I‘K”K�KØ�à ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð Ø˜WÐ5Ð5 |Ð5Ð5Ø Ø˜CØ˜tØ ØØ"ð	�õ !(Ô >ÀÍGÔL^ÔLcÕlsÔl~ô  mDð  !Eð  !Eð  !Eð  Eð  Eð  Eð  Eð  Eð  E�Ø'.×':Ò':Ñ'<Ô'<Ð!<Ð!<Ð!<Ð!<Ð!<Ð!<‘�˜ØÔ%¨Ò*Ð*Ý”J×$Ò$Ð%oÐUVÐWXÑUXÐ%oÐ%oÐ\b×\iÒ\iÑ\kÔ\kÐ%oÐ%oÐ%oÑpÔpÐpÝ”J×$Ò$Ñ&Ô&Ð&Ý#Ð$\È6Ï=Ê=É?Ì?Ð$\Ð$\Ñ]Ô]Ð]Ø 1Ñ$�õ �}Ñ%Ô%¨Ò)Ð)Ø)+¨ÅÀ]ÑASÔASÑ/SÐVXÑ/XÑ)YÐ&Ý"%¥s¨=Ñ'9Ô'9¸OÑ'KÈsÑ&RÑ"SÔ"S�Kà".Ø&8Ø 7Ø%<à1@Ý03°MÑ0BÔ0BØ&1Ð#4Ð#4Ð#4ð$ð $ð
%ð 
%�Mõ !Ô& |°T¸:¸4¼:ÀmÑ;TÔ;TÑUÔUÐUð # aÒ'Ð'¨?½cÀ-Ñ>PÔ>PÒ+PÐ+PÐUdÕgjÐklÕnqÐrñ  oAô  oAð  EGñ  oGñ  hHô  hHñ  VHð  LMò  VMð  VMÝ”J×$Ò$Ð%qÈÐ%qÐ%qÕ[^Ð_lÑ[mÔ[mÐ%qÐ%qÐ%qÑrÔrÐrÝ”J×$Ò$Ñ&Ô&Ð&ð Ÿš¥&Ñ)Ô)×0Ò0µ´¸iÒ1GÑHÔH×NÒNÑPÔP�Øð  Ø:I�FÔ7Ø8mÈaÐRSÉeÐ8mÐ8mÕY\Ð]jÑYkÔYkÐ8mÐ8m�FÔ5Ý;C¼<ÍÌÑ;UÔ;U�FÔ8Ø—I’I‘K”K�Kða0 ð 0 ð 0 ñ 0 ô 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 øøøð 0 ð 0 ð 0 ð 0 ð 0 ð 0 s   Ã)J=N9Î9
OÏOc                 ó.   •— g | ]\  }} ‰||¦  «        ‘ŒS rœ   rœ   )r:   r  rÒ  r  s      €r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>6  s+   ø€ ÐeÐeÐe¹¸¸LÐ#Ð# A |Ñ4Ô4ÐeÐeÐer>   z-[THUMBNAILS] Completed thumbnail generation: rn   z2[THUMBNAILS ERROR] Failed to generate thumbnails: iÐ  c                 óf   — g | ].}|                      d ¦  «        ¯|                     d¦  «        ¯,|‘Œ/S )Úthumb_rÁ  rï  rä  s     r<   r=   z2generate_thumbnails_background.<locals>.<listcomp>E  s>   € ÐkÐkÐk ¸Q¿\º\È(Ñ=SÔ=SÐkÐXY×XbÒXbÐciÑXjÔXjÐk˜1ÐkÐkÐkr>   c                 óx   — t          j        d| ¦  «        }|r"t          |                     d¦  «        ¦  «        ndS )Nzthumb_(\d+)\.jpgrç   r   rö  )r1  Úmatchs     r<   Úextract_thumb_numberz<generate_thumbnails_background.<locals>.extract_thumb_numberG  s6   € Ý”IÐ1°8Ñ<Ô<ˆEØ*/Ð6•3�u—{’{ 1‘~”~Ñ&Ô&Ð&°QÐ6r>   r‹   é    éZ   )Úsprite_countr	  Úthumbnails_per_spriteÚcolumnsÚthumbnail_widthÚthumbnail_heightz/sprite_chunk_Tr'  r¿  rÀ  rÁ  z/thumbnails_sprite_rÂ  rÃ  z/thumb_%03d.jpgz-vfzscale=160:90,tile=ÚxrÆ  rÇ  rÊ  r  r  z3[THUMBNAILS ERROR] Failed to generate sprite sheet r  zSprite sheet z generation failed: z$[THUMBNAILS] Generated sprite sheet z/thumbnails_sprite.jsonÚwzThumbnail generation completedz>[THUMBNAILS ERROR] Error generating thumbnails in background: zError: )Arò   ró   rô   r  r@   Únextr   r}   r~   Úisfilers   Údirnamer3  r�  r2  rÅ   ru   rÊ   Úbasenamer´   rå  r“   r   r”   r5   rÞ   rh   r*   r  r+   r  ri   rè   rS  Úsortr%   ÚTHUMBNAIL_SAMPLING_RATErf   re   rg   rN  Ú	Semaphorer  r7   Ú	enumerateÚgatherrñ   r°  r±  Úranger³   r/  r�   r  Úlinkr  rÏ  r  r  r  r  r  r�  rf  Údump)/r×   rÑ  Úm3u8_dirrÕ  Úm3u8_contentÚlineÚall_ts_filesÚstandard_hlsÚtwitch_segmentsÚsegment_segmentsrQ   rþ  Úsampling_rateÚtasksrö   r°  ÚMAX_THUMBNAILS_PER_SPRITEÚexisting_thumbsr  Útotal_thumbsr"  Úsprite_metaÚ
sprite_idxÚ	start_idxÚend_idxÚchunk_thumbsÚ	chunk_dirr  Ú
thumb_fileÚsrcÚdstÚmax_columnsr$  ÚrowsÚsprite_pathrÔ  r  r  ró   Ú	meta_pathrŽ   r  r  r@   r¡  r  r  s/   ``                                      @@@@@@@r<   Úgenerate_thumbnails_backgroundrN  q  s  øøøøøøøøøè è € å„J×ÒÐ[ÈiÐ[Ð[Ð[Ñ\Ô\Ð\Ý„J×ÒÐ:¨wÐ:Ð:Ð:Ñ;Ô;Ð;Ý„J×ÒÑÔÐà€K€K€KØ1 iÐ1Ð1€Lå	�f‰hŒh‰Œ€BðgåŒ7�>Š>˜'Ñ"Ô"ñ ;	 w×'7Ò'7¸Ñ'@Ô'@ñ ;	åŒJ×ÒÐDÑEÔEÐEÝŒJ×ÒÑÔÐõ ”w—’ wÑ/Ô/ˆHõ �g˜sÑ#Ô#ð ( qØ Ÿvšv™xœx�ð(ð (ð (ñ (ô (ð (ð (ð (ð (ð (ð (øøøð (ð (ð (ð (ð ˆMØ$×*Ò*¨4Ñ0Ô0ð Að A�Ø—z’z‘|”|�Øð A §¢°Ñ 4Ô 4ð A¸¿ºÀuÑ9MÔ9Mð AØ!×(Ò(­¬×)9Ò)9¸$Ñ)?Ô)?Ñ@Ô@Ð@øð ˆGÝŒJ×ÒÐcµ3°}Ñ3EÔ3EÐcÐcÐcÑdÔdÐdÝŒJ×ÒÑÔÐÑð dÐc¥r¤z°'Ñ':Ô':ÐcÑcÔcˆLåŒJ×ÒÐG¸GÐGÐGÐGÑHÔHÐHÝŒJ×ÒÐE¸	ÐEÐEÐEÑFÔFÐFÝŒJ×ÒÐP½3¸|Ñ;LÔ;LÐPÐPÐPÑQÔQÐQÝŒJ×ÒÑÔÐð lÐkÐkÐk |ÐkÑkÔkˆLØ_Ð_Ð_Ð_¨,Ð_Ñ_Ô_ˆOØTÐT¨<ÐTÑTÔTÐåŒJ×ÒÐP½3¸|Ñ;LÔ;LÐPÐPÐPÑQÔQÐQÝŒJ×ÒÐV½cÀ/Ñ>RÔ>RÐVÐVÐVÑWÔWÐWÝŒJ×ÒÐX½sÐCSÑ?TÔ?TÐXÐXÐXÑYÔYÐYÝŒJ×ÒÑÔÐð ð HØ ,�Ý”
× Ò Ð!UÑVÔVÐVÐVØ ð HØ /�Ý”
× Ò Ð!OÑPÔPÐPÐPØ!ð HØ 0�Ý”
× Ò Ð!QÑRÔRÐRÐRà ,�Ý”
× Ò Ð!FÑGÔGÐGÝŒJ×ÒÑÔÐåŒ
×ÒÐS­s°=Ñ/AÔ/AÐSÐSÐSÑTÔTÐTÝŒ
×ÒÑÔÐàð 	Ø—X’X�fÑ%Ô%×,Ò,­V¬Y¸)Ò-CÑDÔD×JÒJÑLÔLˆFØð Ø2E�Ô/Ý7?´|ÅHÄLÑ7QÔ7Q�Ô4Ø—	’	‘”�Øð~ 	�Š‰
Œ
ˆ
ˆ
ˆ
ðy	ð 	ð 	ð0 	×ÒÐ5ÐÑ6Ô6Ð6õ !Ô8ˆØ˜1ÒÐØ)¨/¨/¨M¨/Ô:ˆMð —’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	Ý.1°-Ñ.@Ô.@ˆFÔ+Ø23ˆFÔ/Ø0OˆFÔ-Ø.2ˆFÔ+Ý3;´<ÅÄÑ3MÔ3MˆFÔ0Ø�IŠI‰KŒKˆKàˆÝÔ% aÑ(Ô(ˆ	ð@	 ­ð @	 ½3ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ð @	 ðF fÐeÐeÐeÍIÐVcÑLdÔLdÐeÑeÔeˆð		Ý”. %Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(ÝŒJ×ÒÐuÈ_ÐuÐuÕ_bÐcpÑ_qÔ_qÐuÐuÐuÑvÔvÐvÝŒJ×ÒÑÔÐÐøÝð 	ð 	ð 	ÝŒJ×ÒÐWÐRSÐWÐWÐWÑXÔXÐXÝŒJ×ÒÑÔÐØÐÐÐØ×ÒÑ!Ô!Ð!Øøøøøð	øøøð %)Ð!àkÐk¥b¤j°Ñ&9Ô&9ÐkÑkÔkˆð	7ð 	7ð 	7ð 	×ÒÐ!5ÐÑ6Ô6Ð6å˜?Ñ+Ô+ˆØ$Ð'@Ñ@À1ÑDÐIbÑbˆð )Ø ,Ø%>ØØ"Ø "ð
ð 
ˆõ   Ñ-Ô-ð -	ñ -	ˆJØ"Ð%>Ñ>ˆIÝ˜)Ð&?Ñ?ÀÑNÔNˆGØ*¨9°WÐ+<Ô=ˆLð #Ð>Ð>°*Ð>Ð>ˆIÝŒK˜	¨DÐ1Ñ1Ô1Ð1õ "+¨<¸Ñ!;Ô!;ð "ð "‘��:Ø Ð/Ð/ :Ð/Ð/�Ø"Ð6Ð6¨1Ð6Ð6Ð6Ð6�Ý”7—>’> #Ñ&Ô&ð #Ý”I˜c‘N”N�NÝ”˜˜SÑ!Ô!Ð!Ð!ð ˆKÝ˜+¥s¨<Ñ'8Ô'8Ñ9Ô9ˆGÝ˜Ñ%Ô%¨Ñ/°!Ñ3¸Ñ?ˆDð %ÐMÐM¸Àa¹ÐMÐMÐMˆKð Ø˜Ð3Ð3Ð3ØÐ<¨GÐ<Ð<°dÐ<Ð<Ø˜ØØðˆCõ $Ô:¸CÍÔHZÔH_ÕhoÔhzÔhð  Að  Að  Að  Að  Að  Að  Að  Að  AˆGØ#*×#6Ò#6Ñ#8Ô#8Ð8Ð8Ð8Ð8Ð8Ð8‰NˆF�Fõ ŒM˜)°4Ð8Ñ8Ô8Ð8àÔ! QÒ&Ð&Ý”
× Ò Ð!|ÐWaÐdeÑWeÐ!|Ð!|Ðio×ivÒivÑixÔixÐ!|Ð!|Ð!|Ñ}Ô}Ð}Ý”
× Ò Ñ"Ô"Ð"Ý"Ð#h°:À±>Ð#hÐ#hÐW]×WdÒWdÑWfÔWfÐ#hÐ#hÑiÔiÐiåŒJ×ÒÐtÀJÐQRÁNÐtÐtÐUaÐtÐtÐepÐtÐtÐtÑuÔuÐuÝŒJ×ÒÑÔÐÑð Ð7Ð7Ð7ˆ	Ý�)˜SÑ!Ô!ð 	& QØˆDŒI�k 1Ñ%Ô%Ð%ð	&ð 	&ð 	&ñ 	&ô 	&ð 	&ð 	&ð 	&ð 	&ð 	&ð 	&øøøð 	&ð 	&ð 	&ð 	&ð —’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	Ý25°mÑ2DÔ2DˆFÔ/Ý.1°-Ñ.@Ô.@ˆFÔ+Ø0PˆFÔ-Ø.2ˆFÔ+Ý3;´<ÅÄÑ3MÔ3MˆFÔ0Ø�IŠI‰KŒKˆKùøåð 	ð 	ð 	ÝŒ
×ÒÐ_ÐZ[Ð_Ð_Ð_Ñ`Ô`Ð`ÝŒ
×ÒÑÔÐà—’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	Ý.1°!©f¬fˆFÔ+Ø0B½#¸a¹&¼&Ð0BÐ0BˆFÔ-Ý3;´<ÅÄÑ3MÔ3MˆFÔ0Ø�IŠI‰KŒKˆKøøøøøøøøøð	øøøð 	�Š‰
Œ
ˆ
ˆ
ˆ
øˆ�Š‰
Œ
ˆ
ˆ
øøøsª   ÂB"l Ä7EÅl ÅEÅl ÅEÅ O1l Õ(D1l ÚA%\  Û?l Ü 
])Ü
A]$Ý$])Ý)Kl è5iél éiél éiéB?l ìp; ì
p"ì&C2pðp; ðp"ð"p; ð;qz /{stream_id}/generate-thumbnailsc              ƒ   ó  ‡ ‡K  — 	 |                      t          ¦  «                             t          j        ‰ k    ¦  «                             ¦   «         }|st          dd¬¦  «        ‚	 |                     ¦   «         ƒ d{V —†}|                     d¦  «        }n	#  d}Y nxY w|r|                     d¦  «        r|t          d¦  «        d…         }t          j        › |› �Št          j                             d‰› d�¦  «         t          j                             ¦   «          �n`|j        r…|j        }|                     d¦  «        r|t          d¦  «        d…         }t          j        › |› �Št          j                             d	‰› d�¦  «         t          j                             ¦   «          nÔt          j        › d
‰ › �Št"          j                             ‰‰ › d�¦  «        }	t"          j                             |	¦  «        rD|	Št          j                             d‰› d�¦  «         t          j                             ¦   «          n=t          j                             d¦  «         t          j                             ¦   «          |sS|j        rL|j        dk    rAt/          j        t2          j        ¦  «        |j        z
                       ¦   «         dk     rd‰ dœS |rxd|_        d|_        d|_        d|_        d|_        |                     ¦   «          t          j                             d‰ › d�¦  «         t          j                             ¦   «          ˆˆ fd„}
tA          j!        |
¬¦  «        }d|_"        | #                    ¦   «          d‰ dœS # t
          $ r ‚ tH          $ rg}t          j                             d|› d�¦  «         t          j                             ¦   «          t          ddtK          |¦  «        › �¬¦  «        ‚d}~ww xY w)zFGenerate all thumbnails for a stream (admin only) - runs in backgroundrª  rÙ   rÚ   NrY   r’   z$[THUMBNAILS] Using custom HLS path: rï   z)[THUMBNAILS] Using HLS path from stream: r»  rm   z"[THUMBNAILS] Using m3u8 playlist: zG[THUMBNAILS] No m3u8 playlist found, using directory with .ts segments
r   i,  zDThumbnail generation already in progress. Use force=true to restart.r´  zForced restartz&[THUMBNAILS] Force restart for stream z - progress reset
c                  óL   •— t          j        t          ‰‰ ¦  «        ¦  «         d S )N)rN  rÐ  rN  )rÑ  r×   s   €€r<   Ú	run_asyncz&generate_thumbnails.<locals>.run_asyncñ  s$   ø€ ÝŒKÕ6°yÀ'ÑJÔJÑKÔKÐKÐKÐKr>   rY  Tz*Thumbnail generation started in backgroundz0[THUMBNAILS ERROR] Error generating thumbnails: rŒ  zFailed to generate thumbnails: )&r“   r   r”   r5   rÞ   r   r@   rM   ru   r´   r%   r†   rò   ró   rô   r  rY   r}   r~   r€   r�   ri   rf   r*   r  r+   r  Útotal_secondsre   rh   rg   rè   ra  rb  rc  rd  rñ   r7   )r×   rH   r¨  rŽ   r�   rQ   ÚbodyÚcustom_hls_pathrY   r‚   rQ  ro  rö   rÑ  s   `            @r<   Úgenerate_thumbnailsrU  ¥  s?  øøè è € ðR`à—’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	LÝ¨CÐ8JÐKÑKÔKÐKð	#Ø Ÿš™œÐ'Ð'Ð'Ð'Ð'Ð'ˆDØ"Ÿhšh zÑ2Ô2ˆOˆOøð	#Ø"ˆOˆOˆOøøøð ð 	'ð ×)Ò)¨*Ñ5Ô5ð DØ"1µ#°j±/´/Ð2BÐ2BÔ"C�Ý!Ô-Ð@¨Ð@Ð@ˆGÝŒJ×ÒÐOÀGÐOÐOÐOÑPÔPÐPÝŒJ×ÒÑÔÐÑð Œð 'Ø!œ?�à×&Ò& zÑ2Ô2ð :Ø'­¨J©¬Ð(8Ð(8Ô9�HÝ%Ô1Ð=°8Ð=Ð=�Ý”
× Ò Ð!XÈWÐ!XÐ!XÐ!XÑYÔYÐYÝ”
× Ò Ñ"Ô"Ð"Ð"õ &Ô1ÐFÐF¸9ÐFÐF�õ œGŸLšL¨°YÐ2EÐ2EÐ2EÑFÔF�	Ý”7—>’> )Ñ,Ô,ð 'Ø'�GÝ”J×$Ò$Ð%UÈ'Ð%UÐ%UÐ%UÑVÔVÐVÝ”J×$Ò$Ñ&Ô&Ð&Ð&å”J×$Ò$Ð%pÑqÔqÐqÝ”J×$Ò$Ñ&Ô&Ð&ð ð 	˜Ô=ð 	À&ÔBaÐdeÒBeÐBeå”�Xœ\Ñ*Ô*¨VÔ-QÑQ×`Ò`ÑbÔbÐehÒhÐhàeØ!*ðð ð ð ð 	Ø23ˆFÔ/Ø./ˆFÔ+Ø.2ˆFÔ+Ø0@ˆFÔ-Ø37ˆFÔ0Ø�IŠI‰KŒKˆKÝŒJ×ÒÐdÀiÐdÐdÐdÑeÔeÐeÝŒJ×ÒÑÔÐð	Lð 	Lð 	Lð 	Lð 	Lð 	LåÔ!¨Ð3Ñ3Ô3ˆØˆŒØ�Š‰Œˆð DØ"ð
ð 
ð 	
øõ ð ð ð ØÝð `ð `ð `ÝŒ
×ÒÐQÈAÐQÐQÐQÑRÔRÐRÝŒ
×ÒÑÔÐÝ¨Ð4^ÕVYÐZ[ÑV\ÔV\Ð4^Ð4^Ð_Ñ_Ô_Ð_øøøøð`øøøs9   †A N Á'/B ÂN ÂBÂH:N ËB4N ÎPÎA"PÐPz/{stream_id}/thumbnailc              ƒ   óœ  K  — 	 |                      ¦   «         ƒ d{V —†}|                     d¦  «        }|€t          dd¬¦  «        ‚|                     t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          dd¬¦  «        ‚|j        st          dd¬¦  «        ‚d	d
l	m
}  |¦   «         }|j        }	|	                     d¦  «        rd|	› �}	t          j        › d| › d�}
|                     |	t          |¦  «        |
¬¦  «        }t!          t#          j        t&          j        ¦  «                             ¦   «         ¦  «        }d| › d|› �|_        t#          j        t&          j        ¦  «        |_        |                     ¦   «          	 t3          j        d| › �¦  «         n#  Y nxY wd|j        iS # t          $ r ‚ t6          $ rg}t8          j                             d|› d�¦  «         t8          j                             ¦   «          t          ddtA          |¦  «        › �¬¦  «        ‚d}~ww xY w)z5Generate a single thumbnail from a specific timestampNr  rŠ  zTimestamp is requiredrÚ   rª  rÙ   zStream has no HLS pathr   ©ÚThumbnailServicern   z/appú/thumbnails/rÁ  ©Ú
video_pathÚtimestamp_secondsrW  rý   rþ   ústream:rX   z=[THUMBNAIL ERROR] Error generating thumbnail from timestamp: rï   rŒ  rÎ  )!r@   rM   r   r“   r   r”   r5   rÞ   rY   Úservices.thumbnail_servicerX  ru   r%   r†   Ú!generate_thumbnail_from_timestampÚfloatr  r*   r  r+   r  r  rX   r  rè   r,   r  rñ   rò   ró   rô   r  r7   )r×   rH   rŽ   r�   rS  r  rQ   rX  Úthumbnail_servicerY   rW  rÓ  Útimestamp_paramrö   s                 r<   Úgenerate_single_thumbnailrc    s�  è è € ð5_à—\’\‘^”^Ð#Ð#Ð#Ð#Ð#Ð#ˆØ—H’H˜[Ñ)Ô)ˆ	àÐÝ¨CÐ8OÐPÑPÔPÐPð —’�&Ñ!Ô!×(Ò(­¬°iÒ)?Ñ@Ô@×FÒFÑHÔHˆØð 	LÝ¨CÐ8JÐKÑKÔKÐKàŒð 	RÝ¨CÐ8PÐQÑQÔQÐQð 	BÐAÐAÐAÐAÐAØ,Ð,Ñ.Ô.Ðð ”?ˆØ×Ò˜sÑ#Ô#ð 	)Ø(˜hÐ(Ð(ˆHõ "Ô-ÐJÐJ¸9ÐJÐJÐJˆØ*×LÒLØÝ# IÑ.Ô.Ø#ð Mñ 
ô 
ˆõ �hœl­8¬<Ñ8Ô8×BÒBÑDÔDÑEÔEˆØY°iÐYÐYÈÐYÐYˆÔÝ&.¤lµ8´<Ñ&@Ô&@ˆÔ#Ø
�	Š	‰Œˆð	ÝÔÐ 5¨)Ð 5Ð 5Ñ6Ô6Ð6Ð6øð	ØˆDøøøà Ô!5Ð6Ð6øåð ð ð ØÝð _ð _ð _ÝŒ
×ÒÐ^ÐYZÐ^Ð^Ð^Ñ_Ô_Ð_ÝŒ
×ÒÑÔÐÝ¨Ð4]ÕUXÐYZÑU[ÔU[Ð4]Ð4]Ð^Ñ^Ô^Ð^øøøøð_øøøs1   „F#G Æ(G  Æ?G Ç GÇG ÇIÇ$A"IÉIz/{stream_id}/thumbnail-uploadc              ƒ   ó  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        j	        dk    r+|j
        |j        k    rt          t          j        d¬¦  «        ‚	 t          j        t          j        › d�d¬¦  «         t          j        › d| › d	�}t!          |d
¦  «        5 }t#          j        |j        |¦  «         ddd¦  «         n# 1 swxY w Y   t)          t+          j        t.          j        ¦  «                             ¦   «         ¦  «        }d| › d|› �|_        t+          j        t.          j        ¦  «        |_        |                     ¦   «          	 t;          j        d| › �¦  «         n#  Y nxY wd|j        iS # t>          $ r0}t          t          j         dtC          |¦  «        › �¬¦  «        ‚d}~ww xY w)z(Upload a client-side generated thumbnailrÙ   rÚ   rú   rÝ   z/thumbnailsTr'  rY  rÁ  r*  Nrý   rþ   r]  rX   zFailed to upload thumbnail: )"r“   r   r”   r5   rÞ   r   r   rß   rá   râ   rU   rã   r}   r/  r%   r†   r3  r  r4  r%  r  r*   r  r+   r  r  rX   r  rè   r,   r  rñ   rg  r7   )	r×   r%  rŽ   r�   rQ   rW  r6  rb  rö   s	            r<   Úupload_stream_thumbnailre  C  sG  è è € ð �XŠX•fÑÔ×$Ò$¥V¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔD€Fàð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔ Ò*Ð*¨vÔ/@ÀLÄOÒ/SÐ/SÝÝÔ1Ø"ð
ñ 
ô 
ð 	
ð

å
Œ•xÔ+Ð8Ð8Ð8À4ÐHÑHÔHÐHå!Ô-ÐJÐJ¸9ÐJÐJÐJˆõ �+˜tÑ$Ô$ð 	2¨ÝÔ˜tœy¨&Ñ1Ô1Ð1ð	2ð 	2ð 	2ñ 	2ô 	2ð 	2ð 	2ð 	2ð 	2ð 	2ð 	2øøøð 	2ð 	2ð 	2ð 	2õ �hœl­8¬<Ñ8Ô8×BÒBÑDÔDÑEÔEˆØY°iÐYÐYÈÐYÐYˆÔÝ&.¤lµ8´<Ñ&@Ô&@ˆÔ#Ø
�	Š	‰Œˆð	ÝÔÐ 5¨)Ð 5Ð 5Ñ6Ô6Ð6Ð6øð	ØˆDøøøà Ô!5Ð6Ð6øåð 
ð 
ð 
ÝÝÔ=Ø:µ#°a±&´&Ð:Ð:ð
ñ 
ô 
ð 	
øøøøð
øøøsV   Â)AG
 Ã.DÄ	G
 ÄDÄG
 ÄDÄBG
 Æ"F: Æ9G
 Æ:F>Æ<G
 Ç

HÇ+G?Ç?Hz/manualÚthumbnail_timestampr`   c              ƒ   óB  K  — 	 |}|sd}	�n|j         j        dk    rt          dd¬¦  «        ‚t          j                             |¦  «        s¨t          j                             d|                     d¦  «        ¦  «        t          j                             d|                     d¦  «        ¦  «        |g}
|
D ]%}t          j                             |¦  «        r|} nŒ&t          d	d
|› d|
› d�¬¦  «        ‚n3t          j                             |¦  «        st          d	d
|› �¬¦  «        ‚d}|�r8	 | 	                    ¦   «         ƒ d{V —†}t          j        |                     d¦  «        ¦  «        }t          |¦  «        }|                     |¦  «        }| s|                     d¦  «        r|d         } |s|                     d¦  «        r|d         }n“# t          j        $ r t          d	d¬¦  «        ‚t"          $ rg}t$          j                             d|› d�¦  «         t$          j                             ¦   «          t          d	dt-          |¦  «        › �¬¦  «        ‚d}~ww xY w| sd} t          |¦  «        }|                     |j        |sdn||pi ||d¬¦  «        }|�sðd|j        › �}	t          j        |	d¬¦  «         d|j        › �|_        d|_        |                     ¦   «          |                     |¦  «         	 ddlm}  |¦   «          n:# t"          $ r-}t$          j                             d|› d�¦  «         Y d}~nd}~ww xY wd}|�rO|                     d¦  «        �r9	 |                     d¦  «        }d |› d!�}tA          j        |d"¬#¦  «        }|j!        d$k    rÁt          j                             |	d%¦  «        }tE          |d&¦  «        5 }|                     |j#        ¦  «         ddd¦  «         n# 1 swxY w Y   tH          j%        rd'tH          j%        › d|j        › d(�n
d|j        › d(�|_&        d}|                     ¦   «          |                     |¦  «         n:# t"          $ r-}t$          j                             d)|› d�¦  «         Y d}~nd}~ww xY w|sï	 d*}t          j                             |	d+¦  «        }t          j                             |¦  «        rrtO          j(        ||¦  «         tH          j%        rd'tH          j%        › d|j        › d,�n
d|j        › d,�|_&        |                     ¦   «          |                     |¦  «         n:# t"          $ r-}t$          j                             d-|› d�¦  «         Y d}~nd}~ww xY w|�rK	 |                     d.¦  «        |                     d/¦  «        |                     d0¦  «        |                     d1¦  «        d2œ}||_)        |                     ¦   «          |                     d1¦  «        r"| *                    |j        |d1         ¬3¦  «         |                     d4¦  «        r7| +                    |j        |d4         |                     d5i ¦  «        ¬6¦  «         nX# t"          $ rK}t$          j                             d7|› d�¦  «         t$          j                             ¦   «          Y d}~nd}~ww xY w|�rD|j        �r<	 dd8l,m-}  |¦   «         }| .                    |j        |tH          j/        › d9|j        › d:�¬;¦  «        }tH          j%        rd'tH          j%        › d<|j        › d:�n
d<|j        › d:�|_&        |                     ¦   «          ta          j1        d=|j        › �¦  «         ta          j1        d>¦  «         ta          j1        d?¦  «         ta          j1        d@¦  «         nX# t"          $ rK}t$          j                             dA|› d�¦  «         t$          j                             ¦   «          Y d}~nd}~ww xY wte          |j        ¦  «        |_3        ti          |¦  «        |_5        |j&        rH|j&         6                    dB¦  «        s.tH          j%        rd'tH          j%        › |j&        › �n|j&        |_&        |S # t          $ r ‚ t"          $ rg}t$          j                             dC|› d�¦  «         t$          j                             ¦   «          t          dDdEt-          |¦  «        › �¬¦  «        ‚d}~ww xY w)FzGCreate a stream manually without upload, optionally with chat.json dataNrÜ   i“  z'Only admins can specify custom HLS pathrÚ   z/app/storagern   r‘   rŠ  zHLS path does not exist: z	 (tried: ú)r  rS   rT   r‹  z/[MANUAL IMPORT ERROR] Error parsing chat.json: rï   zError parsing chat.json: zManual StreamF)Úuser_idrY   r˜  rf  r`   Úis_twitch_importz/app/uploads/videos/Tr'  rá  rz   r   rÿ   z;[FFCONCAT ERROR] Failed to regenerate after manual import: Úvideo_idz4https://static-cdn.jtvnw.net/cf_vods/d2nvs3xx597ldy/z/thumb/thumb-640-360.jpgr  )ÚtimeoutéÈ   zthumbnail.jpgr*  rp   z/thumbnail.jpgz3[MANUAL IMPORT ERROR] Error downloading thumbnail: z%/app/app/static/default_thumbnail.svgzthumbnail.svgz/thumbnail.svgz7[MANUAL IMPORT ERROR] Error copying default thumbnail: rÁ   r€  r�  rÃ   r‚  rƒ  r…  r‡  rˆ  z1[MANUAL IMPORT ERROR] Error importing chat data: rW  rY  rÁ  rZ  rý   r]  zstreams:latestzstreams:popularzstreams:randomz2[MANUAL IMPORT ERROR] Error generating thumbnail: ro   z4[MANUAL IMPORT ERROR] Error creating manual stream: rŒ  z Failed to create manual stream: )7rá   râ   r   r}   r~   Úisabsr€   Úlstripr�   r�  r@   rŽ  r�  r)   r�  rM   r”  rñ   rò   ró   rô   r  r7   Úcreate_stream_from_chat_jsonr5   r/  rY   r   rè   ré   r  r   ÚrequestsrK   r3  r¡   r%   rv   rX   r  Úcopyrd   r‘  r“  r^  rX  r_  r†   r,   r  rx   rZ   rƒ   r[   ru   )rS   rT   rY   rf  r`   r}  rŽ   r�   Úresolved_pathrÑ  Úpossible_pathsr~   r˜  r•  r–  r—  rö   rQ   r   Úthumbnail_downloadedrk  Útwitch_thumbnail_urlrª   rÓ  rÕ  Údefault_thumbnail_pathÚthumbnail_destrÒ   rX  ra  s                                 r<   Úcreate_manual_streamry  y  sS  è è € ð{aà ˆØð 	dàˆG‰Gð Ô Ô%¨Ò0Ð0Ý#°Ð<eÐfÑfÔfÐfõ ”7—=’= Ñ*Ô*ð dõ ”G—L’L °·²ÀÑ1EÔ1EÑFÔFÝ”G—L’L °·²ÀÑ1EÔ1EÑFÔFØð"�ð
 +ð Bð B�DÝ”w—~’~ dÑ+Ô+ð Ø(,˜Ø˜ðõ (°Cð  AAÐ\dð  AAð  AAÐo}ð  AAð  AAð  AAð  Bñ  Bô  Bð  Bð õ ”W—^’^ HÑ-Ô-ð dÝ#°Ð<bÐX`Ð<bÐ<bÐcÑcÔcÐcð ˆØñ 	bðbØ*8×*=Ò*=Ñ*?Ô*?Ð$?Ð$?Ð$?Ð$?Ð$?Ð$?Ð!Ý!%¤Ð,=×,DÒ,DÀWÑ,MÔ,MÑ!NÔ!N�å$3°BÑ$7Ô$7Ð!Ø/×?Ò?ÀÑOÔO�ð ð 1 §¢°Ñ!9Ô!9ð 1Ø'¨Ô0�EØ"ð = {§¢°}Ñ'EÔ'Eð =Ø"-¨mÔ"<�KøøÝÔ'ð Vð Vð VÝ#°Ð<TÐUÑUÔUÐUÝð bð bð bÝ”
× Ò Ð!XÐSTÐ!XÐ!XÐ!XÑYÔYÐYÝ”
× Ò Ñ"Ô"Ð"Ý#°Ð<`ÕX[Ð\]ÑX^ÔX^Ð<`Ð<`ÐaÑaÔaÐaøøøøðbøøøð ð 	$Ø#ˆEõ ,¨BÑ/Ô/ÐØ"×?Ò?Ø ”OØ!)Ð<�T�T¨}Ø#Ð) rØ 3ØØ"ð @ñ 
ô 
ˆð ñ .	fØ8¨V¬YÐ8Ð8ˆGÝŒK˜¨$Ð/Ñ/Ô/Ð/à<°´Ð<Ð<ˆFŒOØ#ˆFŒMØ�IŠI‰KŒKˆKØ�JŠJ�vÑÔÐðfØRÐRÐRÐRÐRÐRØ*Ð*Ñ,Ô,Ð,Ð,øÝð fð fð fÝ”
× Ò Ð!dÐ_`Ð!dÐ!dÐ!dÑeÔeÐeÐeÐeÐeÐeÐeøøøøðføøøð $)Ð Øñ b˜{Ÿš¨zÑ:Ô:ñ bðbØ*Ÿš¨zÑ:Ô:�Hð ,EÐbjð  ,Eð  ,Eð  ,EÐ(Ý'œ|Ð,@È"ÐMÑMÔM�HØÔ+¨sÒ2Ð2Ý)+¬¯ª°g¸Ñ)OÔ)O˜Ý! .°$Ñ7Ô7ð 6¸1ØŸGšG HÔ$4Ñ5Ô5Ð5ð6ð 6ð 6ñ 6ô 6ð 6ð 6ð 6ð 6ð 6ð 6øøøð 6ð 6ð 6ð 6õ yAô  yHð  0zÐ/t½(¼/Ð/tÐ/tÐ[aÔ[dÐ/tÐ/tÐ/tÐ/tð  Nzð  agô  ajð  Nzð  Nzð  Nz˜Ô,Ø/3Ð,ØŸ	š	™œ˜ØŸ
š
 6Ñ*Ô*Ð*øøÝ ð bð bð bÝ”J×$Ò$Ð%`Ð[\Ð%`Ð%`Ð%`ÑaÔaÐaÐaÐaÐaÐaÐaøøøøðbøøøð (ð 
fð	fØ-TÐ*Ý%'¤W§\¢\°'¸?Ñ%KÔ%K�NÝ”w—~’~Ð&<Ñ=Ô=ð +ÝœÐ$:¸NÑKÔKÐKõ yAô  yHð  0zÐ/t½(¼/Ð/tÐ/tÐ[aÔ[dÐ/tÐ/tÐ/tÐ/tð  Nzð  agô  ajð  Nzð  Nzð  Nz˜Ô,ØŸ	š	™œ˜ØŸ
š
 6Ñ*Ô*Ð*øøÝ ð fð fð fÝ”J×$Ò$Ð%dÐ_`Ð%dÐ%dÐ%dÑeÔeÐeÐeÐeÐeÐeÐeøøøøðføøøð ñ 	#ð#ð (ŸOšO¨FÑ3Ô3Ø&1§o¢oÐ6FÑ&GÔ&GØ#.§?¢?°=Ñ#AÔ#AØ +§¢°
Ñ ;Ô ;ð	ð �ð *2�Ô&Ø—	’	‘”�ð —?’? :Ñ.Ô.ð Ø%×DÒDØ"(¤)Ø&1°*Ô&=ð Eñ ô ð ð —?’? :Ñ.Ô.ð Ø%×IÒIØ"(¤)Ø&1°*Ô&=Ø&1§o¢o°oÀrÑ&JÔ&Jð Jñ ô ð øøõ
 ð #ð #ð #Ý”
× Ò Ð!ZÐUVÐ!ZÐ!ZÐ!ZÑ[Ô[Ð[Ý”
× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð#øøøð ñ 	# 6¤?ñ 	#ð#ØIÐIÐIÐIÐIÐIØ$4Ð$4Ñ$6Ô$6Ð!ð "3×!TÒ!TØ%œØ&9Ý#+Ô#7Ð TÐ TÀVÄYÐ TÐ TÐ Tð "Uñ "ô "�õ ksÔjyð  (fÐ'fµ(´/Ð'fÐ'fÐW]ÔW`Ð'fÐ'fÐ'fÐ'fð  @fð  W]ô  W`ð  @fð  @fð  @f�Ô$Ø—	’	‘”�õ Ô#Ð$9¨f¬iÐ$9Ð$9Ñ:Ô:Ð:ÝÔ#Ð$4Ñ5Ô5Ð5ÝÔ#Ð$5Ñ6Ô6Ð6ÝÔ#Ð$4Ñ5Ô5Ð5Ð5øÝð #ð #ð #Ý”
× Ò Ð![ÐVWÐ![Ð![Ð![Ñ\Ô\Ð\Ý”
× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð#øøøõ (¨¬Ñ8Ô8ˆŒÝ0°Ñ8Ô8ˆÔàÔð 	C¨Ô(<×(GÒ(GÈÑ(OÔ(Oð 	CÝYaÔYhð  $CÐ#U­h¬oÐ#U¸vÔ?SÐ#UÐ#UÐ#UÐntô  oCˆFÔ àˆøåð ð ð ØÝð að að aÝŒ
×ÒÐUÐPQÐUÐUÐUÑVÔVÐVÝŒ
×ÒÑÔÐÝ¨Ð4_ÕWZÐ[\ÑW]ÔW]Ð4_Ð4_Ð`Ñ`Ô`Ð`øøøøðaøøøs>  „D(b# Ä-B#G Çb# Ç)I!Ç:A"IÉI!É!Bb# Ì L Ìb# Ì
MÌ#MÌ>b# ÍMÍb# Í'A,Q% ÏO:Ï.Q% Ï:O>Ï>Q% ÐO>ÐA"Q% Ñ$b# Ñ%
RÑ/#RÒb# ÒRÒb# Ò"B3U Õb# Õ
VÕ #VÖb# ÖVÖb# ÖC1Z Úb# Ú
[ÚA[Ûb# Û[Ûb# Û*C"_ ßb# ß
`"ßA`àb# à`"à"B b# â#dâ7A"däd)vÚfastapir   r   r   r   r   r   r	   r
   r   Úfastapi.responsesr   Úpydanticr   ra  rÏ  rN  rò   r±   Úuuidrq  rB   r@   Úfastapi.securityr   Úsqlalchemy.ormr   Útypingr   r   r   rR  r   Úmodels.streamr   Úmodels.userr   Úmodels.processing_jobr   Úschemas.streamr   r   r   r   Úauthr   r   r   r   r    r!   r"   r#   r  r%   r  r'   Úservices.chat_servicer(   Úservices.chat_json_servicer)   r}   r  r÷  r*   r+   r,   Úrouterr0   Údictr7   rw  ÚLockÚthumbnail_progress_lockrG   rP   rk   rx   rv  rƒ   rˆ   rM   r  r˜   r«   r®   r¶   r¸   rÖ   rå   Úpostrê   ÚHTTP_201_CREATEDr÷   Úputr  r  r  ÚHTTP_204_NO_CONTENTr  r  r8  rp  rr  r|  r™  r£  r§  r¸  r×  rÛ  ré  rN  rU  rc  re  r`  ry  rœ   r>   r<   ú<module>r�     sw  ðØ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oÐ oØ &Ð &Ð &Ð &Ð &Ð &Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø 
€
€
€
Ø €€€Ø €€€Ø €€€Ø €€€Ø €€€Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø "Ð "Ð "Ð "Ð "Ð "Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [ð Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  Gð  GØ Ð Ð Ð Ð Ð Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø /Ð /Ð /Ð /Ð /Ð /Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø 	€	€	€	Ø €€€Ø 	€	€	€	Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'à	ˆ˜.°	¨{Ð	;Ñ	;Ô	;€ð ')Ð �D˜˜d˜”OÐ (Ð (Ñ (Ø(˜)œ.Ñ*Ô*Ð ð6˜ð 6 ð 6ð 6ð 6ð 6ð˜ð  tð °¸Ô0Bð ð ð ð ð˜vð ¨$ð ð ð ð ðB˜Sð  Sð ð ð ð ð. ð ð ð ð ð:¨ð ð ð ð ð ‡‚ˆB˜t NÔ3€Ñ4Ô4àØØ�'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð	ð Ø
ðàðð 	ðð ˜4”.ð	ð ð ñ 5Ô4ðð> ‡‚ˆIÑÔð Ø�'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð	(ð (Øð(àð(ð 	ð(ð ˜4”.ð	(ð (ð (ñ Ôð(ðV ‡‚ˆJÑÔð Ø�'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð	(ð (Øð(àð(ð 	ð(ð ˜4”.ð	(ð (ð (ñ Ôð(ðV ‡‚ˆIÑÔð Ø�'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð	)ð )Øð)àð)ð 	ð)ð ˜4”.ð	)ð )ð )ñ Ôð)ðX ‡‚ˆL¨¨nÔ)=€Ñ>Ô>àØØ�'˜&‘/”/Ø ˜Ð!7Ñ8Ô8ð	ð Ø
ðàðð 	ðð ð	ð ð ñ ?Ô>ðð4 ‡‚ˆI d¨>Ô&:€Ñ;Ô;ð Ø�'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð	fð fØ
ðfàðfð 	ðfð ˜4”.ð	fð fð fñ <Ô;ðfðR ‡‚ˆN¨>€Ñ:Ô:ð �'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð*ð *Øð*àð*ð ˜4”.ð*ð *ð *ñ ;Ô:ð*ðZ ‡‚Ð °€Ñ@Ô@ð �'˜&‘/”/Ø#* 7Ð+DÑ#EÔ#Eð0ð 0Øð0àð0ð ˜4”.ð0ð 0ð 0ñ AÔ@ð0ðf ‡‚ˆR ¸FÔ<S€ÑTÔTð �'˜&‘/”/Ø ˜Ð!3Ð!3°OÑ!DÔ!DÑEÔEðVð VØðVàðVð ðVð Vð Vñ UÔTðVð* ‡‚ˆN¨>€Ñ:Ô:ð �'˜&‘/”/Ø ˜Ð!7Ð!7¸ÐJ]Ð8^Ñ!_Ô!_Ñ`Ô`ð	Vð VØðVàðVð 	ðVð ð	Vð Vð Vñ ;Ô:ðVðr ‡‚Ð#°N€ÑCÔCð �'˜&‘/”/Ø ˜Ð!7Ñ8Ô8ð	ð Øðàðð 	ðð ð	ð ð ñ DÔCðð< ‡‚ˆ~¨6Ô+E€ÑFÔFð �'˜&‘/”/Ø ˜Ð!7Ð!7¸ÐJ]Ð8^Ñ!_Ô!_Ñ`Ô`Ø(,ð	9Vð 9VØð9Vàð9Vð ð9Vð &ð	9Vð 9Vð 9Vñ GÔFð9VðxW 3ð W°#ð WÀcð WÐVYð Wð Wð Wð Wðt ‡‚Ð"Ñ#Ô#ð �t˜C‘y”yØ�'˜&‘/”/Ø ˜Ð!3Ð!3°OÑ!DÔ!DÑEÔEð	.Mð .MØð.Mà
ð.Mð 	ð.Mð ð	.Mð .Mð .Mñ $Ô#ð.Mðb ‡‚Ð¨nÈ&ÔJa€ÑbÔbð  Ø!%ØØØ�'˜&‘/”/Ø ˜Ð!3Ð!3°OÑ!DÔ!DÑEÔEð{
ð {
Øð{
à�CŒ=ð{
ð ˜#”ð{
ð ð	{
ð
 ð{
ð 	ð{
ð ð{
ð {
ð {
ñ cÔbð{
ð|(ð (ð (ð (ð (˜	ñ (ô (ð (ð
 ‡‚Ð'¸€ÑGÔGð �'˜&‘/”/Ø ˜Ð!8Ñ9Ô9ð	x
ð x
Øðx
àðx
ð 	ðx
ð ð	x
ð x
ð x
ñ HÔGðx
ðv ‡‚Ð,¸^€ÑLÔLð "&  c¡¤Ø�'˜&‘/”/Ø ˜Ð!8Ñ9Ô9ð	Z\ð Z\ØðZ\àðZ\ð 	ðZ\ð ð	Z\ð Z\ð Z\ñ MÔLðZ\ðz ‡‚Ð,Ñ-Ô-ð �'˜&‘/”/ð
ð 
Øð
àð
ð 
ð 
ñ .Ô-ð
ð4 ‡‚Ð.Ñ/Ô/ð �'˜&‘/”/ð
ð 
Øð
àð
ð 
ð 
ñ 0Ô/ð
ð4 ‡‚Ð#Ñ$Ô$ð Ø�'˜&‘/”/Ø�7Ð+Ñ,Ô,ð	R
ð R
ØðR
àðR
ð 	ðR
ð R
ð R
ñ %Ô$ðR
ðj ‡‚Ð5Ñ6Ô6ð �'˜&‘/”/ð8_ð 8_Øð8_àð8_ð 	ð8_ð 8_ð 8_ñ 7Ô6ð8_ðv ‡‚Ð-Ñ.Ô.ð �'˜&‘/”/ðcð cØðcàðcð cð cñ /Ô.ðcð6 ‡‚Ð$Ñ%Ô%ð �'˜&‘/”/Ø ˜Ð!7Ñ8Ô8ð(Zð (ZØð(Zàð(Zð ð(Zð (Zð (Zñ &Ô%ð(ZðVq°Cð qÀ#ð qð qð qð qðh	 ‡‚Ð/Ñ0Ô0ð Ø�'˜&‘/”/Ø ˜Ð!9Ñ:Ô:ðZ`ð Z`ØðZ`àðZ`ð ðZ`ð 	ð	Z`ð
 ðZ`ð Z`ð Z`ñ 1Ô0ðZ`ðz ‡‚Ð%Ñ&Ô&ð �'˜&‘/”/Ø ˜Ð!9Ñ:Ô:ð	<_ð <_Øð<_àð<_ð 	ð<_ð ð	<_ð <_ð <_ñ 'Ô&ð<_ð~ ‡‚Ð,Ñ-Ô-ð �t˜C‘y”yØ�'˜&‘/”/Ø ˜Ð!9Ñ:Ô:ð	2
ð 2
Øð2
à
ð2
ð 	ð2
ð ð	2
ð 2
ð 2
ñ .Ô-ð2
ðj ‡‚ˆY ~€Ñ6Ô6à˜4 ™:œ:Ø!%  d¡¤Ø"˜d 4™jœjØ+/¨4°©:¬:Ø�d˜5‘k”kØ+/¨4°©:¬:Ø�'˜&‘/”/Ø ˜Ð!3Ð!3°OÑ!DÔ!DÑEÔEðFað FaØ�CŒ=ðFaà˜#”ðFað �sŒmðFað " %œð	Fað
 ðFað ˜ZÔ(ðFað 	ðFað ðFað Fað Fañ 7Ô6ðFað Fað Far>   