
    [7_i(B                     |    S r SSKJrJr  SSKJrJr   " S S\R                  5      r " S S\R                  5      r	g)	u]   
CTF 方向配置相关模型

包含方向配置、知识库、Prompt 模板等相关模型
   )dbget_beijing_now)UserRolec                      \ rS rSrSrSr\R                  " \R                  " S5      SS9r	\R                  " \R                  " S5      SS	9r
\R                  " \R                  " S5      S
S9r\R                  " \R                  5      r\R                  " \R                  SS9r\R                  " \R                   SS9r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  5      r\R                  " \R                  " S5      5      r\R                  " \R                  " S5      5      r\R                  " \R                  " S5      5      r\R                  " \R                  " S5      5      r\R                  " \R                  " S5      5      r\R                  " \R@                  \!S9r"\R                  " \R@                  \!\!S9r#S*S jr$S r%S r&S r'S r(S r)S r*S r+S r,S r-S r.S r/S r0S r1S r2S r3S r4S  r5S! r6S" r7S#\84S$ jr9S#\84S% jr:\;S& 5       r<\;S' 5       r=S(r>g))+CategoryConfig   u   CTF 方向配置模型

用于存储不同 CTF 方向（Web、Crypto、Reverse、Pwn、Misc）的配置信息，
包括表单字段、生成阶段、Prompt 模板等。
category_configs2   Tprimary_keyd   Fnullablefolderdefault       )r   onupdatec                    SSK nU R                  U R                  U R                  U R                  U R
                  U R                  U R                  U R                  U R                  U R                  U R                  U R                  (       a  U R                  R                  5       OSU R                  (       a  U R                  R                  5       OSS.nU(       a  U R                  5       US'   U R!                  5       US'   U R#                  5       US'   U R%                  5       US'   U R'                  5       US'   U R)                  5       US	'   U R+                  5       US
'   U R-                  5       US'   U$ )u   转换为字典r   N)idnameicondescriptionenabled
sort_orderprompt_template_pathknowledge_base_pathknowledge_db_pathchoice_script_path
output_dir
created_at
updated_atform_fieldsform_layoutstagesdifficulty_rulesdifficultiesoutput_config	ui_configadvanced_config)jsonr   r   r   r   r   r   r   r   r    r!   r"   r#   	isoformatr$   get_form_fieldsget_form_layout
get_stagesget_difficulty_rulesget_difficultiesget_output_configget_ui_configget_advanced_config)selfinclude_configr-   datas       ;/Users/yu22x/Desktop/ge/ctf/app/models/database/category.pyto_dictCategoryConfig.to_dict@   s4   ''IIII++||//$($=$=#'#;#;!%!7!7"&"9"9//9=$//335d9=$//335d
  "&"6"6"8D"&"6"6"8D!__.DN'+'@'@'BD#$#'#8#8#:D $($:$:$<D! $ 2 2 4D&*&>&>&@D"#    c                 z    SSK n U R                  (       a  UR                  U R                  5      $ / $ !   / s $ = f)u   获取表单字段配置r   N)r-   r%   loadsr7   r-   s     r:   r/   CategoryConfig.get_form_fields`   8    	373C3C4::d../KK	I   +4 4 :c                 6    SSK nUR                  USS9U l        g)u   设置表单字段配置r   NFensure_ascii)r-   dumpsr%   )r7   fieldsr-   s      r:   set_form_fieldsCategoryConfig.set_form_fieldsh       ::f5:Ar=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ 0 $ !   0 s $ = f)u   获取表单布局配置r   N)r-   r&   r?   r@   s     r:   r0   CategoryConfig.get_form_layoutm   rB   rC   c                 6    SSK nUR                  USS9U l        g)u   设置表单布局配置r   NFrE   )r-   rG   r&   )r7   layoutr-   s      r:   set_form_layoutCategoryConfig.set_form_layoutu   rK   r=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ / $ !   / s $ = f)u   获取阶段配置r   N)r-   r'   r?   r@   s     r:   r1   CategoryConfig.get_stagesz   s4    	.2kk4::dkk*ArA	IrC   c                 6    SSK nUR                  USS9U l        g)u   设置阶段配置r   NFrE   )r-   rG   r'   )r7   r'   r-   s      r:   
set_stagesCategoryConfig.set_stages   s    jjej<r=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ / $ !   / s $ = f)u   获取难度规则r   N)r-   r(   r?   r@   s     r:   r2   #CategoryConfig.get_difficulty_rules   9    	8<8M8M4::d334USUU	IrC   c                 6    SSK nUR                  USS9U l        g)u   设置难度规则r   NFrE   )r-   rG   r(   )r7   rulesr-   s      r:   set_difficulty_rules#CategoryConfig.set_difficulty_rules   s     $

5u
 Er=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ 0 $ !   0 s $ = f)u   获取输出配置r   N)r-   r*   r?   r@   s     r:   r4    CategoryConfig.get_output_config   s8    	595G5G4::d001ORO	IrC   c                 6    SSK nUR                  USS9U l        g)u   设置输出配置r   NFrE   )r-   rG   r*   r7   configr-   s      r:   set_output_config CategoryConfig.set_output_config   s    !ZZUZCr=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ 0 $ !   0 s $ = f)u   获取 UI 配置r   N)r-   r+   r?   r@   s     r:   r5   CategoryConfig.get_ui_config   s4    	154::dnn-GRG	IrC   c                 6    SSK nUR                  USS9U l        g)u   设置 UI 配置r   NFrE   )r-   rG   r+   ra   s      r:   set_ui_configCategoryConfig.set_ui_config   s    F?r=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ 0 $ !   0 s $ = f)u   获取高级配置r   N)r-   r,   r?   r@   s     r:   r6   "CategoryConfig.get_advanced_config   s9    	7;7K7K4::d223SQSS	IrC   c                 6    SSK nUR                  USS9U l        g)u   设置高级配置r   NFrE   )r-   rG   r,   ra   s      r:   set_advanced_config"CategoryConfig.set_advanced_config   s    #zz&uzEr=   c                 z    SSK n U R                  (       a  UR                  U R                  5      $ 0 $ !   0 s $ = f)u    获取编译后的 Prompt 模板r   N)r-   compiled_promptsr?   r@   s     r:   get_compiled_prompts#CategoryConfig.get_compiled_prompts   rY   rC   c                 T    SSK nU(       a  UR                  USS9U l        gSU l        g)u   设置编译后的 Prompt 模板

Args:
    prompts_dict: 字典，格式: {"beginner": "...", "easy": "...", "medium": "...", "hard": "..."}
r   NFrE   )r-   rG   rp   )r7   prompts_dictr-   s      r:   set_compiled_prompts#CategoryConfig.set_compiled_prompts   s&     	P\

<e
 Lbfr=   c                     SSK n U R                  (       a  UR                  U R                  5      $  U R                  5       $ !    U R                  5       $ = f)u  获取难度独立配置（新格式）

Returns:
    dict: {"入门": {"stages": [...], "rules": {...}}, ...}
    如果 difficulties 字段存在，直接返回
    否则从旧格式 stages + difficulty_rules 自动转换（只读转换，不写回数据库）
r   N)r-   r)   r?   _convert_old_to_new_formatr@   s     r:   r3   CategoryConfig.get_difficulties   s[     		  zz$"3"344 ! ..00		 ..00s   +A Ac           
         0 nU R                  5       =(       d    / nU R                  5       =(       d    / nU(       d	  U(       d  U$ U GH  n[        U[        5      (       a  SU;  a  M!  US   nUR	                  5        VVs0 s H  u  pgUS:w  d  M  Xg_M     nnn/ n	U GH  n
[        U
[        5      (       d  M  [        U
5      nSU;   ao  [        US   [        5      (       aW  X[S   ;   aL  US   U   n[        U[        5      (       a  UR                  SS5      US'   O[        U[        5      (       a  XS'   US	 SU;   Ga  [        US   [        5      (       a  US   R                  U5      =(       de    US   R                  S5      =(       dJ    US   R                  S5      =(       d/    US   R                  S	5      =(       d    US   R                  S
5      nU(       a_  [        U[        5      (       aJ  UR                  UR	                  5        VVs0 s H  u  pgUS:w  d  M  Xg_M     snn5        SU;   a  US   US'   US	 U	R                  U5        GM     U	US.X'   GM     U(       d  U(       a  / SQnU H  n/ n	U H  n
[        U
[        5      (       d  M  [        U
5      nSU;   ao  [        US   [        5      (       aW  X[S   ;   aL  US   U   n[        U[        5      (       a  UR                  SS5      US'   O[        U[        5      (       a  XS'   US	 U	R                  U5        M     U	(       d  M  U	0 S.X'   M     U$ s  snnf s  snnf )u   从旧格式（stages + difficulty_rules）转换为新格式（difficulties）

注意：这是只读转换，不会写回数据库
r   promptscontent promptdifficulty_configbeginnereasymediumhard)r'   r[   )u   入门u   简单u   中等u   困难)	r1   r2   
isinstancedictitemsgetstrupdateappend)r7   r)   r'   r[   rule	diff_namekv
diff_rulesdiff_stagesstage
stage_copyprompt_datadiff_configdefault_difficultiess                  r:   rx   )CategoryConfig._convert_old_to_new_format   sI   
 "(b))+1r e DdD))V4-?VI+/::<G<411;$!$<JG K!%..!%[
 
*z*Y:OQU/V/V y$99&0&;I&F%k4883>??9b3QJx0'S993>x0"9- '*4JObDcei9j9j",-@"A"E"Ei"P #N",-@"A"E"Ej"Q#N",-@"A"E"Ef"M#N #--@"A"E"Eh"O#N #--@"A"E"Ef"M	   #z+t'D'D"))K<M<M<O*b<ODASTXaSa414<O*bc#{23>x3HJx0 ##67"":.K  P &#'L#c n #K 1	 #E%eT22 !%eJ J.:j>SUY3Z3Z$9(==*4Y*?	*JK)+t<<7ByRT7U
8 4!+K!=!=7B8 4&y1&&z2 $ ;"-!#/L+' 20 Y HD +cs    MMM!Mc                 T    SSK nU(       a  UR                  USS9U l        gSU l        g)u   设置难度独立配置（新格式）

Args:
    difficulties: dict, 格式: {"入门": {"stages": [...], "rules": {...}}, ...}
r   NFrE   )r-   rG   r)   )r7   r)   r-   s      r:   set_difficultiesCategoryConfig.set_difficultiesA  s&     	LXDJJ|%JH^br=   
difficultyc                     U R                  5       nX;   a+  [        X!   [        5      (       a  X!   R                  S/ 5      $ / $ )u   获取指定难度的阶段列表

Args:
    difficulty: str, 难度名称（中文：入门/简单/中等/困难）
    
Returns:
    list: 该难度的阶段列表，如果难度不存在则返回空列表
r'   r3   r   r   r   r7   r   r)   s      r:   get_stages_by_difficulty'CategoryConfig.get_stages_by_difficultyJ  sB     ,,.%*\5Mt*T*T+//"==	r=   c                     U R                  5       nX;   a+  [        X!   [        5      (       a  X!   R                  S0 5      $ 0 $ )u   获取指定难度的规则

Args:
    difficulty: str, 难度名称（中文：入门/简单/中等/困难）
    
Returns:
    dict: 该难度的规则，如果难度不存在则返回空字典
r[   r   r   s      r:   get_rules_by_difficulty&CategoryConfig.get_rules_by_difficultyX  sB     ,,.%*\5Mt*T*T+//<<	r=   c                      [         R                  R                  SS9R                  [         R                  5      R                  5       $ )u   获取所有启用的方向T)r   )r   query	filter_byorder_byr   all r=   r:   get_enabled_categories%CategoryConfig.get_enabled_categoriesf  s8     ##--d-;DD^E^E^_cceer=   c                  x    [         R                  R                  [         R                  5      R	                  5       $ )u   获取所有方向)r   r   r   r   r   r   r=   r:   get_all_categories!CategoryConfig.get_all_categoriesk  s*     ##,,^-F-FGKKMMr=   )	r,   rp   r)   r(   r%   r&   r*   r'   r+   N)T)?__name__
__module____qualname____firstlineno____doc____tablename__r   ColumnStringr   r   r   Textr   Booleanr   Integerr   r%   r&   r'   r(   r)   r*   r+   r,   rp   r   r   r    r!   r"   DateTimer   r#   r$   r;   r/   rI   r0   rP   r1   rU   r2   r\   r4   rc   r5   rh   r6   rm   rq   ru   r3   rx   r   r   r   r   staticmethodr   r   __static_attributes__r   r=   r:   r   r      s   
 'M	299R=d	3B99RYYs^e4D99RYYr]H5D))BGG$Kii

E2G2::q1J ))BGG$K))BGG$K YYrwwF yy) 99RWW%L IIbgg&M 		"''"I ii(O yy) 99RYYs^4))BIIcN3		"))C.1299S>2299S>*J 2;;@J2;;/ZJ@B
B
=
F
D
@
F
g1&`Dc3 #  f f N Nr=   r   c                   N   \ rS rSrSrSr\R                  " \R                  SS9r	\R                  " \R                  " S5      \R                  " SSS	9S
S9r\R                  " \R                  \R                  " SSS	9S
S9r\R                  " \R                  " S5      SS9r\R                  " \R                  \S9r\R$                  " SSSS94r\R(                  " S\R*                  " SSS9S9r\R(                  " S\R*                  " SSS9S9rS r\S 5       r\S 5       rSrg)CategoryAdminit  uN   方向管理员模型

用于分配不同用户管理不同方向的权限。
category_adminsTr   r   zcategory_configs.idCASCADE)ondeleteFr   zusers.ideditorr   category_iduser_iduq_category_user)r   r   adminsdynamic)lazy)backrefr   managed_categoriesc                 \   U R                   U R                  U R                  (       a  U R                  R                  OS U R                  U R
                  (       a  U R
                  R                  OS U R                  U R                  (       a  U R                  R                  5       S.$ S S.$ )N)r   r   category_namer   usernameroler#   )
r   r   category_configr   r   userr   r   r#   r.   )r7   s    r:   r;   CategoryAdmin.to_dict  s    ''++:>:N:NT1166TX||.2ii		**TII9=$//335
 	
 OS
 	
r=   c                     [         R                  R                  U 5      nU(       a  UR                  [        R
                  :X  a  g[        R                  R                  U US9R                  5       nUSL$ )u*   检查用户是否可以管理指定方向T)r   r   N)	r   r   r   r   r   ADMINr   r   first)r   r   r   admins       r:   
can_manageCategoryAdmin.can_manage  sg     zz~~g&DII+ ##--# . 
 %' 	 D  r=   c                    [         R                  R                  U 5      nU(       a2  UR                  [        R
                  :X  a  [        R                  5       $ [        R                  R                  U S9R                  5       nU Vs/ s H  o3R                  PM     nn[        R                  R                  [        R                  R                  U5      5      R                  5       $ s  snf )u$   获取用户可管理的方向列表)r   )r   r   r   r   r   r   r   r   r   r   r   r   filterr   in_)r   r   admin_recordsacategory_idss        r:   get_user_categories!CategoryAdmin.get_user_categories  s     zz~~g&DII+!4466%++55g5FJJL/<=}!}=##**>+<+<+@+@+NOSSUU >s   C)r   N)r   r   r   r   r   r   r   r   r   r   r   
ForeignKeyr   r   r   r   r   r#   UniqueConstraint__table_args__relationshipr   r   r   r;   r   r   r   r   r   r=   r:   r   r   t  s    &M	2::4	0B))BIIbM2==9NYb+cnstKii

BMM*y$Q\abG99RYYr]H5D2;;@J 	M9;MNN
 oo&6

8Zc@deO??62::6JQZ+[\D	
 ! ! V Vr=   r   N)
r   baser   r   r   r   r   Modelr   r   r   r=   r:   <module>r      s9    & cNRXX cNR9VBHH 9Vr=   