
    YiL                        S r SSKJrJrJr  SSKJrJrJrJ	r	J
r
Jr  SSKJr  SSKJr  \R                   " SS/S	9\S
 5       5       r\R                   " SS/S	9\S 5       5       r\R                   " SS/S	9\S 5       5       r\R                   " SS/S	9\S 5       5       r\R                   " SS/S	9\S 5       5       r\R                   " SS/S	9\S 5       5       rg)u\   
管理员系统工具 API

提供数据库备份、清理、重置等系统维护功能。
    )requestjsonify	send_file)dbChallengeRecordDeploymentRecordUserCategoryAdminRole   )admin_bp)superadmin_requiredz/api/cleanup-deploymentsPOST)methodsc                  Z    SSK J n Jn  SSKJn  U R	                  5       nX1" SS9-
  n[
        R                  R                  [        R                  " [
        R                  S:H  [        R                  " [
        R                  R                  S5      [
        R                  U:  5      [        R                  " [
        R                  U:  [
        R                  R                  SS	/5      5      5      5      R!                  5       nU" 5       nSnSnU H  n	 U	R                  S:X  ai  U	R"                  (       a2   UR%                  U	R&                  U	R"                  U	R(                  5        [        R0                  R3                  U	5        US-  nM}  U	R"                  (       a2   UR%                  U	R&                  U	R"                  U	R(                  5        SU	l
        US-  nM     [        R0                  R5                  5         Xx-   nSU S3nUS:  a  USU SU S3-  n[7        SUUUUS.5      $ ! [*         a.  n
[-        S
U	R&                   S[/        U
5       35         Sn
A
NSn
A
ff = f! [*         a.  n
[-        S
U	R&                   S[/        U
5       35         Sn
A
NSn
A
ff = f! [*         a0  n
[-        SU	R&                   S[/        U
5       35         Sn
A
GM  Sn
A
ff = f! [*         aA  n
[        R0                  R9                  5         [7        S[/        U
5      S.5      S4s Sn
A
$ Sn
A
ff = f)u   清理过期部署r   )datetime	timedelta)DockerExecutionService   )hoursexpiredNrunningstoppedu   清理部署 u	    失败: r   u   处理部署 u    时出错: 
   已清理 u    个过期部署u
   （删除 u    个，标记 u    个）T)successcountdeletedmarkedmessageFr   error  )r   r   .app.services.deployment.core.execution_servicer   utcnowr   queryfilterr   or_statusand_
expires_atisnot
created_atin_allworking_directorydelete_deploymentdeployment_uuidexternal_port	Exceptionprintstrsessiondeletecommitr   rollback)r   r   r   nowcutoffexpired_deploymentsdocker_servicedeleted_countmarked_count
deploymentetotal_countr   s                K   /Users/yu22x/Desktop/ddd_副本131/ctf/app/routes/admin/system_tools_api.pyapi_cleanup_deploymentsrD      s   UA0Yooyr** /44;;FF ''94$//55d;$//#5
 $//&8$++//I0FG
 #% 	" 01-J!$$	1!33a*<< * : : * < < * 8 8 JJ%%j1!Q&M "33a*<< * : : * < < * 8 8 )2J% A%L? .H 	

#2{m+;<1M?.gVVG $"
  	?  ) a!M*2L2L1MYWZ[\W]V^"_``a  ) a!M*2L2L1MYWZ[\W]V^"_``a
  j&@&@%AcRSfXVW$  A


53q6:;S@@As   DK !J"71H,($J"K J" 1I'J"AK ,
I$6$IJ"I$$J"'
J1$JJ"JJ""
K,$KK KK 
L*)6L%L*%L*z/api/cleanup-invalid-challengesc                  "    SSK n [        R                  R                  5       nSnU Hf  nUR                  (       d  M  U R
                  R                  UR                  5      (       a  MB  [        R                  R                  U5        US-  nMh     [        R                  R                  5         [        SUSU S3S.5      $ ! [         aA  n[        R                  R                  5         [        S[        U5      S	.5      S
4s SnA$ SnAff = f)u   清理无效题目记录r   Nr   Tr   u    个无效题目记录)r   r   r   Fr    r"   )osr   r%   r.   
output_dirpathexistsr   r6   r7   r8   r   r3   r9   r5   )rF   
challengesr   	challengerA   s        rC   api_cleanup_invalid_challengesrL   j   s    A %**..0
#I###BGGNN9;O;O,P,P

!!),
	 $ 	

#E7*@A
  	
  A


53q6:;S@@As)   8C (C *AC 
D6D	D	Dz/api/backup-databasec                      SSK n SSKnSSKnSSKJn  SSKJn  SSKJn  U" UR                  5      nUS-  S-  nUR                  SSS	9  UR                  5       R                  S
5      nUR                  S:X  Ga  U" UR                  5      n	U	R                  5       (       d  [        SSU	 3S.5      S4$ U	R!                  5       R"                  n
USU S3-  nSSKnUR'                  [)        U	5      5      nUR'                  [)        U5      5      nUR+                  U5        UR-                  5         UR-                  5         USU S3-  n[/        US5       nUR/                  US5       nUR1                  UU5        SSS5        SSS5        UR3                  5         UR!                  5       R"                  nSnUR                  5       R5                  5       US-  S-  S-  -
  nSnUR7                  S5       H8  nUR!                  5       R8                  U:  d  M#  UR3                  5         US-  nM:     [        SS[)        UR;                  U5      5      UU
US.5      $ UR                  S:X  Ga   SSKnSSKJ n  USU S 3-  n UR'                  URD                  URF                  URH                  URJ                  URL                  S!9nSSK'nU RP                  RS                  5       nURL                  US"'   S#S$URD                  S%[)        URF                  5      S&URJ                  S'URH                  S(S)S*[)        U5      /n URU                  UUSSSS+S,9nUR-                  5         USU SJ3-  n[/        US5       nUR/                  US5       nUR1                  UU5        SSS5        SSS5        UR3                  5         UR!                  5       R"                  nSnUR                  5       R5                  5       US-  S-  S-  -
  nSnUR7                  SK5       H8  nUR!                  5       R8                  U:  d  M#  UR3                  5         US-  nM:     [        SS[)        UR;                  U5      5      UUSL.5      $ [        SSMUR                   3S.5      S4$ ! , (       d  f       GN"= f! , (       d  f       GN,= f! [B         a    [        SSS.5      S4s $ f = f! URV                   a#    UR-                  5         [        SS-S.5      S4s $ URX                  [Z        4 Ga!  nUR-                  5         SS.K.J/nJ0n   U" URb                  5      n!U!R'                  5        n"SS/K.J2n#  U#" U!5      n$U$Rg                  5       n%[/        US0S1S29 n&U&Ri                  S35        U&Ri                  S4UR                  5       R                  S55       S635        U&Ri                  S7URH                   S835        U% GH  n'U&Ri                  S9U' S635        U&Ri                  S:U' S;35        U"Rk                  U " S<U' S=35      5      nURm                  5       n(U((       d  Mb  URo                  5       n)S>Rq                  U) V*s/ s H	  n*S=U* S=3PM     Os  sn*f sn*5      n+U( GH_  n,/ n-U, GH&  n.U.c  U-Rs                  S?5        M  [u        U.[(        5      (       a)  U.Rw                  S@SA5      n/U-Rs                  S@U/ S@35        MX  [u        U.[x        [z        45      (       a  U-Rs                  [)        U.5      5        M  [u        U.[|        5      (       a  U-Rs                  U.(       a  SBOSC5        M  [u        U.U5      (       a%  U-Rs                  S@U.R                  5        S@35        M  [)        U.5      Rw                  S@SA5      n0U-Rs                  S@U0 S@35        GM)     S>Rq                  U-5      n1U&Ri                  SDU' SEU+ SFU1 SG35        GMb     GM     SSS5        O! , (       d  f       O= fSSS5        O! , (       d  f       O= fU!R                  5          SnAGNSnAff = f! [         aD  nSH[        5       ;   a  WR-                  5         [        SSI[)        U5       3S.5      S4s SnA$ SnAff = f! , (       d  f       GN= f! , (       d  f       GN= f! [         a:  nSSKCn2U2R                  5         [        SSN[)        U5       3S.5      S4s SnA$ SnAff = f)Ou   备份数据库r   Nr   PathConfigbackupsdatabaseT)parentsexist_okz%Y%m%d_%H%M%SsqliteFu   数据库文件不存在: r      ctf_z.dbz.db.gzrbwb   r   <   *.gzr   u   数据库备份成功)r   r   backup_filebackup_sizedb_sizedeleted_old
postgresql)ISOLATION_LEVEL_AUTOCOMMITu;   未安装 psycopg2，请运行: pip install psycopg2-binaryr"   z.sql)hostportrT   userpassword
PGPASSWORDpg_dumpz-hz-pz-Uz-dz-Fpz-fi,  )envcapture_outputtextchecktimeoutu   备份超时（超过5分钟）)create_enginern   )inspectwzutf-8)encodingu   -- PostgreSQL 数据库备份
u   -- 备份时间: %Y-%m-%d %H:%M:%S
u   -- 数据库: z

u	   
-- 表: zTRUNCATE TABLE "z" CASCADE;

zSELECT * FROM ""z, NULL'z''TRUEFALSEzINSERT INTO "z" (z
) VALUES (z);
connu   PostgreSQL 备份失败: z.sql.gzz*.sql.gz)r   r   r_   r`   rb   u   不支持的数据库类型: u   备份失败: )ErF   shutilgzipr   pathlibrP   configrR   BASE_DIRmkdirr:   strftimeDATABASE_TYPEDB_PATHrI   r   statst_sizesqlite3connectr5   backupcloseopencopyfileobjunlink	timestampglobst_mtimerelative_topsycopg2psycopg2.extensionsrd   ImportErrorPOSTGRES_HOSTPOSTGRES_PORTPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORD
subprocessenvironcopyrunTimeoutExpiredCalledProcessErrorFileNotFoundError
sqlalchemyrq   rn   SQLALCHEMY_DATABASE_URIrr   get_table_nameswriteexecutefetchallkeysjoinappend
isinstancereplaceintfloatbool	isoformatdisposer3   locals	traceback	print_exc)3rF   r}   r~   r   rP   rR   project_root
backup_dirr   db_pathra   r_   r   source_connbackup_conncompressed_filef_inf_outcompressed_size	keep_dayscutoff_timer>   
old_backupr   rd   r|   r   rl   cmdresultrA   rq   rn   engine
connectionrr   	inspectortablesftablerowscolumnscol	col_namesrowvaluesvalval_escapedval_str
values_strr   s3                                                      rC   api_backup_databaser      s   f% ! FOO,!I-
:
5 LLN++O<	8+6>>*G>>##$9'C     lln,,G %i['<<K !//#g,7K!//#k*:;K{+ )T)F+CCOk4(DYY5&&tU3 6 )
   .224<<O I",,.224	B8Kb8PQKM(oof5
??$--;%%'!Q&M 6
 2"?#>#>|#LM.",   !!\1J %i['==Ki''----#//--#55 (  "jjoo'$*$<$<L! &..#f223&..&,,##k*F%'^^'+!" # , FN 

 )T)G+DDOk4(DYY5&&tU3 6 )
   .224<<O I",,.224	B8Kb8PQKM(ooj9
??$--;%%'!Q&M :
 2"?#>#>|#LM.,    89M9M8NO   c 65 )(B  $Z    V "00 JJL"#(!B$    #557HI 7%JJL ?*6+I+IJF)Z6$+FO	!*!:!:!<!+sWEGG$EFGG&78O8OPc8d7eeg$hiGGnV5G5G4H$MN *0 !*UG2(> ? !*;E7/(R S *4););D?SXRYYZA[<\)]'-'8#'4.4kkmG04		QX:YQX#Qse1:QX:Y0ZI/31336C/2{06f0E1;C1E1E>Akk#t>T06+a>P0Q1;C#u1N1N06c#h0G1;C1F1F06fQX0Y1;C1J1J06#--/ARRS>T0U:=c(:J:J3PT:U06'!n0M 47" 6:YYv5F
()-wc)T^_i^jjn0o(p) 04 *0 FEE *))^ NN$$o7%v  VX%JJL$8QA     65 )(@  %c!fX.
   	sp  B1b; 4B!b; R((R;R(Bb; Ab; b; ,
R: 6	b;  B;a <S a  b; 5b)bb)#Bb; 7Ab; 9b; 
R%	 R((
R72b; :Sb; Sb; 0a
a a":`>*`C_=_=,Y=<E8_=4	`=
``	`>
`%	!`>8a >aa 
b9b	b
b; bb; 
b&	!b))
b83b; ;
c?/c:4c?:c?z/api/backup-database/listGETc                      SSK Jn   SSKJn  SSKJn  U " UR
                  5      nUS-  S-  nUR                  5       (       d  [        S/ S.5      $ / n[        UR                  S	5      SS
9 H  nUR                  5       nUR                  UR                  UR                  [        UR                  S-  S5      UR                  UR                   5      R#                  S5      [%        UR'                  U5      5      S.5        M     [        SUS.5      $ ! [(         a:  nSSKn	U	R-                  5         [        SS[%        U5       3S.5      S4s SnA$ SnAff = f)u   获取备份文件列表r   rO   rN   rQ   rS   rT   T)r   rS   r^   )reversei      ru   )filenamesizesize_mbr,   relative_pathNFu   获取备份列表失败: r    r"   )r   rP   r   r   rR   r   rI   r   sortedr   r   r   namer   roundfromtimestampr   r   r5   r   r3   r   r   )
rP   r   rR   r   r   rS   r_   r   rA   r   s
             rC   api_list_backupsr   t  sS   % %! FOO,!I-
:
  ""   !*//&"94HK##%DNN',, !=qA&44T]]CLLM`a!$[%<%<\%J!K  I 
  	  1#a&:
   	s%   AD CD 
E/EEEz/api/backup-database/downloadc                      SSK Jn   SSKJn  [        R
                  R                  S5      nU(       d  [        SSS.5      S4$ UR                  S	5      (       d  [        SS
S.5      S4$ SU;   d  SU;   d  SU;   a  [        SSS.5      S4$ U " UR                  5      nUS-  S-  nXB-  n UR                  5       nUR                  5       nUR                  U5        UR                  5       (       d  [        SSS.5      S4$ [        [!        U5      SUSS9$ ! [        [        4 a    [        SSS.5      S4s $ f = f! ["         a:  nSSKnUR'                  5         [        SS[!        U5       3S.5      S4s SnA$ SnAff = f)u   下载备份文件r   rO   rQ   r   Fu   缺少文件名参数r    rX   z.gzu   无效的文件类型z../\u   非法的文件名rS   rT   u   非法路径u   备份文件不存在i  Tzapplication/gzip)as_attachmentdownload_namemimetypeNu   下载失败: r"   )r   rP   r   rR   r   argsgetr   endswithr   resolver   
ValueErrorOSErrorrI   r   r5   r3   r   r   )rP   rR   r   r   r   r_   rA   r   s           rC   api_download_backupr     s   = !<<##J/ 0      '' 0    8sh$(2B -    FOO,!I-
:
 +	%--/K#++-J##J/ !!## 0    "'	
 	
 G$ 	 '   	(  %c!fX.
   	sZ   AD< %D< *!D< D< +1D $D< D<  D96D< 8D99D< <
F /E;5F ;F z/api/reset-databasec                  D    [         R                  R                  5         [        R                  R                  5         [        R                  R                  [        R                  [        R                  :g  5      R                  5         [        R                  R                  5         [        R                  R                  5         [        SSS.5      $ ! [         aA  n [        R                  R                  5         [        S[!        U 5      S.5      S4s Sn A $ Sn A ff = f)u!   重置数据库（危险操作）Tu   数据库已重置)r   r   Fr    r"   N)r   r%   r7   r   r	   r&   roler   ADMINr
   r   r6   r8   r   r3   r9   r5   )rA   s    rC   api_reset_databaser     s    A$$& 	%%' 	

$))tzz1299; 	""$


+
  	  A


53q6:;S@@As   CC 
D6DDDN)__doc__flaskr   r   r   app.models.database.modelsr   r   r   r	   r
   r    r   app.services.auth.decoratorsr   routerD   rL   r   r   r   r        rC   <module>r      s*  
 . - g g  < 
*VH=WA  >WAt 
1F8DA  EA6 
&9h  :hV 
+eW='  >'T 
/%A?  B?D 
%x8A  9Ar   