
    lOi@?                        S r SSKrSSKrSSKrSSKrSSKJrJrJr  SSK	J
r
  SSKJr  SSKJr  SSKJr  SSKJrJr  S	 rS
 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\R,                  " SS/S9\S 5       5       rg)ut   
知识库文件管理 API

提供知识库文件的上传、下载、删除、创建、读取、写入等功能。
    N)request	send_filecurrent_app)secure_filename)category_api_bp)category_admin_required)APIResponse)NotFoundErrorValidationErrorc                     [         R                  R                  [        5      nUn[	        S5       H"  n[         R                  R                  U5      nM$     [         R                  R                  USU S5      $ )u   获取data文件夹路径   ge10data)ospathabspath__file__rangedirnamejoin)category_idcurrent_filebase_dir_s       P   /Users/yu22x/Desktop/ddd_副本121/ctf/app/routes/admin/category/file_manager.pyget_data_dirr      sT     77??8,LH1X77??8, 77<<&+v>>    c                     U (       d  g[         R                  R                  U 5      nSU;   d  UR                  S5      (       a  gU$ )u*   规范化路径，防止路径遍历攻击 ../N)r   r   normpath
startswith)r   
normalizeds     r   normalize_pathr%      s=    !!$'JzZ22377r   z#/<category_id>/knowledge/files/treeGET)methodsc                   ^  [        U 5      n[        R                  R                  U5      (       d+  [        R                  " USS9  [
        R                  " S/ 0S9$ SU4S jjmT" U5      n[
        R                  " SU0S9$ ! [         aW  n[        R                  R                  S[        U5       35        [
        R                  " S[        U5       35      s SnA$ SnAff = f)	u   获取文件树结构Texist_oktreer   c           	      $  > / n [        [        R                  " U 5      5       H  n[        R                  R	                  X5      nU(       a  [        R                  R	                  X5      OUn[        R                  R                  U5      (       a   T" XE5      nUR                  USUUS.5        M  [        R                  " U5      nUR                  USUUR                  UR                  S.5        M     [        US S9$ ! [         a     Nf = f)u   递归构建文件树	directory)nametyper   childrenfile)r/   r0   r   sizemodifiedc                 8    U S   S:H  U S   R                  5       4$ )Nr0   r2   r/   )lower)xs    r   <lambda>3get_file_tree.<locals>.build_tree.<locals>.<lambda>P   s    &	V0CQvY__EV/Wr   )key)sortedr   listdirr   r   isdirappendstatst_sizest_mtimePermissionError)	r   relative_pathitemsitem	item_pathitem_rel_pathr1   r?   
build_trees	           r   rH   !get_file_tree.<locals>.build_tree4   s    E"2::d#34D "T 8IIVBGGLL$E\`Mww}}Y//#-i#G$($/$1(0	&   "wwy1$($*$1$(LL(,&  50 %%WXX # s   C2D 
DDu   获取文件树失败: N)r   )r   r   r   existsmakedirsr	   success	Exceptionr   loggererrorstrserver_error)r   data_dirr+   erH   s       @r   get_file_treerT   )   s    *L,ww~~h''KK40&&VRL99	Y< (#""77 L  #:3q6(!CD''*A#a&(JKKLs%   AB %B 
C$ACC$C$z%/<category_id>/knowledge/files/uploadPOSTc           	         S[         R                  ;  a  [        S5      e[         R                  S   n[         R                  R	                  SS5      n[         R                  R	                  SS5      R                  5       S:H  nUR                  S:X  a  [        S5      e [        U 5      nU(       a=  [        U5      nU(       d  [        S5      e[        R                  R                  XE5      nOUn[        R                  " US	S
9  [        UR                  5      n[        R                  R                  Xg5      nU(       Ga  US-   n	UR                  U	5        Sn
/ n UR                  5       R                  S5      (       Ga=  [         R"                  " U	S5       nUR%                  5       nU GH  nSU;   d  UR'                  S5      (       a  UR)                  U5        M3  [        R                  R                  Xn5      nUR                  S5      (       a  [        R                  " US	S
9  M  [        R                  " [        R                  R+                  U5      S	S
9  UR-                  U5       n[-        US5       nUR/                  UR1                  5       5        SSS5        SSS5        U
S-  n
GM     SSS5        GOUR                  5       R                  S5      (       Gas  UR                  5       R                  S5      (       a  SOSn[2        R,                  " U	U5       nUR5                  5        GH  nSUR6                  ;   d   UR6                  R'                  S5      (       a  UR)                  UR6                  5        MQ  [        R                  R                  XnR6                  5      n[        R                  R9                  U5      R'                  [        R                  R9                  U5      5      (       d  UR)                  UR6                  5        M  UR;                  X5        UR=                  5       (       d  GM  U
S-  n
GM     SSS5        O![        R>                  " U	5        [        S5      e[        R>                  " U	5        SU
 S3nU(       a  US[A        U5       S3-  n[B        RD                  " XS.US9$ [        R                  RI                  U5      (       a  [        SU S35      eUR                  U5        [        RJ                  " U5      n[        R                  RM                  X5      n[B        RD                  " SUUURN                  URP                  S .0SU S!3S9$ ! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GN,= f! , (       d  f       GN>= f! [F         aA  n[        R                  RI                  U	5      (       a  [        R>                  " U	5        UeSnAff = f! [         a    e [F         aW  n[R        RT                  RW                  S"[Y        U5       35        [B        RZ                  " S"[Y        U5       35      s SnA$ SnAff = f)#u:   上传文件到data文件夹，支持压缩包自动解压r2   u   请选择文件r   r   extractfalsetrue   非法路径Tr)   z.tmpr   z.ziprr    r!   wbN   )z.tar.tar.gz.tgz)r^   r_   zr:gzu;   不支持的压缩包格式，仅支持 .zip, .tar, .tar.gzu"   压缩包解压成功，共解压 u
    个文件u   ，u    个文件因安全原因跳过)extracted_counterror_files)r   message   文件 
    已存在)r/   r   r3   r4   u    上传成功u   上传文件失败: ).r   filesr   formgetr6   filenamer   r%   r   r   r   rK   r   saveendswithzipfileZipFilenamelistr#   r>   r   openwritereadtarfile
getmembersr/   r   rW   isfileremovelenr	   rL   rM   rJ   r?   relpathr@   rA   r   rN   rO   rP   rQ   )r   r2   rC   rW   rR   r$   save_dirsafe_filename	file_path	temp_pathr`   ra   zip_ref	file_listmembertarget_pathsourcetargetmodetar_refrb   rS   r?   file_rel_paths                           r   upload_knowledge_filer   Z   s    W]]"/00== DLL$$VR0Mlly'288:fDG}}/00xI, '6J%n55ww||H9HH
Ht,'6GGLL9	 !F*IIIi OKA &&(11&99 C8G$+$4$4$6	&/F#v~1B1B31G1G + 2 26 : ( +-'',,x*HK  &s33 "K$ G "BGGOOK,HSW X%,\\&%9VT+W[E\`f$*LL$? F]%9 /1 4! '0 98* #((*334OPP%2%8%8%:%C%CDW%X%X6^aD i6'&-&8&8&:F#v{{2fkk6L6LS6Q6Q + 2 26;; ? (*,'',,x*MK $&77??;#?#J#J277??[cKd#e#e + 2 26;; ? (#OOF=%}} /1 4 '; 76( IIi()*ghh 		)$>>OzZS%5$66UVVG"**-<Y#  ww~~i((%j&IJJIIi 779%DGGOOI@M&& - - $$(MM	 "->
 
u F]E\%9%9# 98. 76F  77>>),,IIi(	:   I  #7Ax!@A''*>s1vh(GHHIs    B<X <V9 CV.V; U1	V#V5A.V9 #DV'
V'A5V9 B,X 1
V ;V
VV
V$V9 '
V61V9 9
X<W??XX Y2AY-'Y2-Y2z'/<category_id>/knowledge/files/downloadc                    [         R                  R                  S5      nU(       d  [        S5      e [	        U 5      n[        U5      nU(       d  [        S5      e[        R                  R                  X#5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        S5      e[        R                  R                  U5      (       d  [        S5      e[        R                  R                  U5      (       d  [        S5      e[        R                  R                  U5      n[        USUS9$ ! [        [        4 a    e [          aW  n["        R$                  R'                  S[)        U5       35        [*        R,                  " S[)        U5       35      s S	nA$ S	nAff = f)
u   下载文件r      缺少路径参数rZ      文件不存在   不是文件T)as_attachmentdownload_nameu   下载文件失败: N)r   argsrg   r   r   r%   r   r   r   r   r#   rJ   r
   rs   basenamer   rM   r   rN   rO   rP   r	   rQ   )r   ry   rR   r$   	full_pathrh   rS   s          r   download_knowledge_filer      sZ      (I233I, $I.
!.11GGLL6	 wwy)44RWW__X5NOO!.11ww~~i(( 122ww~~i((!.1177##I.$hOO]+  I  #7Ax!@A''*>s1vh(GHHIs   D)E G7AG	G	Gz%/<category_id>/knowledge/files/deleteDELETEc                 >   [         R                  " 5       nUR                  S5      nUR                  SS5      nU(       d  [        S5      e [	        U 5      n[        U5      nU(       d  [        S5      e[        R                  R                  XE5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        S5      e[        R                  R                  U5      (       d  [        S5      eU(       a:  [        R                  " U5        S[        R                  R                  U5       S3nO9[        R                   " U5        S	[        R                  R                  U5       S3n["        R$                  " US
9$ ! [        [        4 a    e [&         aW  n[(        R*                  R-                  S[/        U5       35        ["        R0                  " S[/        U5       35      s SnA$ SnAff = f)u   删除文件或文件夹r   is_directoryFr   rZ   u   文件或文件夹不存在
   文件夹 u    删除成功rc   rb   u   删除失败: N)r   get_jsonrg   r   r   r%   r   r   r   r   r#   rJ   r
   shutilrmtreer   rt   r	   rL   rM   r   rN   rO   rP   rQ   )	r   r   ry   r   rR   r$   r   rb   rS   s	            r   delete_knowledge_filer   	  s    D I88NE2L233C, $I.
!.11GGLL6	 wwy)44RWW__X5NOO!.11ww~~i(( =>> MM)$"277#3#3I#>"?}MGIIi  0 0 ;<MJG""733]+  C  >#a&!:;''.Q(ABBCs    EF+ +HAHHHz%/<category_id>/knowledge/files/createc                    [         R                  " 5       nUR                  S5      nUR                  SS5      nUR                  SS5      nU(       d  [        S5      e [	        U 5      nU(       a=  [        U5      nU(       d  [        S5      e[        R                  R                  XV5      nOUn[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        S5      e[        R                  " USS	9  [        R                  R                  Xr5      n[        R                  R                  U5      (       a  [        U(       a  S
OS SU S35      eU(       a  [        R                  " USS	9  SU S3n	O+[        USSS9 n
U
R                  S5        SSS5        SU S3n	[        R                   " U	S9$ ! , (       d  f       N(= f! [         a    e ["         aW  n[$        R&                  R)                  S[+        U5       35        [        R,                  " S[+        U5       35      s SnA$ SnAff = f)u   创建文件或文件夹r/   r   r   r   Fu   缺少名称参数rZ   Tr)   u	   文件夹u   文件 rd   r   u    创建成功wutf-8encodingNrc   r   u   创建失败: )r   r   rg   r   r   r%   r   r   r   r   r#   rK   rJ   rn   ro   r	   rL   rM   r   rN   rO   rP   rQ   )r   r   r/   r   r   rR   r$   
parent_dirnew_pathrb   frS   s               r   create_file_or_folderr   5  s    D88FD88FBD88NE2L233&C, '-J%n55h;J!J wwz*55bggooh6OPP!.11
J. 77<<
177>>(##!L[h$OqQUPVV`"abbKK40"4&6G hg6! 7v]3G""733	 76
   C  >#a&!:;''.Q(ABBCs8   EG/ *G<!G/ 
G,(G/ /IAIIIz#/<category_id>/knowledge/files/readc                    [         R                  R                  S5      nU(       d  [        S5      e [	        U 5      n[        U5      nU(       d  [        S5      e[        R                  R                  X#5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        S5      e[        R                  R                  U5      (       d  [        S5      e[        R                  R                  U5      (       d  [        S5      e[        USSS9 nUR                  5       nS	S	S	5        [         R"                  " S
W0S9$ ! , (       d  f       N$= f! [        [        4 a    e [$         aW  n[&        R(                  R+                  S[-        U5       35        [         R.                  " S[-        U5       35      s S	nA$ S	nAff = f)u   读取文件内容r   r   rZ   r   r   r[   r   r   Ncontentr,   u   读取文件失败: )r   r   rg   r   r   r%   r   r   r   r   r#   rJ   r
   rs   rn   rp   r	   rL   rM   r   rN   rO   rP   rQ   )r   ry   rR   r$   r   r   r   rS   s           r   read_file_contentr   j  ss      (I233I,#I.
!.11GGLL6	wwy)44RWW__X5NOO!.11ww~~i(( 122ww~~i((!.11)S73qffhG 4 ""G(<== 43 ]+  I  #7Ax!@A''*>s1vh(GHHIs7   DE> >E-E> -
E;7E> >G/AG*$G/*G/z$/<category_id>/knowledge/files/writec                    [         R                  " 5       nUR                  S5      nUR                  SS5      nU(       d  [        S5      e [	        U 5      n[        U5      nU(       d  [        S5      e[        R                  R                  XE5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        S5      e[        R                  " [        R                  R                  U5      SS9  [        USS	S
9 nUR                  U5        SSS5        [        R                   " SS9$ ! , (       d  f       N"= f! [         a    e ["         aW  n[$        R&                  R)                  S[+        U5       35        [        R,                  " S[+        U5       35      s SnA$ SnAff = f)u   写入文件内容r   r   r   r   rZ   Tr)   r   r   r   Nu   文件保存成功r   u   写入文件失败: )r   r   rg   r   r   r%   r   r   r   r   r#   rK   r   rn   ro   r	   rL   rM   r   rN   rO   rP   rQ   )	r   r   ry   r   rR   r$   r   r   rS   s	            r   write_file_contentr     sc    D Ihhy"%G233I,#I.
!.11GGLL6	wwy)44RWW__X5NOO!.11 	BGGOOI.>)S73qGGG 4 ""+?@@ 43   I  #7Ax!@A''*>s1vh(GHHIs8   CE* +E=E* 
E'#E* *G>AG
GG)__doc__r   rk   rq   r   flaskr   r   r   werkzeug.utilsr   app.routes.admin.categoryr   app.middleware.authr   app.utils.responser	   app.utils.exceptionsr
   r   r   r%   routerT   r   r   r   r   r   r    r   r   <module>r      s  
 
    1 1 * 5 7 * ??	 <ugN,L  O,L^ >QDI  RDIN @5'R!I  S!IH >
S'C  T'CT >Q0C  R0Cf <ugN!I  O!IH =xP I  Q Ir   