§
    Òåi  ã                   ó$  — d dl mZmZmZmZmZ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Zd dlZd dl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  ddl!m"Z" ddl#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+  ej,        e-¦  «        Z. eddg¬¦  «        Z/ ee¬¦  «        Z0e/ 1                    d¦  «        d dd ee¦  «         e e)d¦  «        ¦  «        dfde2de2de3dededefd „¦   «         Z4e/ 1                    d!e"¬"¦  «         ee¦  «         e e)d¦  «        ¦  «        fd#e3dedefd$„¦   «         Z5e/ 6                    d%e"¬"¦  «         ee¦  «         e e)d¦  «        ¦  «        fd#e3d&e$dedefd'„¦   «         Z7e/ 8                    d!ej9        ¬(¦  «         ee¦  «         e e)d¦  «        ¦  «        fd#e3dedefd)„¦   «         Z:e/ 1                    d*e&¬"¦  «         ee¦  «         ee(¦  «        fdedefd+„¦   «         Z;e/ 6                    d,e"¬"¦  «         ee¦  «         e e)d¦  «        ¦  «        fd#e3dedefd-„¦   «         Z<e/ 6                    d.e"¬"¦  «         ee¦  «         e e)d¦  «        ¦  «        fd#e3dedefd/„¦   «         Z=dS )0é    )Ú	APIRouterÚDependsÚHTTPExceptionÚstatusÚRequestÚResponse)ÚSession)ÚfuncÚand_)ÚLimiter)Úget_remote_address)ÚDictNé   )Úget_db)ÚUser)ÚStream)ÚComment)ÚWatchHistory©ÚRole)ÚUserResponse)ÚUserRoleUpdateÚUserListResponseÚSystemStats)Úget_current_admin_userÚrequire_permission)Úpublish_eventz
/api/adminÚadmin)ÚprefixÚtags)Úkey_funcz/usersé2   zadmin:usersÚskipÚlimitÚroleÚdbÚcurrent_userÚrequestc              ƒ   ó8  K  — |                      t          ¦  «        }|rw|                      t          ¦  «                             t          j        |k    ¦  «                             ¦   «         }|r(|                     t          j        |j        k    ¦  «        }|                     t          j	         
                    ¦   «         ¦  «                             | ¦  «                             |¦  «                             ¦   «         }d„ |D ¦   «         }	d„ |	D ¦   «         }
t          j        |
t           ¬¦  «        }t#          j        |                     ¦   «         ¦  «                             ¦   «         }|r.|j                             d¦  «        |k    rt/          d¬¦  «        S |	S )Nc                 ó6   — g | ]}t          j        |¦  «        ‘ŒS © )r   Úfrom_orm_with_role)Ú.0Úusers     ú/app/app/api/admin.pyú
<listcomp>zlist_users.<locals>.<listcomp>,   s$   € ÐJÐJÐJ¸DÕÔ1°$Ñ7Ô7ÐJÐJÐJó    c                 ó6   — g | ]}|                      ¦   «         ‘ŒS r+   )Ú
model_dump)r-   Úrs     r/   r0   zlist_users.<locals>.<listcomp>/   s    € Ð2Ð2Ð2 a�1—<’<‘>”>Ð2Ð2Ð2r1   )Údefaultzif-none-matchi0  ©Ústatus_code)Úqueryr   r   ÚfilterÚnameÚfirstÚrole_idÚidÚorder_byÚ
created_atÚdescÚoffsetr$   ÚallÚjsonÚdumpsÚstrÚhashlibÚmd5ÚencodeÚ	hexdigestÚheadersÚgetr   )r#   r$   r%   r&   r'   r(   r8   Úrole_objÚusersÚresultÚresult_dictÚresult_jsonÚetags                r/   Ú
list_usersrR      sS  è è € ð �HŠH•T‰NŒN€Eàð >Ø—8’8�D‘>”>×(Ò(­¬°dÒ):Ñ;Ô;×AÒAÑCÔCˆØð 	>Ø—L’L¥¤°´Ò!<Ñ=Ô=ˆEà�NŠN�4œ?×/Ò/Ñ1Ô1Ñ2Ô2×9Ò9¸$Ñ?Ô?×EÒEÀeÑLÔL×PÒPÑRÔR€EØJÐJÀEÐJÑJÔJ€Fð 3Ð2¨6Ð2Ñ2Ô2€KÝ”*˜[µ#Ð6Ñ6Ô6€KÝŒ;�{×)Ò)Ñ+Ô+Ñ,Ô,×6Ò6Ñ8Ô8€Dàð )�7”?×&Ò& Ñ7Ô7¸4Ò?Ð?Ý CÐ(Ñ(Ô(Ð(à€Mr1   z/users/{user_id})Úresponse_modelÚuser_idc              ƒ   ó  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚t          j	        |¦  «        S )NúUser not found©r7   Údetail)
r8   r   r9   r=   r;   r   r   ÚHTTP_404_NOT_FOUNDr   r,   ©rT   r&   r'   r.   s       r/   Úget_userr[   9   ss   è è € ð �8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€Dàð 
ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
õ
 Ô*¨4Ñ0Ô0Ð0r1   z/users/{user_id}/roleÚrole_updatec              ƒ   óP  K  — t                                d| › d|j        › �¦  «         |                     t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|s8t                                d| › �¦  «         t          t          j        d¬¦  «        ‚t                                d|j        › d|j        r|j        j        nd › �¦  «         |                     t          ¦  «                             t          j        |j        k    ¦  «                             ¦   «         }|s=t                                d|j        › �¦  «         t          t          j        d	¬¦  «        ‚t                                d
|j        › �¦  «         |j        �r|j        j        dk    �r|j        dk    r÷|                     t          ¦  «                             t          j        dk    ¦  «                             ¦   «         }|                     t          ¦  «                             t          j        |j        k    ¦  «                             ¦   «         }t                                d|› �¦  «         |dk    r5t                                d¦  «         t          t          j        d¬¦  «        ‚|j        |_        |                     ¦   «          |                     |¦  «         t)          dt+          |j        ¦  «        |j        dœ¦  «         t-          j        |¦  «        S )Nz'Attempting to update role for user_id: z
 to role: zUser not found: rV   rW   zUser found: z, current role: zRole not found: zRole not foundzNew role found: r   zAdmin count: é   z,Cannot remove admin role from the last adminÚuser_role_changed)rT   Ú	role_name)ÚloggerÚinfor%   r8   r   r9   r=   r;   Úwarningr   r   rY   Úusernamer:   r   r<   ÚcountÚHTTP_400_BAD_REQUESTÚcommitÚrefreshr   rE   r   r,   )rT   r\   r&   r'   r.   Únew_roleÚ
admin_roleÚadmin_counts           r/   Úupdate_user_rolerl   J   s¶  è è € õ ‡K‚KÐ_¸'Ð_Ð_È[ÔM]Ð_Ð_Ñ`Ô`Ð`Ø�8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€Dàð 
Ý�ŠÐ3¨'Ð3Ð3Ñ4Ô4Ð4ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
õ
 ‡K‚KÐe˜tœ}ÐeÐeÐPTÔPYÐ>c¸d¼i¼n¸nÐ_cÐeÐeÑfÔfÐfð �xŠx�‰~Œ~×$Ò$¥T¤Y°+Ô2BÒ%BÑCÔC×IÒIÑKÔK€HØð 
Ý�ŠÐ<¨+Ô*:Ð<Ð<Ñ=Ô=Ð=ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
õ
 ‡K‚KÐ2 8¤=Ð2Ð2Ñ3Ô3Ð3ð „yñ 	�T”Y”^ wÒ.Ñ.°;Ô3CÀwÒ3NÐ3NØ—X’X�d‘^”^×*Ò*­4¬9¸Ò+?Ñ@Ô@×FÒFÑHÔHˆ
Ø—h’h�t‘n”n×+Ò+­D¬L¸J¼MÒ,IÑJÔJ×PÒPÑRÔRˆÝ�ŠÐ1 KÐ1Ð1Ñ2Ô2Ð2Ø˜!ÒÐÝ�NŠNÐIÑJÔJÐJÝÝ"Ô7ØEðñ ô ð ð
 ”;€D„LØ‡I‚I�K„K€KØ‡J‚JˆtÑÔÐõ Ð%µ3°t´w±<´<ÈhÌmÐ'\Ð'\Ñ]Ô]Ð]åÔ*¨4Ñ0Ô0Ð0r1   r6   c              ƒ   ó4  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        rÐ|j        j	        dk    rÀ|                      t          ¦  «                             t          j	        dk    ¦  «                             ¦   «         }|                      t          ¦  «                             t          j        |j        k    ¦  «                             ¦   «         }|dk    rt          t          j        d¬¦  «        ‚|j        |j        k    rt          t          j        d¬¦  «        ‚|                     |¦  «         |                     ¦   «          d S )NrV   rW   r   r^   zCannot delete the last adminzCannot delete yourself)r8   r   r9   r=   r;   r   r   rY   r%   r:   r   r<   re   rf   Údeleterg   )rT   r&   r'   r.   rj   rk   s         r/   Údelete_userro   ~   s[  è è € ð �8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€Dàð 
ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
ð „yð �T”Y”^ wÒ.Ð.Ø—X’X�d‘^”^×*Ò*­4¬9¸Ò+?Ñ@Ô@×FÒFÑHÔHˆ
Ø—h’h�t‘n”n×+Ò+­D¬L¸J¼MÒ,IÑJÔJ×PÒPÑRÔRˆØ˜!ÒÐÝÝ"Ô7Ø5ðñ ô ð ð „w�,”/Ò!Ð!ÝÝÔ3Ø+ð
ñ 
ô 
ð 	
ð
 ‡I‚Iˆd�O„O€OØ‡I‚I�K„K€Kàˆ4r1   z/statsc              ƒ   óº  K  — |                       t          ¦  «                             ¦   «         }|                       t          ¦  «                             ¦   «         }|                       t          ¦  «                             ¦   «         }ddlm}m} |                     ¦   «          |d¬¦  «        z
  }|                       t          ¦  «         	                    t          j
        |k    ¦  «                             t          j        ¦  «                             ¦   «         }ddlm}	 i }
dD ]¤}|                       |	¦  «         	                    |	j        |k    ¦  «                             ¦   «         }|rX|                       t          ¦  «         	                    t          j        |j        k    ¦  «                             ¦   «         }||
|<   ŒŸd|
|<   Œ¥t'          |||||
¬¦  «        S )Nr   )ÚdatetimeÚ	timedeltaé   )Údaysr   )r.   ÚmodÚ
subscriberÚcreatorr   )Útotal_usersÚtotal_streamsÚtotal_commentsÚactive_usersÚusers_by_role)r8   r   re   r   r   rq   rr   Úutcnowr   r9   Úlast_watched_atÚdistinctrT   Úapp.models.permissionr   r:   r;   r<   r=   r   )r&   r'   rx   ry   rz   rq   rr   Úseven_days_agor{   r   r|   r`   r%   re   s                 r/   Úget_system_statsr‚   £   s±  è è € ð
 —(’(�4‘.”.×&Ò&Ñ(Ô(€KØ—H’H�VÑ$Ô$×*Ò*Ñ,Ô,€MØ—X’X�gÑ&Ô&×,Ò,Ñ.Ô.€Nð -Ð,Ð,Ð,Ð,Ð,Ð,Ð,Ø—_’_Ñ&Ô&¨¨¸Ð):Ñ):Ô):Ñ:€NØ—8’8�LÑ)Ô)×0Ò0ÝÔ$¨Ò6ñô ç‚h�|Ô#Ñ$Ô$§U¢U¡W¤Wð ð
 +Ð*Ð*Ð*Ð*Ð*Ø€MØFð )ð )ˆ	Ø�xŠx˜‰~Œ~×$Ò$ T¤Y°)Ò%;Ñ<Ô<×BÒBÑDÔDˆØð 	)Ø—H’H�T‘N”N×)Ò)­$¬,¸$¼'Ò*AÑBÔB×HÒHÑJÔJˆEØ',ˆM˜)Ñ$Ð$à'(ˆM˜)Ñ$Ð$åØØ#Ø%Ø!Ø#ðñ ô ð r1   z/users/{user_id}/activatec              ƒ   ób  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚d|_        | 	                    ¦   «          | 
                    |¦  «         t          j        |¦  «        S )NrV   rW   T)r8   r   r9   r=   r;   r   r   rY   Ú	is_activerg   rh   r   r,   rZ   s       r/   Úactivate_userr…   Ç   s™   è è € ð �8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€Dàð 
ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
ð
 €D„NØ‡I‚I�K„K€KØ‡J‚JˆtÑÔÐåÔ*¨4Ñ0Ô0Ð0r1   z/users/{user_id}/deactivatec              ƒ   ó¸  K  — |                      t          ¦  «                             t          j        | k    ¦  «                             ¦   «         }|st          t          j        d¬¦  «        ‚|j        |j        k    rt          t          j        d¬¦  «        ‚d|_	        | 
                    ¦   «          |                     |¦  «         t          j        |¦  «        S )NrV   rW   zCannot deactivate yourselfF)r8   r   r9   r=   r;   r   r   rY   rf   r„   rg   rh   r   r,   rZ   s       r/   Údeactivate_userr‡   Ü   sÊ   è è € ð �8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€Dàð 
ÝÝÔ1Ø#ð
ñ 
ô 
ð 	
ð „w�,”/Ò!Ð!ÝÝÔ3Ø/ð
ñ 
ô 
ð 	
ð
 €D„NØ‡I‚I�K„K€KØ‡J‚JˆtÑÔÐåÔ*¨4Ñ0Ô0Ð0r1   )>Úfastapir   r   r   r   r   r   Úsqlalchemy.ormr	   Ú
sqlalchemyr
   r   Úslowapir   Úslowapi.utilr   Útypingr   ÚloggingrF   rC   Údatabaser   Úmodels.userr   Úmodels.streamr   Úmodels.commentr   Úmodels.watch_historyr   Úmodels.permissionr   Úschemas.userr   Úschemas.adminr   r   r   Úauthr   r   Ússer   Ú	getLoggerÚ__name__ra   ÚrouterÚlimiterrK   ÚintrE   rR   r[   Úputrl   rn   ÚHTTP_204_NO_CONTENTro   r‚   r…   r‡   r+   r1   r/   ú<module>r       s  ðØ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PØ "Ð "Ð "Ð "Ð "Ð "Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø +Ð +Ð +Ð +Ð +Ð +Ø Ð Ð Ð Ð Ð Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø $Ð $Ð $Ð $Ð $Ð $Ø /Ð /Ð /Ð /Ð /Ð /Ø $Ð $Ð $Ð $Ð $Ð $Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IØ =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø Ð Ð Ð Ð Ð à	ˆÔ	˜8Ñ	$Ô	$€à	ˆ˜,¨g¨YÐ	7Ñ	7Ô	7€Ø
ˆ'Ð-Ð
.Ñ
.Ô
.€ð ‡‚ˆHÑÔàØØØ�'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCØðð Ø
ðàðð ðð 	ð	ð
 ðð ðð ð ñ Ôðð: ‡‚Ð¨|€Ñ<Ô<ð �'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCð1ð 1Øð1àð1ð ð1ð 1ð 1ñ =Ô<ð1ð  ‡‚Ð#°L€ÑAÔAð �'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCð	01ð 01Øð01àð01ð 	ð01ð ð	01ð 01ð 01ñ BÔAð01ðf ‡‚Ð!¨vÔ/I€ÑJÔJð �'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCð!ð !Øð!àð!ð ð!ð !ð !ñ KÔJð!ðH ‡‚ˆH [€Ñ1Ô1à�'˜&‘/”/Ø ˜Ð!7Ñ8Ô8ð ð  Øð àð ð  ð  ñ 2Ô1ð ðF ‡‚Ð'¸€ÑEÔEð �'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCð1ð 1Øð1àð1ð ð1ð 1ð 1ñ FÔEð1ð( ‡‚Ð)¸,€ÑGÔGð �'˜&‘/”/Ø ˜Ð!3Ð!3°MÑ!BÔ!BÑCÔCð1ð 1Øð1àð1ð ð1ð 1ð 1ñ HÔGð1ð 1ð 1r1   