
    R7_i
                        S r SSKrSSKrSSKJrJrJrJr  SSKJ	r	  SSK
JrJr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Jr  S
 r\" S\SS9rS rSMS jrS r\R?                  SS/S9S 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&\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      S- 5       5       r-\R?                  S.S/S9\S/ 5       5       r.\R?                  S0S/S9\S1 5       5       r/\R?                  S2S/S9\S3 5       5       r0\R?                  S4S/S9\S5 5       5       r1\R?                  S6S/S9\S7 5       5       r2\R?                  S8SS/S9\S9 5       5       r3S: r4S; r5\R?                  S<S/S9\S= 5       5       r6\R?                  S>S/S9\S? 5       5       r7\R?                  S@S/S9\SA 5       5       r8\R?                  SBS/S9\SC 5       5       r9\R?                  SDS/S9\SE 5       5       r:\R?                  SFS/S9\SG 5       5       r;\R?                  SHS/S9\SI 5       5       r<\R?                  SJS/S9\" SK5      SL 5       5       r=g)Nu^   
CTF 方向配置管理 API

提供方向配置、知识库、Prompt 模板的管理接口。
    N)	Blueprintrequestjsonifycurrent_appwraps)dbUserCategoryConfigCategoryAdminRole)CategoryService)PromptCompiler)AuthService)ToolExecutorSandboxConfigc                  ,    [         R                  " 5       $ )u   获取当前用户)r   get_current_user     </Users/yu22x/Desktop/ge/ctf/app/routes/admin/category_api.pyr   r      s    ''))r   category_apiz/api/admin/categories)
url_prefixc                 0   ^  [        T 5      U 4S j5       nU$ )u   管理员权限装饰器c                     > [        5       nU(       a  UR                  [        R                  :w  a  [	        SSS.5      S4$ T" U 0 UD6$ )NFu   需要管理员权限successerror  )r   roler   ADMINr   )argskwargsuserfs      r   decorated_function*admin_required.<locals>.decorated_function   sD    !tyyDJJ.u7NOPRUUU$!&!!r   r   )r%   r&   s   ` r   admin_requiredr(      s!    
1X" "
 r   viewerc                    ^  U 4S jnU$ )u   
方向权限装饰器 - 支持三级权限

权限级别:
- viewer: 只读权限，可查看配置
- editor: 编辑权限，可修改配置
- owner: 管理权限，可管理权限和删除
c                 4   >^  [        T 5      U U4S j5       nU$ )Nc                    > [        5       nU(       d  [        SSS.5      S4$ UR                  [        R                  :X  a  T	" U 0 UD6$ UR                  S5      =(       d    [        R                  R                  S5      nU(       d  T	" U 0 UD6$ [        R                  R                  UUR                  S9R                  5       nU(       d  [        SSS.5      S4$ S	S
SS.nUR                  UR                  S5      nUR                  T
S	5      nXg:  a*  SSSS.n[        SSUR                  T
T
5       S3S.5      S4$ T	" U 0 UD6$ )NF   请先登录r     category_id)r/   user_idu   没有该方向的访问权限r            )r)   editorownerr   u   查看u   编辑u   管理u   需要u   权限)r   r   r    r   r!   getr   	view_argsr   query	filter_byidfirst)r"   r#   r$   r/   admin_recordrole_levels
user_levelrequired_level
role_namesr%   min_roles            r   r&   Kcategory_permission_required.<locals>.decorator.<locals>.decorated_function/   sZ   #%D5>JKSPP yyDJJ&$)&)) **]3[w7H7H7L7L]7[K$)&)) )..88' 9  eg 
  5;[\]_bbb &'!a@K$):):A>J(__Xq9N*(0HxX
$%jnnXx&H%IP    
 d%f%%r   r   )r%   r&   rA   s   ` r   	decorator/category_permission_required.<locals>.decorator.   s"    	q"	& 
"	&F "!r   r   )rA   rC   s   ` r   category_permission_requiredrE   %   s    %"L r   c                 $    [        S5      " U 5      $ )uA   方向管理员权限装饰器（编辑级别）- 兼容旧代码r4   )rE   )r%   s    r   category_admin_requiredrG   W   s    '1!44r    GET)methodsc            
      L   [        5       n U (       d  [        SSS.5      S4$ U R                  [        R                  :X  a  [
        R                  " 5       nO [        R                  " U R                  5      n[        SU Vs/ s H  o"R                  SS9PM     snS.5      $ s  snf )u   获取所有方向列表Fr-   r   r.   Tinclude_config)r   
categories)r   r   r    r   r!   r   get_all_categoriesr   get_user_categoriesr:   to_dict)r$   rN   cs      r   list_categoriesrS   ^   s     D5>BCSHH yyDJJ$779
"66tww?
@JK
1yyy6
K  Ks    B!
z/<category_id>c                     [         R                  " U 5      nU(       d  [        SSS.5      S4$ [        SUR                  SS9S.5      $ )u   获取方向详情F   方向不存在r     TrL   )r   category)r   get_categoryr   rQ   r/   rW   s     r   rX   rX   q   sS     ++K8H53DEFKK$$D$9  r   POSTc                     [         R                  " 5       n U (       d  [        SSS.5      S4$ U R                  S5      nU(       d  [        SSS.5      S4$ [        R
                  R                  U5      nU(       a  [        SSS.5      S4$  [        R                  " U 5      n[        SUR                  5       S	S
.5      $ ! [         a#  n[        S[        U5      S.5      S4s SnA$ SnAff = f)u   创建新方向F   无效的请求数据r     r:   u   方向 ID 不能为空u   方向 ID 已存在Tu   方向创建成功r   rW   message  N)r   get_jsonr   r6   r   r8   r   create_categoryrQ   	Exceptionstr)datar/   existingrW   es        r   rb   rb      s     D53JKLcQQ((4.K53KLMsRR ##''4H53HIJCOOA"2248 ((*+
  	
  A53q6:;S@@As   2B? ?
C,	C'!C,'C,PUTc                 P   [         R                  " 5       nU(       d  [        SSS.5      S4$  [        R                  " X5      nU(       d  [        SSS.5      S4$ [        SUR                  5       SS	.5      $ ! [         a#  n[        S[        U5      S.5      S
4s SnA$ SnAff = f)u   更新方向配置Fr\   r   r]   rU   rV   Tu   方向配置更新成功r^   r`   N)r   ra   r   r   update_categoryrQ   rc   rd   )r/   re   rW   rg   s       r   rj   rj      s     D53JKLcQQA"22;Eu7HIJCOO ((*1
  	
  A53q6:;S@@As#   ,A8 A8 8
B%B B% B%DELETEc                      [         R                  " U 5      nU(       d  [        SSS.5      S4$ [        SSS.5      $ ! [         a#  n[        S[	        U5      S.5      S4s S	nA$ S	nAff = f)
u   删除方向FrU   r   rV   Tu   方向删除成功r   r_   r`   N)r   delete_categoryr   rc   rd   )r/   r   rg   s      r   rn   rn      sv    
A!11+>u7HIJCOO+
  	  A53q6:;S@@As   ,= = 
A*A%A*%A*z/<category_id>/togglec                 4   [         R                  R                  U 5      nU(       d  [        SSS.5      S4$ UR                  (       + Ul        [
        R                  R                  5         [        SUR                  SUR                  (       a  SOS 3S	.5      $ )
u   启用/禁用方向FrU   r   rV   Tu	   方向已u   启用u   禁用)r   enabledr_   )r   r8   r6   r   rp   r	   sessioncommitrY   s     r   toggle_categoryrs      s     ##''4H53DEFKK#+++HJJ##8+;+;xJK  r   z/<category_id>/form-fieldsc                     [         R                  R                  U 5      nU(       d  [        SSS.5      S4$ [        SUR	                  5       UR                  5       S.5      $ )u   获取表单字段配置FrU   r   rV   T)r   form_fieldsform_layout)r   r8   r6   r   get_form_fieldsget_form_layoutrY   s     r   rw   rw      s`     ##''4H53DEFKK//1//1  r   c                    [         R                  " 5       nU(       d  [        SSS.5      S4$ [        R                  R                  U 5      nU(       d  [        SSS.5      S4$ SU;   a  UR                  US   5        SU;   a  UR                  US   5        [        R                  R                  5         [        S	S
S.5      $ )u   更新表单字段配置Fr\   r   r]   rU   rV   ru   rv   Tu   表单配置更新成功rm   )r   ra   r   r   r8   r6   set_form_fieldsset_form_layoutr	   rq   rr   )r/   re   rW   s      r   update_form_fieldsr|      s     D53JKLcQQ##''4H53DEFKK  m!45  m!45JJ-  r   z/<category_id>/stagesc                     [         R                  R                  U 5      nU(       d  [        SSS.5      S4$ [        SUR	                  5       S.5      $ )u   获取阶段配置FrU   r   rV   T)r   stages)r   r8   r6   r   
get_stagesrY   s     r   r   r      sT     ##''4H53DEFKK%%'  r   c                    [         R                  " 5       nU(       a  SU;  a  [        SSS.5      S4$ [        R                  R                  U 5      nU(       d  [        SSS.5      S4$ UR                  US   5        SS	KJn   UR                  U5        [        R                  R!                  5         [        SSS.5      $ ! [         a+  nSS
KnUR                  S[        U5       35         S
nAN\S
nAff = f)u   更新阶段配置r~   Fr\   r   r]   rU   rV   r   PromptCompilerServiceN   自动编译 Prompt 失败: Tu   阶段配置更新成功rm   )r   ra   r   r   r8   r6   
set_stages$app.services.prompt.compiler_servicer   compile_and_save_promptsrc   loggingwarningrd   r	   rq   rr   )r/   re   rW   r   rg   r   s         r   update_stagesr     s     D84'53JKLcQQ##''4H53DEFKKX' KA66x@ JJ-    A6s1vh?@@As   C 
C6!C11C6z/importc                     [         R                  " 5       n U (       d  [        SSS.5      S4$ U R                  S5      nU R                  SS5      nU(       d  [        SSS.5      S4$ UR                  S	5      (       d  [        SS
S.5      S4$ UR                  S5      (       d  [        SSS.5      S4$ US	   n[        R
                  R                  U5      n U(       a  US:X  a  [        SSU S3S.5      S4$ US:X  aT  [        R                  R                  U5        [        R                  R                  5         [        R                  " U5      nO-[        R                  " X15      nO[        R                  " U5      n[        SUR                  5       SUR                   S3S.5      $ ! [         aD  n[        R                  R!                  5         [        SS[#        U5       3S.5      S4s SnA$ SnAff = f)u0   导入方向配置（JSON）- 支持单个配置Fr\   r   r]   configmodecreate   缺少配置数据r:      配置必须包含 id 字段name   配置必须包含 name 字段   方向 u+    已存在，请选择覆盖或合并模式	overwriteT    导入成功r^      导入失败: r`   N)r   ra   r   r6   r   r8   r	   rq   deleterr   r   rb   rj   rQ   r   rc   rollbackrd   )re   r   r   r/   rf   rW   rg   s          r   import_categoryr   /  s    D53JKLcQQXXhF88FH%D53GHI3NN ::d53QRSUXXX::f53STUWZZZ,K##''4HTx5W[MQ|;}~  BE  E  E$

!!(+

!!#*::6B +::;O '66v>H ((* }=
  	
  T


5^CF83LMNPSSSTs%    F+ 9B1F+ +
G959G4.G94G9z/import-batchc            
         [         R                  " 5       n U (       d  [        SSS.5      S4$ U R                  S5      nU R                  SS5      nU(       d  [        SSS.5      S4$ [	        U[
        5      (       d  [        SS	S.5      S4$ [        U5      S
:X  a  [        SSS.5      S4$ / / [        U5      S.n[        U5       GH  u  pE UR                  S5      (       d  US   R                  US-   SSS.5        M:  UR                  S5      (       d,  US   R                  US-   UR                  S5      SS.5        M|  US   n[        R                  R                  U5      nU(       a  US:X  a(  US   R                  US-   UUR                  SS.5        M  US:X  aT  [        R                  R                  U5        [        R                  R                  5         [         R"                  " U5      nO-[         R$                  " Xe5      nO[         R"                  " U5      nUS   R                  US-   UUR                  SUR                   S3S.5        GM     [        US   5      n
[        US   5      n[        US
:H  USU
 SU S 3S!.5      $ ! [&         aa  n	[        R                  R)                  5         US   R                  US-   UR                  SS5      S[+        U	5       3S.5         Sn	A	GM0  Sn	A	ff = f)"u(   批量导入方向配置（JSON数组）Fr\   r   r]   configsr   r   r   u!   配置数据必须是数组格式r   u   配置数组不能为空)r   failedtotalr:   r   r1   Nr   )indexr:   r   r   r   u0   方向已存在，请选择覆盖或合并模式)r   r:   r   r   r   r   r   r   )r   r:   r   r_   u   未知r   u   批量导入完成：成功 u    个，失败 u    个)r   resultsr_   )r   ra   r   r6   
isinstancelistlen	enumerateappendr   r8   r   r	   rq   r   rr   r   rb   rj   rc   r   rd   )re   r   r   r   idxr   r/   rf   rW   rg   success_countfailed_counts               r   import_categories_batchr   a  s    D53JKLcQQhhy!G88FH%D53GHI3NN gt$$53VWXZ]]]
7|q53MNOQTTT WG !)7	::d##!(( 1W;* 
 ::f%%!(( 1W **T*=* 
  ,K%++//<H8#H%,,!$q) (#S	.  [(JJ%%h/JJ%%'.>>vFH  />>{SH +::6BI%%q! $X]]O=A	' W *v 	*+Mwx()L1$1-|n\`a    	JJ!H$$qjjx0)#a&2&  	s.   1J?A JAJB;J
K:AK55K:z/exportc                      [         R                  R                  [         R                  5      R	                  5       n / nU  GH[  n0 SUR
                  _SUR                  _SUR                  _SUR                  _SUR                  _SUR                  _SUR                  5       _SUR                  5       _S	UR                  5       _S
UR                  5       _SUR                  5       _SUR                  _SUR                   _SUR"                  _SUR$                  _SUR&                  _nUR)                  5       nU(       a#  [+        UR-                  5       5      (       a  XCS'   O&UR/                  5       US'   UR1                  5       US'   UR3                  U5        GM^     [5        SU[7        U5      S.5      $ ! [8         a#  n[5        S[;        U5      S.5      S4s SnA$ SnAff = f)u(   导出所有方向配置（JSON数组）r:   r   icondescriptionrp   
sort_orderru   rv   output_config	ui_configadvanced_configprompt_template_pathknowledge_base_pathknowledge_db_pathchoice_script_path
output_dirdifficultiesr~   difficulty_rulesT)r   r   countFr   r`   N)r   r8   order_byr   allr:   r   r   r   rp   rw   rx   get_output_configget_ui_configget_advanced_configr   r   r   r   r   get_difficultiesanyvaluesr   get_difficulty_rulesr   r   r   rc   rd   )rN   r   rW   r   r   rg   s         r   export_all_categoriesr     s   'A#))22>3L3LMQQS
"Hhkk  x33	
 8++ h11 x779 x779  !;!;!= X335 "8#?#?#A '(E(E &x'C'C $X%?%? %h&A&A  h11!F& $446LL$7$7$9 : :)5~& $,#6#6#8x -5-J-J-L)*NN6"7 #: \
  	
  A53q6:;S@@As   F6F9 9
G&G!G&!G&z/<category_id>/exportc                    SSK Jn  SSKnSSKJn  [        R
                  R                  U 5      nU(       d  [        SSS.5      S4$ 0 S	UR                  _S
UR                  _SUR                  _SUR                  _SUR                  _SUR                  _SUR                  5       _SUR                  5       _SUR!                  5       _SUR#                  5       _SUR%                  5       _SUR&                  _SUR(                  _SUR*                  _SUR,                  _SUR.                  _nUR1                  5       nU(       a#  [3        UR5                  5       5      (       a  XeS'   O&UR7                  5       US'   UR9                  5       US'   UR:                  " USSS9nUR=                  5       R?                  S5      nU  SU S 3n	U" US!S"U	 S#3S$S%.S&9n
U
$ )'u0   导出方向配置（直接下载 JSON 文件）r   )ResponseN)datetimeFrU   r   rV   r:   r   r   r   rp   r   ru   rv   r   r   r   r   r   r   r   r   r   r~   r   r2   )ensure_asciiindentz%Y%m%d_%H%M%S_category_config_z.jsonzapplication/jsonzattachment; filename=""zapplication/json; charset=utf-8)zContent-DispositionzContent-Typemimetypeheaders) flaskr   jsonr   r   r8   r6   r   r:   r   r   r   rp   r   rw   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   dumpsnowstrftime)r/   r   r   r   rW   r   r   json_str	timestampfilenameresponses              r   export_categoryr     s+    !##''4H53DEFKKhkk 	 	x++	
 	8## 	h)) 	x//1 	x//1 	335 	X++- 	8779 	 = = 	x;; 	X77 	h99  	h))!F& ,,.LL//122!-~ $..0x%-%B%B%D!" zz&uQ?H ''8I/	{%@H #%;H:Q#G=
H Or   z/<category_id>/prompts/compilec           	         [         R                  " 5       =(       d    0 n [        5       nSU;   a&  UR                  US   U UR	                  S5      5      nO UR                  XR	                  S5      5      n[        SU[        UR                  S5      5      [        U5      S.S.5      $ ! [         a#  n[        S[        U5      S.5      S	4s S
nA$ S
nAff = f)u   编译 Prompt 模板template_content
user_inputT
)total_linestotal_chars)r   compiled_promptstatsFr   r`   N)r   ra   r   compile_from_templater6   compiler   r   splitrc   rd   )r/   re   compilercompiledrg   s        r   compile_promptr   6  s     #DA!# %55'(&H  ''XXl5KLH'"8>>$#78"8}
  	  A53q6:;S@@As   BB) )
C3CCCz/<category_id>/prompts/validatec                    [         R                  " 5       nU(       a  SU;  a  [        SSS.5      S4$ [        R                  R                  U 5      nU(       d  [        SSS.5      S4$  [        5       nUR                  US   UR                  SS	95      n[        SUS
.5      $ ! [         a#  n[        S[        U5      S.5      S4s SnA$ SnAff = f)u)   验证 Prompt 模板与配置的一致性r   Fu   请提供模板内容r   r]   rU   rV   TrL   )r   
validationr`   N)r   ra   r   r   r8   r6   r   validate_templaterQ   rc   rd   )r/   re   rW   r   resultrg   s         r   validate_promptr   U  s     D%T153JKLcQQ##''4H53DEFKKA!#++#$D1

  
  	  A53q6:;S@@As   *9B$ $
C.CCCz/initc                       [         R                  " 5         [        SSS.5      $ ! [         a#  n [        S[	        U 5      S.5      S4s Sn A $ Sn A ff = f)u   初始化默认方向配置Tu!   默认方向配置初始化成功rm   Fr   r`   N)r   init_default_categoriesr   rc   rd   )rg   s    r   init_categoriesr   z  sY    A//1:
  	  A53q6:;S@@As   "% 
AAAAz/<category_id>/stage-promptsc                 >   SSK Jn  [        R                  R	                  U 5      nU(       d  [        SSS.5      S4$ UR                  5       =(       d    / nUR                  5       =(       d    0 nUR                  X5      n[        SUUR	                  SS	5      S
.5      $ )uG   获取阶段 Prompt 配置（包含系统固定部分和用户扩展）r   StagePromptGeneratorFrU   r   rV   Tglobal_rulesrH   )r   r~   r   )	app.services.prompt.generatorr   r   r8   r6   r   r   r   generate_all_stages)r/   r   rW   r~   advancedresult_stagess         r   get_stage_promptsr     s     C##''4H53DEFKK  "(bF++-3H )<<[QM ^R8  r   z/<category_id>/stage-extensionsc                    [         R                  R                  U 5      nU(       d  [        SSS.5      S4$ [        R
                  " 5       nUR                  S0 5      nUR                  SS5      n UR                  5       =(       d    / nU H#  nUR                  SS5      nXs;   d  M  X7   US	'   M%     [        R                  " U5      Ul	        UR                  5       =(       d    0 nXHS'   [        R                  " U5      Ul        S
SKJn	   U	R                  U5        [&        R(                  R+                  5         [        SSS.5      $ ! [         a+  n
S
SKnUR#                  S[%        U
5       35         Sn
A
N\Sn
A
ff = f! [         aA  n
[&        R(                  R-                  5         [        S[%        U
5      S.5      S4s Sn
A
$ Sn
A
ff = f)u'   保存阶段扩展内容和全局规则FrU   r   rV   
extensionsr   rH   r:   user_extensionr   r   Nr   Tu   Prompt 配置保存成功rm   r`   )r   r8   r6   r   r   ra   r   r   r   r~   r   r   r   r   r   rc   r   r   rd   r	   rq   rr   r   )r/   rW   re   r   r   r~   stagestage_idr   r   rg   r   s               r   save_stage_extensionsr     s    ##''4H53DEFKKD,+J88NB/L$A$$&," Eyyr*H%*4*>&'  **V, //17R#/ #'::h#7  	O	E!::8D 	

 2
  	  	EOO:3q6(CDD	E  A


53q6:;S@@AsO   13F (A$F E
 +F 

E?!E:5F :E??F 
G6GGGz/<category_id>/compile-promptc                    SSK Jn  [        R                  R	                  U 5      nU(       d  [        SSS.5      S4$  [        R                  S:X  a  [        R                  " 5       =(       d    0 O0 nUR	                  SS5      nU(       a)  UR	                  S	S
5      nUR	                  S/ 5      nUnUnODUR                  5       =(       d    / nUR                  5       =(       d    0 n	U	R	                  S	S
5      nUR                  5       =(       d    0 n	U(       Gap  UR	                  SS5      n
/ nU GHT  nUR	                  SS
5      UR	                  SS
5      UR	                  SS
5      UR	                  SS
5      UR	                  SS5      UR	                  S	S
5      UR	                  SS
5      S.nU
(       a9  UR	                  SS
5      nU(       a  US   (       a  US==   SU-   -  ss'   OXS'   OUR	                  S0 5      nU(       al  [        U[        5      (       aW  SnS H  nUU;   d  M  UU   n  O   U(       a8  UR	                  SS
5      nU(       a  US   (       a  US==   SU-   -  ss'   OXS'   UR                  U5        GMW     OUR                  X5      nUR                  5       =(       d    / nUR!                  5       =(       d    0 nS
nU HW  nUSUR	                  SS
5       SUR	                  SS5       SUR	                  SS 5       S!UR	                  S"SS /5       S#3	-  nMY     UR"                  U S$S%S&S'S(S)S*S+US,UR	                  S-S.S//5      UR	                  S0S15      UR	                  S2S35      S4.nSnU H  nUR	                  S5      S5:X  d  M  Un  O   U(       aQ  UR	                  S6S
5      R%                  5       nU(       a*  UR	                  S5      (       a  US-   US   -   US'   OUUS'   UR'                  XUU(       a  UOS5      n[        S7US8.5      $ ! [(         a7  nSSKnUR-                  5         [        S[/        U5      S.5      S94s SnA$ SnAff = f):u%   编译完整的 Prompt（预览用）r   r   FrU   r   rV   rZ   use_current_editssystem_promptrH   r~   is_new_formatr:   r   r   output_formatskip_forbiddenr   )r:   r   r   outputr   r   r   prompt

promptsN)   中等u   简单u   入门u   困难mediumeasybeginnerhardcontentz| z | 	max_countr1   u    个 | writeup_count   u    篇 | depth_rangez |
r  PHPu   SQL注入, XSSu   博客系统   r3   z
[4.0, 7.0]g?zPHP, Python, Node.js, Go, Java
port_rangei  ih  flag_formatzDASCTF{...}directory_patternz{timestamp}_{name})rW   r/   
difficultylanguageknowledge_pointsscener  max_knowledger  	diff_ratedifficulty_tableavailable_languagesr  r  r  knowledge_acquisitionknowledge_script_instructionT)r   r  r`   )r   r   r   r8   r6   r   r   methodra   r   r   r   dictr   r   r   r   r   stripcompile_full_promptrc   	traceback	print_excrd   )r/   r   rW   re   r   current_system_promptcurrent_stagesr~   r   r   r   full_stages
stage_data
stage_infoprompt_contentr  r  diffr   r   r  rulecontextknowledge_stager   script_instructionrg   r!  s                               r   r   r     s    C##''4H53DEFKKCA+2>>V+Cw!'R HH%8%@ $(HH_b$A!!XXh3N $F1M ((*0bF335;H$LL"=M//17R  HH_e<MK$
$..r2&NN626#->>-#D(nn_bA&0nn5Eu&M%/^^OR%H&0nn5Er&J
 !%/^^Hb%AN%%&67&'78F^<SS8;I'78 )nnY;G:gt#<#<!%$rD#w)0 % %s
 "-3ZZ	2-FN-#-.>#?$./?$@F^D[$[$@CQ/?$@"":.O %R /BB;WK $88:@b 224: $D"TXXfb%9$:#dhh{TU>V=WW^_c_g_ghwyz_{^|  }D  EI  EM  EM  N[  ^_  ab  ]c  Ed  De  ei  !j  j % !&" 0#' 0#C'++L5%.I(,,]MJ!.!2!23FH\!]
&  Eyy"99"' ! !0!4!45SUW!X!^!^!` ""&&'7888JV8SVefvVw8wO$458JO$45 &99g*M
 
  	  A53q6:;S@@As,   G(P *E)P BP 
Q ),QQ Q c           	         [         R                  R                  [        5      n[         R                  R	                  [         R                  R	                  [         R                  R	                  [         R                  R	                  U5      5      5      5      n[         R                  R                  US5      n[         R                  R                  X0S5      $ )u   获取data文件夹路径ge10re   )ospathabspath__file__dirnamejoin)r/   current_filectf_dir	base_paths       r   get_data_dirr9  l  sv    77??8,Lggoobggoobggoobggool>[.\]^GWf-I77<<	77r   c                     U (       d  g[         R                  R                  U 5      nSU;   d  UR                  S5      (       a  gU$ )u*   规范化路径，防止路径遍历攻击rH   ../N)r0  r1  normpath
startswith)r1  
normalizeds     r   normalize_pathr@  s  s=    !!$'JzZ22377r   z#/<category_id>/knowledge/files/treec                   ^  [        U 5      n[        R                  R                  U5      (       d#  [        R                  " USS9  [        S/ S.5      $ SU4S jjmT" U5      n[        SUS.5      $ ! [         ac  nSSKn[        R                  R                  S[        U5       SUR                  5        35        [        S	[        U5      S
.5      S4s SnA$ SnAff = f)u   获取文件树结构Texist_ok)r   treec           	      $  > / 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)r   typer1  childrenfile)r   rG  r1  sizemodifiedc                 8    U S   S:H  U S   R                  5       4$ )NrG  rI  r   )lower)xs    r   <lambda>3get_file_tree.<locals>.build_tree.<locals>.<lambda>  s    &	V0CQvY__EV/Wr   )key)sortedr0  listdirr1  r5  isdirr   statst_sizest_mtimePermissionError)	r1  relative_pathitemsitem	item_pathitem_rel_pathrH  rU  
build_trees	           r   r^  !get_file_tree.<locals>.build_tree  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r   Nu   获取文件树失败: r   Fr   r`   )rH   )r9  r0  r1  existsmakedirsr   rc   r!  r   loggerr   rd   
format_exc)r/   data_dirrD  rg   r!  r^  s        @r   get_file_treere  ~  s    1A,ww~~h''KK40  
	Y< (#
  	  A  #:3q6("YEYEYE[D\!]^53q6:;S@@As%   AA3 A3 3
C =ACC C z%/<category_id>/knowledge/files/uploadc           	         SSK Jn  SSKnSSKnSSKnS[
        R                  ;  a  [        SSS.5      S4$ [
        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SS.5      S4$  [        U 5      nU(       aB  [        U5      n	U	(       d  [        SSS.5      S4$ [        R                  R!                  X5      n
OUn
[        R"                  " U
SS9  U" UR                  5      n[        R                  R!                  X5      nU(       Gay  US-   nUR%                  U5        Sn/ n UR                  5       R'                  S5      (       Ga9  U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!                  U
U5      nUR'                  S5      (       a  [        R"                  " USS9  M  [        R"                  " [        R                  R1                  U5      SS9  UR3                  U5       n[3        US5       nUR5                  UR7                  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ap  UR                  5       R'                  S5      (       a  SOSnUR3                  UU5       nUR9                  5        GH  nSUR:                  ;   d   UR:                  R-                  S5      (       a  UR/                  UR:                  5        MQ  [        R                  R!                  U
UR:                  5      n[        R                  R=                  U5      R-                  [        R                  R=                  U5      5      (       d  UR/                  UR:                  5        M  UR?                  UU
5        URA                  5       (       d  GM  US-  nGM     SSS5        O&[        RB                  " U5        [        SSS.5      S4$ [        RB                  " U5        SU S3nU(       a  US[E        U5       S3-  n[        SUUUS .5      $ [        R                  RI                  U5      (       a  [        SS!U S"3S.5      S4$ UR%                  U5        [        RJ                  " U5      n[        R                  RM                  X5      n[        SUUURN                  URP                  S#.S!U S$3S%.5      $ ! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GN"= f! , (       d  f       GN4= f! [F         aA  n[        R                  RI                  U5      (       a  [        RB                  " U5        UeSnAff = f! [F         ac  nSSK)n[T        RV                  RY                  S&[[        U5       S'UR]                  5        35        [        S[[        U5      S.5      S(4s SnA$ SnAff = f))u:   上传文件到data文件夹，支持压缩包自动解压r   )secure_filenameNrI  Fu   请选择文件r   r]   r1  rH   extractfalsetrue   非法路径TrB  z.tmpz.ziprr;  r<  wbr1   )z.tar.tar.gz.tgz)rn  ro  zr:gzu;   不支持的压缩包格式，仅支持 .zip, .tar, .tar.gzu"   压缩包解压成功，共解压 u
    个文件u   ，u    个文件因安全原因跳过)r   extracted_counterror_filesr_      文件 
    已存在)r   r1  rJ  rK  u    上传成功)r   rI  r_   u   上传文件失败: r   r`   )/werkzeug.utilsrg  zipfiletarfileshutilr   filesr   formr6   rM  r   r9  r@  r0  r1  r5  ra  saveendswithZipFilenamelistr>  r   r4  openwriteread
getmembersr   r2  rh  isfileremover   rc   r`  rU  relpathrV  rW  r!  r   rb  r   rd   rc  )r/   rg  ru  rv  rw  rI  rY  rh  rd  r?  save_dirsafe_filename	file_path	temp_pathrp  rq  zip_ref	file_listmembertarget_pathsourcetargetr   tar_refr_   rg   rU  file_rel_pathr!  s                                r   upload_knowledge_filer    sC    /W]]"53DEFKK== DLL$$VR0Mlly'288:fDG}}53DEFKKyA, '6J5>JKSPPww||H9HH
Ht,'6GGLL9	 !F*IIIi OKD &&(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;; ? (#OOFH=%}} /1 4 '; 76( IIi("u?|#}~  AD  D  D 		)$>>OzZS%5$66UVVG#'6#.&	     ww~~i((5W]OS];^_`beeeIIi 779%DGGOOI@M)) LL $	 %]O=A	 	 	y F]E\%9%9% 980 76J  77>>),,IIi(	8  A  #7Axr)BVBVBXAY!Z[53q6:;S@@As   <3X 0B
X ;7W 2CV'V V	5V=V'A)W 8DV9
V9%.W AW 7X A1X 
VV
V$V''
V61W 9
WW 
X<XXX 
Z#AZ;ZZz'/<category_id>/knowledge/files/downloadc                    SSK Jn  [        R                  R	                  S5      nU(       d  [        SSS.5      S4$  [        U 5      n[        U5      nU(       d  [        SSS.5      S4$ [        R                  R                  X45      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        SSS.5      S	4$ [        R                  R                  U5      (       d  [        SS
S.5      S4$ [        R                  R                  U5      (       d  [        SSS.5      S4$ [        R                  R                  U5      nU" USUS9$ ! [          ac  nSSKn[$        R&                  R)                  S[+        U5       SUR-                  5        35        [        S[+        U5      S.5      S4s SnA$ SnAff = f)u   下载文件r   )	send_filer1  F   缺少路径参数r   r]   rk  r      文件不存在rV      不是文件T)as_attachmentdownload_nameNu   下载文件失败: r   r`   )r   r  r   r"   r6   r   r9  r@  r0  r1  r5  r2  r>  r`  r  basenamerc   r!  r   rb  r   rd   rc  )	r/   r  r  rd  r?  	full_pathr   rg   r!  s	            r   download_knowledge_filer  E  s       (I53GHI3NNA, $I.
u~FGLLGGLL6	 wwy)44RWW__X5NOOu~FGLLww~~i((u7HIJCOOww~~i((u~FGLL77##I.$hOO A  #7Axr)BVBVBXAY!Z[53q6:;S@@As7   ,E9 +A>E9 *3E9 3E9 &E9 9
G&AG!G&!G&z%/<category_id>/knowledge/files/deletec                 P   [         R                  " 5       nUR                  S5      nUR                  SS5      nU(       d  [        SSS.5      S4$  [	        U 5      n[        U5      nU(       d  [        SSS.5      S4$ [        R                  R                  XE5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        SSS.5      S4$ [        R                  R                  U5      (       d  [        SS	S.5      S
4$ U(       a9  SSKnUR                  U5        S[        R                  R                  U5       S3nO9[        R                  " U5        S[        R                  R                  U5       S3n[        SUS.5      $ ! [          ac  n	SSKn
[$        R&                  R)                  S[+        U	5       SU
R-                  5        35        [        S[+        U	5      S.5      S4s Sn	A	$ Sn	A	ff = f)u   删除文件或文件夹r1  is_directoryFr  r   r]   rk  r   u   文件或文件夹不存在rV   r   N
   文件夹 u    删除成功rr  Trm   u   删除失败: r   r`   )r   ra   r6   r   r9  r@  r0  r1  r5  r2  r>  r`  rw  rmtreer  r  rc   r!  r   rb  r   rd   rc  )r/   re   r  r  rd  r?  r  rw  r_   rg   r!  s              r   delete_knowledge_filer  l  s    D I88NE2L53GHI3NN!A, $I.
u~FGLLGGLL6	 wwy)44RWW__X5NOOu~FGLLww~~i((u7TUVX[[[ MM)$"277#3#3I#>"?}MGIIi  0 0 ;<MJG
  	  A  >#a&I<P<P<R;S!TU53q6:;S@@As3   ,F8 >A>F8 =3F8 1BF8 8
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SS.5      S4$  [	        U 5      nU(       aB  [        U5      nU(       d  [        SS	S.5      S4$ [        R                  R                  XV5      nOUn[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        SS	S.5      S
4$ [        R                  " USS9  [        R                  R                  Xr5      n[        R                  R                  U5      (       a  [        SU(       a  SOS SU S3S.5      S4$ 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	[        SU	S.5      $ ! , (       d  f       N"= f! [         ac  nSSKn["        R$                  R'                  S[)        U5       SUR+                  5        35        [        S[)        U5      S.5      S4s SnA$ SnAff = f)u   创建文件或文件夹r   r1  rH   r  Fu   缺少名称参数r   r]   rk  r   TrB  u	   文件夹u   文件 rs  r  u    创建成功wutf-8encodingNrr  rm   r   u   创建失败: r   r`   )r   ra   r6   r   r9  r@  r0  r1  r5  r2  r>  ra  r`  r~  r  rc   r!  r   rb  r   rd   rc  )r/   re   r   r1  r  rd  r?  
parent_dirnew_pathr_   r%   rg   r!  s                r   create_file_or_folderr    s    D88FD88FBD88NE2L53GHI3NN(A, '-J5>JKSPPh;J!J wwz*55bggooh6OPPu~FGLL
J. 77<<
177>>(##u+[c9ddefjekku7vwxz}}}KK40"4&6G hg6! 7v]3G
  		 76  A  >#a&I<P<P<R;S!TU53q6:;S@@AsK   #3G= BG= A6G= .G= >G,G= ,
G:6G= =
I*AI%I*%I*z#/<category_id>/knowledge/files/readc                    [         R                  R                  S5      nU(       d  [        SSS.5      S4$  [	        U 5      n[        U5      nU(       d  [        SSS.5      S4$ [        R                  R                  X#5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        SSS.5      S4$ [        R                  R                  U5      (       d  [        SSS.5      S	4$ [        R                  R                  U5      (       d  [        SS
S.5      S4$ [        USSS9 nUR                  5       nSSS5        [        SWS.5      $ ! , (       d  f       N= f! [         ac  nSSKn["        R$                  R'                  S[)        U5       SUR+                  5        35        [        S[)        U5      S.5      S4s SnA$ SnAff = f)u   读取文件内容r1  Fr  r   r]   rk  r   r  rV   r  rl  r  r  NT)r   r	  r   u   读取文件失败: r   r`   )r   r"   r6   r   r9  r@  r0  r1  r5  r2  r>  r`  r  r~  r  rc   r!  r   rb  r   rd   rc  )	r/   r  rd  r?  r  r%   r	  rg   r!  s	            r   read_file_contentr    s      (I53GHI3NNA,#I.
u~FGLLGGLL6	wwy)44RWW__X5NOOu~FGLLww~~i((u7HIJCOOww~~i((u~FGLL)S73qffhG 4 
  	 43  A  #7Axr)BVBVBXAY!Z[53q6:;S@@AsO   ,F %A>F $3F 3F F E>(F >
FF 
G<AG71G<7G<z$/<category_id>/knowledge/files/writec                    [         R                  " 5       nUR                  S5      nUR                  SS5      nU(       d  [        SSS.5      S4$  [	        U 5      n[        U5      nU(       d  [        SSS.5      S4$ [        R                  R                  XE5      n[        R                  R                  U5      R                  [        R                  R                  U5      5      (       d  [        SSS.5      S	4$ [        R                  " [        R                  R                  U5      S
S9  [        USSS9 nUR                  U5        SSS5        [        S
SS.5      $ ! , (       d  f       N= f! [         ac  nSSKn	["        R$                  R'                  S[)        U5       SU	R+                  5        35        [        S[)        U5      S.5      S4s SnA$ SnAff = f)u   写入文件内容r1  r	  rH   Fr  r   r]   rk  r   TrB  r  r  r  Nu   文件保存成功rm   r   u   写入文件失败: r   r`   )r   ra   r6   r   r9  r@  r0  r1  r5  r2  r>  ra  r4  r~  r  rc   r!  r   rb  r   rd   rc  )
r/   re   r  r	  rd  r?  r  r%   rg   r!  s
             r   write_file_contentr    s    D Ihhy"%G53GHI3NNA,#I.
u~FGLLGGLL6	wwy)44RWW__X5NOOu~FGLL 	BGGOOI.>)S73qGGG 4 +
  	 43  A  #7Axr)BVBVBXAY!Z[53q6:;S@@AsD   ,E3 >A>E3 ==E3 :E"E3 "
E0,E3 3
G =AGG G z/<category_id>/knowledge/shellr5   c                   ^^^^ SSK JnJn  SSKmSSKnSSKn[        R                  " 5       =(       d    0 nUR                  S5      =(       d    SR                  5       mUR                  S5      =(       d    SR                  5       nUR                  S5      nT(       d  [        SS	S
.5      S4$  [        U 5      n[        R                  " USS9  UmU(       aA  [        U5      n	U	(       d  [        SSS
.5      S4$ [        R                  R!                  X5      m[        R                  R#                  T5      R%                  [        R                  R#                  U5      5      (       d  [        SSS
.5      S4$ [        R                  " TSS9  [&        R(                  " U [&        R*                  " 5       S9n
U
R-                  TTS9u  pU(       d  [        SSU 3S
.5      S4$ T(       a&  U
R/                  T5      (       d  [        SSS
.5      S4$ U
R1                  T5      mU(       a  [3        UT5      mUUUU4S jnU" U" U" 5       5      SSSS.S9$ ! [4         ac  nSSKn[8        R:                  R=                  S[?        U5       SURA                  5        35        [        S[?        U5      S
.5      S4s SnA$ SnAff = f)uT   在知识库目录下执行命令（管理员/方向所有者）- 流式输出版本r   )r   stream_with_contextNcommandrH   cwdtimeoutFu   命令不能为空r   r]   TrB  u   非法工作目录u!   工作目录不在允许范围内)r/   policy)working_diru   命令被拒绝: c               3     >#     [         R                  R                  5       n SU S'   SU S'   T
R                  T	STT
R                  T
R
                  SSU S9nS[        R                  " S	T	S
.5       S3v   SSKnUR                  5       n T(       a[  UR                  5       U-
  T:  aD  UR                  5         UR                  5         S[        R                  " SST S3S.5       S3v   gUR                  5       bj  UR                  R                  5       nU(       a  S[        R                  " SUS.5       S3v   S[        R                  " SUR                  S.5       S3v   gUR                  R                  5       nU(       a   S[        R                  " SUS.5       S3v   OUR!                  S5        GM2  ! ["         au  nSSKn[&        R(                  R+                  S[-        U5       SUR/                  5        35        S[        R                  " SS[-        U5       3S.5       S3v    SnAgSnAff = f7f)u*   生成流式输出 - 真正的实时输出catPAGER1PYTHONUNBUFFEREDTr   )shellr  stdoutstderrtextbufsizeenvzdata: start)rG  r  r  Nr   u   命令执行超时 (u   秒))rG  r_   r   )rG  re   done)rG  return_codeg{Gz?u   流式执行命令失败: r   u   执行错误: )r0  environcopyPopenPIPESTDOUTr   r   timekillwaitpollr  r  
returncodereadlinesleeprc   r!  r   rb  r   rd   rc  )r  processr  
start_time	remaininglinerg   r!  actual_timeoutr  
subprocessr  s           r   generate)execute_knowledge_shell.<locals>.generateW  s'    7ijjoo'$G*-&' %**#%??%,, + 	 tzz7w*OPQQUVV !YY[
%499;+C~*U &tzz7QefteuuyOz2{'|&}  ~B  C  C ||~1$+NN$7$7$9	$$*4::xQZ6[+\*]]a"bb &tzz6RYRdRd2e'f&ggkll #>>224D &tzz8T2R'S&TTXYY 

4(3 6  i ""((+Ec!fXRPYPdPdPfOg)hitzz7X[\]X^W_G`*abccghhisD   H?C'F= ,H?-A:F= 'H?(AF= =
H<A+H72H?7H<<H?ztext/event-streamzno-cacheno)zCache-ControlzX-Accel-Bufferingr   u   知识库命令执行失败: r   r`   )!r   r   r  r  	threadingqueuer   ra   r6   r  r   r9  r0  ra  r@  r1  r5  r2  r>  r   create_for_knowledge_baseload_policyis_command_allowedis_path_allowedget_timeoutminrc   r!  r   rb  r   rd   rc  )r/   r   r  r  r  payloadr  r  rd  r?  sandboxallowedreasonr  rg   r!  r  r  r  r  s                   @@@@r   execute_knowledge_shellr  !  sn    4 &BG{{9%+224G;;u#
*
*
,Ckk)$G53GHI3NNlA,
Ht,',J5;OPQSVVV'',,x<K ww{+66rwwx7PQQu7Z[\^aaa
K$/  99# ,,.
 "44W+4Vu9J6(7STUWZZZ w66{CCu7Z[\^aaa !,,W5 .9N9	i 9	iv 
+(!+%)
 	
  A  #@Q9K_K_KaJb!cd53q6:;S@@As;   0A
I ;A>I :A(I #,I AI 
K AJ;5K ;K )r)   )>__doc__r   r0  r   r   r   r   r   	functoolsr   app.models.database.modelsr	   r
   r   r   r   app.services.categoryr   app.services.promptr   app.services.authr   app.services.ai.toolsr   r   r   __name__category_api_bpr(   rE   rG   routerS   rX   rb   rj   rn   rs   rw   r|   r   r   r   r   r   r   r   r   r   r   r   r   r9  r@  re  r  r  r  r  r  r  r  r   r   r   <module>r     s  
  	 : :   2 . ) =* NHAXY/d5 rE7+ ,$ '%9	  :	 rF8,A  -A4 '%9A  :A( '(<A  =A .A  B$ 3eWE
  F
 3eWE  F2 .@	  A	 .@  A> y6(3-T  4-T` 9\  :\~ y5'2)A  3)AX .@h'7 ( A7H 7&JA  KA: 86(KA  LAF w1	A  2	A 5wG  H* 86(K.A  L.Ab 6PKA  QKAl8	 <ugN3A  O3Al >QJA  RJAZ @5'R"A  S"AJ >
S*A  T*AZ >Q2A  R2Aj <ugN#A  O#AL =xP"A  Q"AJ 7&Jg&{A ' K{Ar   