diff --git a/app/api/endpoints/system.py b/app/api/endpoints/system.py index 595eeb81..a078d193 100644 --- a/app/api/endpoints/system.py +++ b/app/api/endpoints/system.py @@ -178,7 +178,7 @@ def get_global_setting(token: str): raise HTTPException(status_code=403, detail="Forbidden") # FIXME: 新增敏感配置项时要在此处添加排除项 - info = settings.dict( + info = settings.model_dump( exclude={"SECRET_KEY", "RESOURCE_SECRET_KEY", "API_TOKEN", "TMDB_API_KEY", "TVDB_API_KEY", "FANART_API_KEY", "COOKIECLOUD_KEY", "COOKIECLOUD_PASSWORD", "GITHUB_TOKEN", "REPO_GITHUB_TOKEN", "U115_APP_ID", "ALIPAN_APP_ID", "TVDB_V4_API_KEY", "TVDB_V4_API_PIN"} @@ -199,7 +199,7 @@ async def get_env_setting(_: User = Depends(get_current_active_user_async)): """ 查询系统环境变量,包括当前版本号(仅管理员) """ - info = settings.dict( + info = settings.model_dump( exclude={"SECRET_KEY", "RESOURCE_SECRET_KEY"} ) info.update({ diff --git a/app/core/config.py b/app/core/config.py index 8a7c84ae..deac0a70 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -547,18 +547,14 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): """ if not isinstance(data, dict): return data - + # 处理 API_TOKEN 特殊验证 if 'API_TOKEN' in data: converted_value, needs_update = cls.validate_api_token(data['API_TOKEN'], data['API_TOKEN']) if needs_update: - cls.update_env_config( - type('Field', (), {'name': 'API_TOKEN'})(), - data['API_TOKEN'], - converted_value - ) + cls.update_env_config("API_TOKEN", data["API_TOKEN"], converted_value) data['API_TOKEN'] = converted_value - + # 对其他字段进行类型转换 for field_name, field_info in cls.model_fields.items(): if field_name not in data: @@ -566,35 +562,31 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): value = data[field_name] if value is None: continue - + field = cls.model_fields.get(field_name) if field: converted_value, needs_update = cls.generic_type_converter( value, value, field.annotation, field.default, field_name ) if needs_update: - cls.update_env_config( - type('Field', (), {'name': field_name})(), - value, - converted_value - ) + cls.update_env_config(field_name, value, converted_value) data[field_name] = converted_value - + return data @staticmethod - def update_env_config(field: Any, original_value: Any, converted_value: Any) -> Tuple[bool, str]: + def update_env_config(field_name: str, original_value: Any, converted_value: Any) -> Tuple[bool, str]: """ 更新 env 配置 """ message = None is_converted = original_value is not None and str(original_value) != str(converted_value) if is_converted: - message = f"配置项 '{field.name}' 的值 '{original_value}' 无效,已替换为 '{converted_value}'" + message = f"配置项 '{field_name}' 的值 '{original_value}' 无效,已替换为 '{converted_value}'" logger.warning(message) - if field.name in os.environ: - message = f"配置项 '{field.name}' 已在环境变量中设置,请手动更新以保持一致性" + if field_name in os.environ: + message = f"配置项 '{field_name}' 已在环境变量中设置,请手动更新以保持一致性" logger.warning(message) return False, message else: @@ -604,10 +596,10 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): else: value_to_write = str(converted_value) if converted_value is not None else "" - set_key(dotenv_path=SystemUtils.get_env_path(), key_to_set=field.name, value_to_set=value_to_write, + set_key(dotenv_path=SystemUtils.get_env_path(), key_to_set=field_name, value_to_set=value_to_write, quote_mode="always") if is_converted: - logger.info(f"配置项 '{field.name}' 已自动修正并写入到 'app.env' 文件") + logger.info(f"配置项 '{field_name}' 已自动修正并写入到 'app.env' 文件") return True, message def update_setting(self, key: str, value: Any) -> Tuple[Optional[bool], str]: @@ -623,17 +615,15 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): try: field = Settings.model_fields[key] original_value = getattr(self, key) - if field.name == "API_TOKEN": + if key == "API_TOKEN": converted_value, needs_update = self.validate_api_token(value, original_value) else: - converted_value, needs_update = self.generic_type_converter(value, - original_value, - field.type_, - field.default, - key) + converted_value, needs_update = self.generic_type_converter( + value, original_value, field.annotation, field.default, key + ) # 如果没有抛出异常,则统一使用 converted_value 进行更新 if needs_update or str(value) != str(converted_value): - success, message = self.update_env_config(field, value, converted_value) + success, message = self.update_env_config(key, value, converted_value) # 仅成功更新配置时,才更新内存 if success: setattr(self, key, converted_value) diff --git a/app/modules/filemanager/transhandler.py b/app/modules/filemanager/transhandler.py index fc03ab44..550fb0a2 100644 --- a/app/modules/filemanager/transhandler.py +++ b/app/modules/filemanager/transhandler.py @@ -129,7 +129,7 @@ class TransHandler: transfer_type=transfer_type, need_notify=need_notify, ) - return self.result.copy() + return self.result.model_copy() else: new_path = target_path / fileitem.name # 整理目录 @@ -147,7 +147,7 @@ class TransHandler: fileitem=fileitem, transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() logger.info(f"文件夹 {fileitem.path} 整理成功") # 返回整理后的路径 @@ -158,7 +158,7 @@ class TransHandler: need_scrape=need_scrape, need_notify=need_notify, transfer_type=transfer_type) - return self.result.copy() + return self.result.model_copy() else: # 整理单个文件 if mediainfo.type == MediaType.TV: @@ -171,7 +171,7 @@ class TransHandler: fail_list=[fileitem.path], transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() # 文件结束季为空 in_meta.end_season = None @@ -207,7 +207,7 @@ class TransHandler: transfer_type=transfer_type, need_notify=need_notify, ) - return self.result.copy() + return self.result.model_copy() else: new_file = target_path / fileitem.name folder_path = target_path @@ -224,7 +224,7 @@ class TransHandler: fail_list=[fileitem.path], transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() # 目标文件 target_item = target_oper.get_item(new_file) if target_item: @@ -255,7 +255,7 @@ class TransHandler: fail_list=[fileitem.path], transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() elif overwrite_mode == 'never': # 存在不覆盖 self.__set_result(success=False, @@ -266,7 +266,7 @@ class TransHandler: fail_list=[fileitem.path], transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() elif overwrite_mode == 'latest': # 仅保留最新版本 logger.info(f"当前整理覆盖模式设置为仅保留最新版本,将覆盖:{new_file}") @@ -293,7 +293,7 @@ class TransHandler: fail_list=[fileitem.path], transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() logger.info(f"文件 {fileitem.path} 整理成功") self.__set_result(success=True, @@ -303,7 +303,7 @@ class TransHandler: need_scrape=need_scrape, transfer_type=transfer_type, need_notify=need_notify) - return self.result.copy() + return self.result.model_copy() finally: self.result = None diff --git a/app/schemas/subscribe.py b/app/schemas/subscribe.py index 753fac02..35c5a39c 100644 --- a/app/schemas/subscribe.py +++ b/app/schemas/subscribe.py @@ -24,7 +24,7 @@ class Subscribe(BaseModel): # 背景图 backdrop: Optional[str] = None # 评分 - vote: Optional[float] = 0 + vote: Optional[float] = 0.0 # 描述 description: Optional[str] = None # 过滤规则 @@ -110,7 +110,7 @@ class SubscribeShare(BaseModel): # 背景图 backdrop: Optional[str] = None # 评分 - vote: Optional[int] = 0 + vote: Optional[float] = 0.0 # 描述 description: Optional[str] = None # 包含