
    Tix*              
       0   d Z ddlZddlZddlZ ej                  dej
                  j                  ej
                  j                  ej
                  j                  e            d            Z	i a
dg g dZ G d d      Z e       Zej                          y)	u;  
Settings Service - 设置服务模块

该模块负责管理应用程序的所有配置设置，包括：
- 代理配置（proxy settings）
- 系统提示词（system prompts）
- 其他应用配置项

主要功能：
1. 读取和写入 JSON 格式的设置文件
2. 提供默认设置配置
3. 敏感信息掩码处理（如密码）
4. 设置的合并和更新操作
5. 全局设置状态管理

文件结构：
- DEFAULT_SETTINGS: 默认配置模板
- SettingsService: 核心设置服务类
- settings_service: 全局服务实例
- app_settings: 全局设置缓存
    NUSER_DATA_DIR	user_datasystem)proxyenabled_knowledgeenabled_knowledge_datac                   R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)SettingsServiceuJ  
    设置服务类

    负责管理应用程序的所有配置设置，包括读取、写入、更新等操作。
    使用 TOML 格式存储配置文件，支持设置的合并和敏感信息掩码。

    Attributes:
        root_dir (str): 项目根目录路径
        settings_file (str): 设置文件的完整路径
    c                 B   t         j                  j                  t         j                  j                  t         j                  j                  t                          | _        t        j
                  dt         j                  j                  t        d            | _        y)u   
        初始化设置服务

        设置项目根目录和配置文件路径。
        配置文件路径可通过环境变量 SETTINGS_PATH 自定义。
        SETTINGS_PATHzsettings.jsonN)	ospathdirname__file__root_dirgetenvjoinr   settings_fileselfs    S/home/jay/workspace/tools/ai-image-gen/jaaz-app/server/services/settings_service.py__init__zSettingsService.__init__7   s[     GGOOBGGOOH568YYRWW\\-IK    c                 \   K   t         j                  j                  | j                        S w)u   
        检查设置文件是否存在

        Returns:
            bool: 如果设置文件存在返回 True，否则返回 False

        Note:
            这是一个异步方法，主要是为了保持 API 接口的一致性
        )r   r   existsr   r   s    r   exists_settingszSettingsService.exists_settingsC   s!      ww~~d0011s   *,c                 @   	 t         j                  j                  | j                        s| j	                          t        | j                  dd      5 }t        j                  |      }ddd       i t        }j                         D ]F  \  }}||v r8t        ||   t              r%t        |t              r||   j                  |       B|||<   H |a|S # 1 sw Y   nxY w# t        $ r2}t        d|        t!        j"                          t        cY d}~S d}~ww xY w)u  
        获取所有设置配置（用于 API 响应）

        该方法会：
        1. 读取设置文件（如果不存在则创建默认配置）
        2. 与默认设置合并，确保所有必需的键都存在
        3. 对敏感信息进行掩码处理
        4. 更新全局设置缓存

        Returns:
            dict: 包含所有设置的字典，敏感信息已被掩码

        Note:
            返回的设置适用于 API 响应，敏感信息（如密码）会被 '*' 掩码
        rutf-8encodingNzError loading settings: )r   r   r   r   create_default_settingsopenjsonloadDEFAULT_SETTINGSitems
isinstancedictupdateapp_settings	Exceptionprint	traceback	print_excr   fsettingsmerged_settingskeyvaluees          r   get_settingszSettingsService.get_settingsO   s	    	$77>>$"4"45,,. d((#@ (A99Q<( 3!12O&nn. 1
U/)j9Mt.TYcdikoYp#C(//6 ,1OC(1 +L""!( ("  	$,QC01!##	$s7   AC" C)A,C" CC" "	D+'DDDc                    	 t         j                  j                  | j                        s| j	                          t        | j                  dd      5 }t        j                  |      }ddd       i t        }j                         D ]F  \  }}||v r8t        ||   t              r%t        |t              r||   j                  |       B|||<   H |a|S # 1 sw Y   nxY w# t        $ r}t        d|        t        cY d}~S d}~ww xY w)u  
        获取原始设置（内部使用，不掩码敏感信息）

        该方法返回完整的设置配置，包括敏感信息，主要用于：
        1. 系统内部逻辑使用
        2. 代理配置等需要完整信息的场景
        3. 设置的验证和处理

        Returns:
            dict: 包含所有设置的完整字典，敏感信息未被掩码

        Note:
            此方法返回的数据包含敏感信息，仅供内部使用，不应直接用于 API 响应
        r   r   r    NzError loading raw settings: )r   r   r   r   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r0   s          r   get_raw_settingsz SettingsService.get_raw_settings{   s    	$77>>$"4"45,,. d((#@ (A99Q<( 3!12O&nn. 1
U/)j9Mt.TYcdikoYp#C(//6+0OC(	1 +L""( (  	$045##	$s7   AC" C)A,C" CC" "	D	+D>D	D	c                 F    | j                         }|j                  dd      S )u   
        获取代理配置

        Returns:
            str: 代理配置字符串
                - '' : 不使用代理
                - 'system' : 使用系统代理
                - URL地址 : 使用指定的代理服务器
        r    r9   getr   r2   s     r   get_proxy_configz SettingsService.get_proxy_config   s#     ((*||GR((r   c                 F    | j                         }|j                  dg       S )uq   
        获取启用的知识库ID列表

        Returns:
            list: 启用的知识库ID列表
        r   r<   r>   s     r   get_enabled_knowledge_idsz)SettingsService.get_enabled_knowledge_ids   s$     ((*||/44r   c                 D   K   | j                  d|i       d{   S 7 w)u   
        更新启用的知识库列表

        Args:
            knowledge_ids (list): 知识库ID列表

        Returns:
            dict: 操作结果
        r   N)update_settings)r   knowledge_idss     r   update_enabled_knowledgez(SettingsService.update_enabled_knowledge   s%      ))+>*NOOOOs     c                 F    | j                         }|j                  dg       S )u   
        获取启用的知识库完整数据列表

        Returns:
            list: 知识库数据列表，每个项目包含name、description、content等信息
        r   r<   r>   s     r   get_enabled_knowledge_dataz*SettingsService.get_enabled_knowledge_data   s$     ((*||4b99r   c                    K   |D cg c]%  }|j                  d      r|j                  dd      ' }}| j                  ||d       d{   S c c}w 7 	w)u   
        更新启用的知识库完整数据

        Args:
            knowledge_data_list (list): 知识库数据列表，包含完整的知识库信息

        Returns:
            dict: 操作结果
        idr;   )r   r   N)r=   rC   )r   knowledge_data_listkbrD   s       r   update_enabled_knowledge_dataz-SettingsService.update_enabled_knowledge_data   sk      $7H"&&, b) H H))!.&9+
   	Hs   A*AA
A
Ac                 \   	 t        j                  t         j                  j                  | j                        d       t        | j                  dd      5 }t        j                  t        |d       ddd       y# 1 sw Y   yxY w# t        $ r}t        d	|        Y d}~yd}~ww xY w)
u  
        创建默认设置文件

        当设置文件不存在时，根据 DEFAULT_SETTINGS 模板创建新的配置文件。
        会自动创建必要的目录结构。

        Raises:
            Exception: 当文件创建失败时抛出异常
        Texist_okwr   r       indentNz!Error creating default settings: )r   makedirsr   r   r   r#   r$   dumpr&   r,   r-   )r   r1   r6   s      r   r"   z'SettingsService.create_default_settings   s    	;KK(:(:;dK d((#@ 9A		*Aa89 9 9 	;5aS9::	;s6   AB
 A>5B
 >BB
 B
 
	B+B&&B+c                   K   	 t         j                         }t        j                  j	                  | j
                        r7	 t        | j
                  dd      5 }t        j                  |      }ddd       |j                         D ]F  \  }}||v r8t        ||   t              r%t        |t              r||   j                  |       B|||<   H t        j                  t        j                  j!                  | j
                        d       t        | j
                  dd      5 }t        j"                  ||d	
       ddd       |adddS # 1 sw Y   xY w# t        $ r}t        d|        Y d}~d}~ww xY w# 1 sw Y   @xY w# t        $ r,}t'        j(                          dt+        |      dcY d}~S d}~ww xY ww)u  
        更新设置配置

        该方法会：
        1. 读取现有设置
        2. 与新数据进行合并（深度合并字典类型）
        3. 保存更新后的设置到文件
        4. 更新全局设置缓存

        Args:
            data (dict): 要更新的设置数据，可以是部分设置

        Returns:
            dict: 包含操作状态和消息的字典
                - status (str): "success" 或 "error"
                - message (str): 操作结果描述

        Example:
            result = await settings_service.update_settings({
                "proxy": {"enable": True, "url": "http://proxy.com:8080"}
            })
        r   r   r    Nz!Error reading existing settings: TrN   rP   rQ   rR   successzSettings updated successfully)statusmessageerror)r&   copyr   r   r   r   r#   r$   r%   r,   r-   r'   r(   r)   r*   rT   r   rU   r+   r.   r/   str)r   dataexisting_settingsr1   r6   r4   r5   s          r   rC   zSettingsService.update_settings   s    .!	: 0 5 5 7ww~~d001Cd00#H 9A,0IIaL)9 #jjl 3
U++
;LS;QSW0X]ghmos]t%c*11%8 .3%c*3 KK(:(:;dK d((#@ :A		+Qq9:
 -L'4STT39 9  C=aSABBC : :  	:!%#a&99	:s   G=F E E0E 8B/F 'E? F GEE 	E<$E72F 7E<<F ?FF 	G !F;5G 6G;G  GN)__name__
__module____qualname____doc__r   r   r7   r9   r?   rA   rE   rG   rL   r"   rC    r   r   r
   r
   +   sB    	
K
2*$X&$P)5
P:$;(8:r   r
   )rb   r   r.   r$   r   r   r   r   r   r   r+   r&   r
   settings_servicer9   rc   r   r   <module>re      s   , 
   		/277<<GGOOBGGOOH-.,= > 
   C: C:P #$   ! ! #r   