diff --git a/CHANGELOG/v2.2.1/CHANGELOG.md b/CHANGELOG/v2.2.1/CHANGELOG.md new file mode 100644 index 00000000..cb36bc57 --- /dev/null +++ b/CHANGELOG/v2.2.1/CHANGELOG.md @@ -0,0 +1,22 @@ +新版本 +v2.0 - Koharu(小鸟游星野) release 4 + +## 🚀 主要更新 + +- 无 + +## 💡 功能优化 + +- 无 + +## 🐛 修复问题 + +- 修复 **日志等级** 问题,防止 Sentry 爆炸。 + +## 🔧 其它变更 + +- 无 + +--- + +💝 **感谢所有贡献者为 SecRandom 项目付出的努力!** diff --git a/app/Language/obtain_language.py b/app/Language/obtain_language.py index 4d56a2cd..2a3e01dc 100644 --- a/app/Language/obtain_language.py +++ b/app/Language/obtain_language.py @@ -63,7 +63,7 @@ def run(self): value = self._read_language_value() self.finished.emit(value) except Exception as e: - logger.exception(f"读取语言内容失败: {e}") + logger.warning(f"读取语言内容失败: {e}") self.finished.emit(None) def _read_language_value(self): diff --git a/app/common/IPC_URL/url_ipc_handler.py b/app/common/IPC_URL/url_ipc_handler.py index 209d9541..0b082ecd 100644 --- a/app/common/IPC_URL/url_ipc_handler.py +++ b/app/common/IPC_URL/url_ipc_handler.py @@ -52,7 +52,7 @@ def register_url_protocol(self) -> bool: try: return self.protocol_manager.register_protocol() except Exception as e: - logger.exception(f"注册URL协议失败: {e}") + logger.warning(f"注册URL协议失败: {e}") return False def unregister_url_protocol(self) -> bool: @@ -65,7 +65,7 @@ def unregister_url_protocol(self) -> bool: try: return self.protocol_manager.unregister_protocol() except Exception as e: - logger.exception(f"注销URL协议失败: {e}") + logger.warning(f"注销URL协议失败: {e}") return False def is_protocol_registered(self) -> bool: @@ -97,7 +97,7 @@ def start_ipc_server(self, port: int = 0) -> bool: self.is_running = True return True except Exception as e: - logger.exception(f"启动IPC服务器失败: {e}") + logger.warning(f"启动IPC服务器失败: {e}") return False def stop_ipc_server(self): @@ -140,11 +140,11 @@ def _run_server(self, port: int): continue except Exception as e: if self.is_running: - logger.exception(f"IPC服务器错误: {e}") + logger.warning(f"IPC服务器错误: {e}") break except Exception as e: - logger.exception(f"IPC服务器启动错误: {e}") + logger.warning(f"IPC服务器启动错误: {e}") finally: if "server_socket" in locals(): server_socket.close() @@ -158,7 +158,7 @@ def _handle_client(self, client_socket: socket.socket, address: tuple): response = self._process_message(message) client_socket.send(json.dumps(response).encode("utf-8")) except Exception as e: - logger.exception(f"处理IPC消息错误: {e}") + logger.warning(f"处理IPC消息错误: {e}") finally: client_socket.close() @@ -188,7 +188,7 @@ def _process_message(self, message: Dict[str, Any]) -> Dict[str, Any]: "type": message_type, "error": str(e), } - logger.exception(f"消息处理失败 - 类型: {message_type}, 错误: {e}") + logger.warning(f"消息处理失败 - 类型: {message_type}, 错误: {e}") return error_response else: unknown_response = { @@ -224,7 +224,7 @@ def _handle_url_message(self, payload: Dict[str, Any]) -> Dict[str, Any]: logger.info(f"URL命令执行成功: {url}, 结果: {result}") return {"success": True, "result": result} except Exception as e: - logger.exception(f"URL命令执行失败: {url}, 错误: {e}") + logger.warning(f"URL命令执行失败: {url}, 错误: {e}") return {"success": False, "error": str(e)} def register_message_handler(self, message_type: str, handler: Callable): @@ -262,7 +262,7 @@ def send_ipc_message( return json.loads(response_data) except Exception as e: - logger.exception(f"发送IPC消息失败: {e}") + logger.warning(f"发送IPC消息失败: {e}") return None def _save_port_config(self, port: int): @@ -286,7 +286,7 @@ def load_port_config(self) -> Optional[int]: config = json.load(f) return config.get("port") except Exception as e: - logger.exception(f"加载端口配置失败: {e}") + logger.warning(f"加载端口配置失败: {e}") return None @@ -328,7 +328,7 @@ def handle_url_args(self, url: str) -> Dict[str, Any]: return result except Exception as e: - logger.exception(f"URL参数解析失败: {url}, 错误: {e}") + logger.warning(f"URL参数解析失败: {url}, 错误: {e}") return {"success": False, "error": str(e)} def execute_url_command( @@ -361,7 +361,7 @@ def execute_url_command( logger.info(f"URL命令执行成功: {url}, 结果: {result}") return {"success": True, "result": result} except Exception as e: - logger.exception(f"URL命令执行失败: {url}, 错误: {e}") + logger.warning(f"URL命令执行失败: {url}, 错误: {e}") return {"success": False, "error": str(e)} def get_available_commands(self) -> Dict[str, Any]: diff --git a/app/common/extraction/cses_parser.py b/app/common/extraction/cses_parser.py index f42e2a71..99c944ce 100644 --- a/app/common/extraction/cses_parser.py +++ b/app/common/extraction/cses_parser.py @@ -283,7 +283,7 @@ def _validate_schedule(self) -> bool: bool: 数据有效返回True,否则返回False """ if not self.schedule_data: - logger.exception("课程表数据为空") + logger.warning("课程表数据为空") return False schedule = self.schedule_data.get("schedule") @@ -293,7 +293,7 @@ def _validate_schedule(self) -> bool: logger.warning("缺少'timeslots'字段,将使用空课程表数据") return True if not isinstance(timeslots, list): - logger.exception("'timeslots'字段必须是列表类型") + logger.warning("'timeslots'字段必须是列表类型") return False for i, timeslot in enumerate(timeslots): if not self._validate_timeslot(timeslot, i): @@ -343,13 +343,13 @@ def _validate_timeslot(self, timeslot: dict, index: int) -> bool: bool: 有效返回True,否则返回False """ if not isinstance(timeslot, dict): - logger.exception(f"时间段{index}必须是字典类型") + logger.warning(f"时间段{index}必须是字典类型") return False required_fields = ["name", "start_time", "end_time"] for field in required_fields: if field not in timeslot: - logger.exception(f"时间段{index}缺少'{field}'字段") + logger.warning(f"时间段{index}缺少'{field}'字段") return False try: @@ -357,11 +357,11 @@ def _validate_timeslot(self, timeslot: dict, index: int) -> bool: end_time = self._parse_time(timeslot["end_time"]) if start_time >= end_time: - logger.exception(f"时间段{index}的开始时间必须早于结束时间") + logger.warning(f"时间段{index}的开始时间必须早于结束时间") return False except ValueError as e: - logger.exception(f"时间段{index}时间格式错误: {e}") + logger.warning(f"时间段{index}时间格式错误: {e}") return False return True @@ -387,7 +387,7 @@ def _parse_time(self, time_str: str) -> time: return time(int(parts[0]), int(parts[1]), int(parts[2])) raise ValueError(f"无效的时间格式: {time_str}") except (ValueError, IndexError): - logger.exception(f"无法解析时间: {time_str}") + logger.warning(f"无法解析时间: {time_str}") raise ValueError(f"无法解析时间: {time_str}") from None def _parse_time_string_to_seconds(self, time_val: str | int) -> int: @@ -416,7 +416,7 @@ def _parse_time_string_to_seconds(self, time_val: str | int) -> int: return int(parts[0]) * 3600 + int(parts[1]) * 60 + int(parts[2]) return int(time_str) except (ValueError, IndexError): - logger.exception(f"无法解析时间字符串: {time_val}") + logger.warning(f"无法解析时间字符串: {time_val}") raise ValueError(f"无法解析时间字符串: {time_val}") from None def _format_time_for_secrandom(self, time_val: str | int) -> str: diff --git a/app/common/music/music_player.py b/app/common/music/music_player.py index 1997ff7c..94af2757 100644 --- a/app/common/music/music_player.py +++ b/app/common/music/music_player.py @@ -96,10 +96,10 @@ def play_music( music_path = get_audio_path(f"music/{music_file}") if not music_path.exists(): - logger.exception(f"音乐文件不存在: {music_path}") + logger.warning(f"音乐文件不存在: {music_path}") return False except Exception as e: - logger.exception(f"获取音乐文件路径失败: {e}") + logger.warning(f"获取音乐文件路径失败: {e}") return False # 从设置中获取音量和渐入渐出时长 @@ -125,7 +125,7 @@ def play_music( ) self._fade_out_duration = fade_out_ms / 1000.0 except Exception as e: - logger.exception(f"获取音乐设置失败: {e}") + logger.warning(f"获取音乐设置失败: {e}") self._volume = 1.0 self._fade_in_duration = 0.0 self._fade_out_duration = 0.0 @@ -208,7 +208,7 @@ def _play_music_worker(self, music_path: str, loop: bool) -> None: data = np.mean(data, axis=1) data = data.astype(np.float32) except Exception as e: - logger.exception(f"读取音乐文件失败: {e}") + logger.warning(f"读取音乐文件失败: {e}") return # 初始化音频流(只初始化一次) @@ -221,7 +221,7 @@ def _play_music_worker(self, music_path: str, loop: bool) -> None: ) stream.start() except Exception as e: - logger.exception(f"初始化音频流失败: {e}") + logger.warning(f"初始化音频流失败: {e}") return # 计算渐入步数 @@ -254,7 +254,7 @@ def _play_music_worker(self, music_path: str, loop: bool) -> None: try: stream.write(chunk) except Exception as e: - logger.exception(f"写入音频流失败: {e}") + logger.warning(f"写入音频流失败: {e}") break # 如果不循环或者收到停止信号,退出循环 @@ -262,7 +262,7 @@ def _play_music_worker(self, music_path: str, loop: bool) -> None: break except Exception as e: - logger.exception(f"音乐播放工作线程异常: {e}") + logger.warning(f"音乐播放工作线程异常: {e}") finally: # 确保音频流关闭 if stream: @@ -270,7 +270,7 @@ def _play_music_worker(self, music_path: str, loop: bool) -> None: stream.stop() stream.close() except Exception as e: - logger.exception(f"关闭音频流失败: {e}") + logger.warning(f"关闭音频流失败: {e}") self._is_playing = False logger.debug("音乐播放工作线程结束") diff --git a/app/common/safety/secure_store.py b/app/common/safety/secure_store.py index 739fc862..6c4593d9 100644 --- a/app/common/safety/secure_store.py +++ b/app/common/safety/secure_store.py @@ -259,7 +259,7 @@ def write_behind_scenes_settings(d: dict) -> None: except Exception as e2: logger.warning(f"降级写入明文JSON也失败:{e2}") except Exception as e: - logger.exception(f"写入内幕设置失败:{p}, 错误:{e}") + logger.warning(f"写入内幕设置失败:{p}, 错误:{e}") try: with open(p, "w", encoding="utf-8") as f: json.dump(d, f, ensure_ascii=False, indent=4) diff --git a/app/common/shortcut/shortcut_manager.py b/app/common/shortcut/shortcut_manager.py index 56f71657..3abf52b5 100644 --- a/app/common/shortcut/shortcut_manager.py +++ b/app/common/shortcut/shortcut_manager.py @@ -93,10 +93,10 @@ def on_pressed(): else: logger.debug(f"快捷键热键为空: {config_key} = {shortcut_str}") except Exception as e: - logger.exception(f"注册快捷键失败 {config_key}: {e}") + logger.warning(f"注册快捷键失败 {config_key}: {e}") import traceback - logger.exception(traceback.format_exc()) + logger.warning(traceback.format_exc()) else: logger.debug(f"快捷键未设置: {config_key}") @@ -129,7 +129,7 @@ def reload_shortcuts(self): try: keyboard.remove_hotkey(hotkey) except Exception as e: - logger.exception(f"注销快捷键失败 {config_key}: {e}") + logger.warning(f"注销快捷键失败 {config_key}: {e}") self.shortcuts.clear() @@ -149,7 +149,7 @@ def update_shortcut(self, config_key: str, shortcut_str: str): keyboard.remove_hotkey(old_hotkey) del self.shortcuts[config_key] except Exception as e: - logger.exception(f"注销快捷键失败 {config_key}: {e}") + logger.warning(f"注销快捷键失败 {config_key}: {e}") if shortcut_str and self._enabled: try: @@ -168,7 +168,7 @@ def on_pressed(): f"快捷键已更新: {config_key} = {shortcut_str}, 热键: {hotkey}" ) except Exception as e: - logger.exception(f"更新快捷键失败 {config_key}: {e}") + logger.warning(f"更新快捷键失败 {config_key}: {e}") def _get_signal_for_key(self, config_key: str) -> Signal: """根据配置键获取对应的信号 @@ -207,7 +207,7 @@ def set_enabled(self, enabled: bool): try: keyboard.remove_hotkey(hotkey) except Exception as e: - logger.exception(f"注销快捷键失败 {config_key}: {e}") + logger.warning(f"注销快捷键失败 {config_key}: {e}") self.shortcuts.clear() logger.info("快捷键已禁用") @@ -227,5 +227,5 @@ def cleanup(self): keyboard.unhook_all() logger.debug("已清理所有 keyboard 钩子") except Exception as e: - logger.exception(f"清理 keyboard 钩子失败: {e}") + logger.warning(f"清理 keyboard 钩子失败: {e}") self.shortcuts.clear() diff --git a/app/common/voice/edge_tts_worker.py b/app/common/voice/edge_tts_worker.py index 82224cfc..a53fd5eb 100644 --- a/app/common/voice/edge_tts_worker.py +++ b/app/common/voice/edge_tts_worker.py @@ -20,7 +20,7 @@ def run(self): voices = self.get_voices() self.voices_fetched.emit(voices) except Exception as e: - logger.exception(f"获取Edge TTS语音列表失败: {e}") + logger.warning(f"获取Edge TTS语音列表失败: {e}") self.error_occurred.emit(str(e)) def get_voices(self): @@ -94,7 +94,7 @@ def get_voices(self): return filtered_voices except Exception as e: - logger.exception(f"获取Edge TTS语音列表失败: {e}") + logger.warning(f"获取Edge TTS语音列表失败: {e}") # 返回默认语音列表 return self.get_default_voices() diff --git a/app/common/voice/voice.py b/app/common/voice/voice.py index a4987044..6268d83b 100644 --- a/app/common/voice/voice.py +++ b/app/common/voice/voice.py @@ -78,7 +78,7 @@ def set_volume(self, volume: float) -> None: """设置播放音量,范围0.0-1.0""" # 输入验证 if not isinstance(volume, (int, float)): - logger.exception(f"无效的音量值: {volume}") + logger.warning(f"无效的音量值: {volume}") return self._volume = max(0.0, min(1.0, float(volume))) @@ -86,7 +86,7 @@ def set_speed(self, speed: int) -> None: """设置播放语速,范围0-200""" # 输入验证 if not isinstance(speed, int): - logger.exception(f"无效的语速值: {speed}") + logger.warning(f"无效的语速值: {speed}") return self._speed = max(0, min(200, speed)) @@ -254,7 +254,7 @@ def add_task(self, task: Union[Tuple[np.ndarray, int], str]) -> bool: self.play_queue.put_nowait(task) return True except queue.Full: - logger.exception("播放队列已满,丢弃新任务") + logger.warning("播放队列已满,丢弃新任务") return False except Exception as e: logger.exception(f"添加播放任务失败: {e}") @@ -396,28 +396,28 @@ async def _generate_voice(self, text: str, voice: str) -> Tuple[np.ndarray, int] return data, fs except NoAudioReceived as e: retry_count += 1 - logger.exception( + logger.warning( f"生成语音失败,未接收到音频数据,重试{retry_count}/{max_retries}: {type(e).__name__} {e}" ) if retry_count < max_retries: await asyncio.sleep(1) except WebSocketError as e: retry_count += 1 - logger.exception( + logger.warning( f"生成语音失败,WebSocket通信错误,重试{retry_count}/{max_retries}: {type(e).__name__} {e}" ) if retry_count < max_retries: await asyncio.sleep(1) except Exception as e: retry_count += 1 - logger.exception( + logger.warning( f"生成语音失败,重试{retry_count}/{max_retries}: {type(e).__name__} {e}" ) if retry_count < max_retries: await asyncio.sleep(1) # 最终失败时的降级处理 - logger.exception("生成语音失败,已达到最大重试次数") + logger.warning("生成语音失败,已达到最大重试次数") raise RuntimeError("生成语音失败") def _generate_cache_key(self, text: str, voice: str) -> str: @@ -481,7 +481,7 @@ def _save_to_disk(self, file_path: str, data: np.ndarray, fs: int) -> None: with self._disk_cache_lock: sf.write(file_path, data, fs) except Exception as e: - logger.exception(f"保存缓存失败: {e}") + logger.warning(f"保存缓存失败: {e}") def _check_and_cleanup(self) -> None: """检查并执行缓存清理""" @@ -507,7 +507,7 @@ def _cleanup_expired_cache(self) -> None: logger.info("缓存清理:本地音频文件不会过期,跳过文件删除") # 可以在这里添加其他清理逻辑,如日志清理等 except Exception as e: - logger.exception(f"缓存清理失败: {e}") + logger.warning(f"缓存清理失败: {e}") class LoadBalancer: @@ -560,11 +560,11 @@ def get_optimal_queue_size(self) -> int: or cpu_percent < 0 or cpu_percent > 100 ): - logger.exception("CPU使用率异常,使用基础队列大小") + logger.warning("CPU使用率异常,使用基础队列大小") return self.BASE_QUEUE_SIZE if not isinstance(mem_available, (int, float)) or mem_available < 0: - logger.exception("内存信息异常,使用基础队列大小") + logger.warning("内存信息异常,使用基础队列大小") return self.BASE_QUEUE_SIZE # 计算基于CPU的队列大小调整系数 @@ -605,7 +605,7 @@ def get_optimal_queue_size(self) -> int: return queue_size except Exception as e: # 异常处理,确保方法总是返回有效值 - logger.exception(f"获取系统负载信息失败: {e},使用基础队列大小") + logger.warning(f"获取系统负载信息失败: {e},使用基础队列大小") return self.BASE_QUEUE_SIZE @@ -658,7 +658,7 @@ def _init_tts_engine(self) -> None: ) logger.info("Windows系统TTS引擎初始化成功") else: - logger.exception( + logger.warning( "Windows系统TTS引擎需要Windows 10及以上系统且非x86架构" ) @@ -686,7 +686,7 @@ def _init_tts_engine(self) -> None: ) logger.info("Linux系统TTS引擎初始化成功 (使用espeak)") else: - logger.exception( + logger.warning( "Linux系统TTS引擎需要安装espeak: sudo apt-get install espeak" ) except Exception as e: diff --git a/app/tools/config.py b/app/tools/config.py index d1006daf..b77afb93 100644 --- a/app/tools/config.py +++ b/app/tools/config.py @@ -407,7 +407,7 @@ def on_notification_click(): else: logger.warning("通知未配置URL,无法打开链接") except Exception as e: - logger.exception(f"打开通知链接失败: {e}") + logger.warning(f"打开通知链接失败: {e}") if sys.platform == "win32": # Windows平台 @@ -494,7 +494,7 @@ def on_notification_click(): logger.warning(f"当前平台不支持系统通知: {sys.platform}") return False except Exception as e: - logger.exception(f"发送系统通知时发生意外错误: {e}") + logger.warning(f"发送系统通知时发生意外错误: {e}") return False @@ -560,9 +560,9 @@ def restore_volume(volume_value): f"Windows音量设置为: {volume_value}%,实际设置值: {actual_volume:.1f}%" ) else: - logger.exception("音频设备没有Activate方法") + logger.warning("音频设备没有Activate方法") else: - logger.exception("无法获取音频设备接口") + logger.warning("无法获取音频设备接口") except Exception as e: logger.exception(f"获取系统主音量控制器失败: {e}") # 作为最后尝试,遍历所有会话并设置音量 @@ -669,7 +669,7 @@ def export_settings(parent: Optional[QWidget] = None) -> None: dialog.exec() except Exception as e: - logger.exception(f"导出设置失败: {e}") + logger.warning(f"导出设置失败: {e}") # 显示错误消息 dialog = MessageBox( get_any_position_value_async( @@ -789,7 +789,7 @@ def import_settings(parent: Optional[QWidget] = None) -> None: success_dialog.exec() except Exception as e: - logger.exception(f"导入设置失败: {e}") + logger.warning(f"导入设置失败: {e}") # 显示错误消息 dialog = MessageBox( get_any_position_value_async( @@ -1172,7 +1172,7 @@ def export_diagnostic_data(parent: Optional[QWidget] = None) -> None: json.dumps(system_info, ensure_ascii=False, indent=2), ) except Exception as e: - logger.exception(f"写入诊断信息文件失败: {e}") + logger.warning"写入诊断信息文件失败: {e}") # 尝试将所有Path对象转换为字符串 class PathEncoder(json.JSONEncoder): @@ -1217,7 +1217,7 @@ def default(self, obj): dialog.exec() except Exception as e: - logger.exception(f"导出诊断数据失败: {e}") + logger.warning(f"导出诊断数据失败: {e}") # 显示错误消息 dialog = MessageBox( get_any_position_value_async( @@ -1346,7 +1346,7 @@ def _apply_export_all_warning(): dialog.buttonLayout.insertStretch(1) dialog.exec() except Exception as e: - logger.exception(f"导出所有数据失败: {e}") + logger.warning(f"导出所有数据失败: {e}") dialog = MessageBox( get_any_position_value_async( "basic_settings", "data_import_export", "export_failure_title", "name" @@ -1623,7 +1623,7 @@ def _apply_overwrite(): success_dialog.exec() except Exception as e: - logger.exception(f"导入所有数据失败: {e}") + logger.warning入所有数据失败: {e}") # 显示错误消息 dialog = MessageBox( get_any_position_value_async( @@ -1779,7 +1779,7 @@ def _load_drawn_records(file_path: str) -> dict: return drawn_records except (json.JSONDecodeError, IOError) as e: - logger.exception(f"读取已抽取记录失败: {e}") + logger.warning{e}") return {} @@ -1824,7 +1824,7 @@ def _save_drawn_records(file_path: str, drawn_records: dict) -> None: with open(file_path, "w", encoding="utf-8") as file: json.dump(drawn_records, file, ensure_ascii=False, indent=2) except IOError as e: - logger.exception(f"保存已抽取记录失败: {e}") + logger.warning(f"保存已抽取记录失败: {e}") # ======= 读取已抽取记录 ======= @@ -1866,7 +1866,7 @@ def read_drawn_record(class_name: str, gender: str, group: str): logger.debug(f"已读取{class_name}_{gender}_{group}已抽取记录") return drawn_records except (json.JSONDecodeError, IOError) as e: - logger.exception(f"读取已抽取记录失败: {e}") + logger.warning(f"读取已抽取记录失败: {e}") return [] else: logger.debug(f"文件 {file_path} 不存在") @@ -1898,7 +1898,7 @@ def remove_record(class_name: str, gender: str, group: str, _prefix: str = "0"): file_name = os.path.basename(os.path.dirname(file_path)) logger.info(f"已删除记录文件夹: {file_name}") except OSError as e: - logger.exception(f"删除文件{file_path}失败: {e}") + logger.warning(f"删除文件{file_path}失败: {e}") elif prefix == "until": # 只删除特定前缀的文件 file_path = get_data_path( @@ -1910,7 +1910,7 @@ def remove_record(class_name: str, gender: str, group: str, _prefix: str = "0"): file_name = os.path.basename(os.path.dirname(file_path)) logger.info(f"已删除记录文件夹: {file_name}") except OSError as e: - logger.exception(f"删除文件{file_path}失败: {e}") + logger.warning(f"删除文件{file_path}失败: {e}") elif prefix == "restart": # 重启后清除 # 构建搜索模式,匹配所有前缀的文件夹 search_pattern = os.path.join("data", "TEMP", "draw_*.json") @@ -1923,7 +1923,7 @@ def remove_record(class_name: str, gender: str, group: str, _prefix: str = "0"): file_name = os.path.basename(os.path.dirname(file_path)) logger.info(f"已删除记录文件夹: {file_name}") except OSError as e: - logger.exception(f"删除文件{file_path}失败: {e}") + logger.warning(f"删除文件{file_path}失败: {e}") def reset_drawn_record(self, class_name: str, gender: str, group: str): @@ -2071,7 +2071,7 @@ def read_drawn_record_simple(pool_name: str): res.append((item["name"], int(item.get("count", 1)))) return res except Exception as e: - logger.exception(f"读取奖池已抽取记录失败: {e}") + logger.warning(f"读取奖池已抽取记录失败: {e}") return [] return [] @@ -2083,7 +2083,7 @@ def reset_drawn_prize_record(self, pool_name: str): try: os.remove(fp) except OSError as e: - logger.exception(f"删除文件{fp}失败: {e}") + logger.warning(f"删除文件{fp}失败: {e}") show_notification( NotificationType.INFO, NotificationConfig( @@ -2094,7 +2094,7 @@ def reset_drawn_prize_record(self, pool_name: str): parent=self, ) except Exception as e: - logger.exception(f"重置奖池抽取记录失败: {e}") + logger.warning(f"重置奖池抽取记录失败: {e}") def set_autostart(enabled: bool) -> bool: @@ -2145,5 +2145,5 @@ def set_autostart(enabled: bool) -> bool: else: return False except Exception as e: - logger.exception(f"设置开机自启动失败: {e}") + logger.warning(f"设置开机自启动失败: {e}") return False diff --git a/app/tools/language_manager.py b/app/tools/language_manager.py index 6d0c6913..b59db881 100644 --- a/app/tools/language_manager.py +++ b/app/tools/language_manager.py @@ -257,7 +257,7 @@ def _merge_language_files( merged[attr_name] = zh_cn_data except Exception as e: - logger.exception(f"导入语言模块 {file_path} 时出错: {e}") + logger.warning(f"导入语言模块 {file_path} 时出错: {e}") continue return merged @@ -288,7 +288,7 @@ def _load_all_languages(self) -> None: language_data = json.load(f) self._loaded_languages[language_code] = language_data except Exception as e: - logger.exception(f"加载语言文件 {filename} 时出错: {e}") + logger.warning(f"加载语言文件 {filename} 时出错: {e}") except Exception as e: logger.exception(f"加载语言文件夹时出错: {e}") diff --git a/app/tools/settings_access.py b/app/tools/settings_access.py index cd6fafc5..1ce1b550 100644 --- a/app/tools/settings_access.py +++ b/app/tools/settings_access.py @@ -37,7 +37,7 @@ def run(self): # logger.debug(f"读取设置: {self.first_level_key}.{self.second_level_key} = {value}") self.finished.emit(value) except Exception as e: - logger.exception(f"读取设置失败: {e}") + logger.warning(f"读取设置失败: {e}") default_value = self._get_default_value() self.finished.emit(default_value) @@ -162,7 +162,7 @@ def readme_settings(first_level_key: str, second_level_key: str): # logger.debug(f"使用默认设置: {first_level_key}.{second_level_key} = {default_value}") return default_value except Exception as e: - logger.exception(f"读取设置失败: {e}") + logger.warning(f"读取设置失败: {e}") default_setting = _get_default_setting(first_level_key, second_level_key) if isinstance(default_setting, dict) and "default_value" in default_setting: return default_setting["default_value"] @@ -246,7 +246,7 @@ def update_settings(first_level_key: str, second_level_key: str, value: Any): first_level_key, second_level_key, value ) except Exception as e: - logger.exception(f"设置更新失败: {e}") + logger.warning(f"设置更新失败: {e}") def _get_default_setting(first_level_key: str, second_level_key: str): diff --git a/app/tools/settings_default.py b/app/tools/settings_default.py index 4053efa9..a48e5cf4 100644 --- a/app/tools/settings_default.py +++ b/app/tools/settings_default.py @@ -93,7 +93,7 @@ def manage_settings_file(): with open_file(settings_file, "r", encoding="utf-8") as f: current_settings = json.load(f) except Exception as e: - logger.exception(f"读取设置文件失败: {e},将重新创建默认设置文件") + logger.warning(f"读取设置文件失败: {e},将重新创建默认设置文件") flat_settings = {} for first_level_key, first_level_value in default_settings.items(): flat_settings[first_level_key] = {} @@ -184,4 +184,4 @@ def manage_settings_file(): pass except Exception as e: - logger.exception(f"管理设置文件时发生错误: {e}") + logger.warning(f"管理设置文件时发生错误: {e}") diff --git a/app/tools/update_utils.py b/app/tools/update_utils.py index b6aa544d..045d39fc 100644 --- a/app/tools/update_utils.py +++ b/app/tools/update_utils.py @@ -45,7 +45,7 @@ def _run_async_func(async_func: Any, *args: Any, **kwargs: Any) -> Any: try: return asyncio.run(async_func(*args, **kwargs)) except Exception as e: - logger.exception(f"运行异步函数失败: {e}") + logger.warning(f"运行异步函数失败: {e}") return None @@ -63,13 +63,13 @@ def check_exe_integrity(exe_path: str) -> bool: # 检查文件是否存在 if not Path(exe_path).exists(): - logger.exception(f"EXE文件不存在: {exe_path}") + logger.warning(f"EXE文件不存在: {exe_path}") return False # 检查文件大小 file_size = Path(exe_path).stat().st_size if file_size == 0: - logger.exception(f"EXE文件大小为0: {exe_path}") + logger.warning(f"EXE文件大小为0: {exe_path}") return False # 检查PE文件头(Windows可执行文件) @@ -77,13 +77,13 @@ def check_exe_integrity(exe_path: str) -> bool: # 读取前两个字节,检查MZ签名 magic = f.read(2) if magic != b"MZ": - logger.exception(f"EXE文件格式错误,不是有效的PE文件: {exe_path}") + logger.warning(f"EXE文件格式错误,不是有效的PE文件: {exe_path}") return False logger.debug(f"EXE安装程序完整性检查通过: {exe_path}") return True except Exception as e: - logger.exception(f"检查EXE安装程序完整性失败: {e}") + logger.warning(f"检查EXE安装程序完整性失败: {e}") return False @@ -104,7 +104,7 @@ def check_update_file_integrity(file_path: str, file_type: str = None) -> bool: if file_ext == ".exe": file_type = "exe" else: - logger.exception( + logger.warning( f"不支持的更新文件类型: {file_ext},仅支持 EXE 安装程序" ) return False @@ -113,10 +113,10 @@ def check_update_file_integrity(file_path: str, file_type: str = None) -> bool: if file_type == "exe": return check_exe_integrity(file_path) else: - logger.exception(f"不支持的文件类型: {file_type},仅支持 EXE 安装程序") + logger.warning(f"不支持的文件类型: {file_type},仅支持 EXE 安装程序") return False except Exception as e: - logger.exception(f"检查更新文件完整性失败: {e}") + logger.warning(f"检查更新文件完整性失败: {e}") return False @@ -135,12 +135,12 @@ async def run_installer_and_exit(exe_path: str) -> bool: # 验证安装程序存在 if not Path(exe_path).exists(): - logger.exception(f"安装程序不存在: {exe_path}") + logger.warning(f"安装程序不存在: {exe_path}") return False # 检查安装程序完整性 if not check_exe_integrity(exe_path): - logger.exception(f"安装程序不完整或已损坏: {exe_path}") + logger.warning(f"安装程序不完整或已损坏: {exe_path}") return False # 使用 subprocess 启动安装程序 @@ -171,7 +171,7 @@ async def run_installer_and_exit(exe_path: str) -> bool: return True except Exception as e: - logger.exception(f"运行安装程序失败: {e}") + logger.warning(f"运行安装程序失败: {e}") return False @@ -271,7 +271,7 @@ async def get_best_source() -> dict: return best_source except Exception as e: - logger.exception(f"获取最佳镜像源失败: {e}") + logger.warning(f"获取最佳镜像源失败: {e}") return UPDATE_SOURCES[0] # 返回默认源 @@ -292,7 +292,7 @@ def get_update_source_url() -> str: else: return "https://github.com" except Exception as e: - logger.exception(f"获取更新源 URL 失败: {e}") + logger.warning(f"获取更新源 URL 失败: {e}") return "https://github.com" @@ -312,7 +312,7 @@ async def get_update_source_url_async() -> str: else: return "https://github.com" except Exception as e: - logger.exception(f"获取更新源 URL 失败: {e}") + logger.warning(f"获取更新源 URL 失败: {e}") return "https://github.com" @@ -441,7 +441,7 @@ async def get_metadata_info_async() -> dict | None: continue # 所有镜像源都失败了 - logger.exception("所有镜像源都获取 metadata.yaml 文件失败") + logger.warning("所有镜像源都获取 metadata.yaml 文件失败") return None else: # 使用指定的更新源 @@ -476,12 +476,12 @@ async def get_metadata_info_async() -> dict | None: ) return metadata except Exception as e: - logger.exception( + logger.warning( f"使用指定的更新源 {source['name']} 获取 metadata.yaml 失败: {e}" ) return None else: - logger.exception(f"无效的更新源索引: {source_index}") + logger.warning(f"无效的更新源索引: {source_index}") return None @@ -534,7 +534,7 @@ async def get_latest_version_async(channel: int | None = None) -> dict | None: ) return {"version": version, "version_no": version_no} except Exception as e: - logger.exception(f"获取最新版本信息失败: {e}") + logger.warning(f"获取最新版本信息失败: {e}") return None @@ -566,7 +566,7 @@ def compare_versions(current_version: str, latest_version: str) -> int: try: # 检查版本号是否为空 if not current_version or not latest_version: - logger.exception( + logger.warning( f"比较版本号失败: 版本号为空,current={current_version}, latest={latest_version}" ) return -1 @@ -625,7 +625,7 @@ def compare_versions(current_version: str, latest_version: str) -> int: return 0 # 版本号完全相同 except Exception as e: - logger.exception(f"比较版本号失败: {e}") + logger.warning(f"比较版本号失败: {e}") return -1 @@ -673,7 +673,7 @@ def get_update_download_url( logger.debug(f"生成更新下载 URL 成功: {download_url}") return download_url except Exception as e: - logger.exception(f"生成更新下载 URL 失败: {e}") + logger.warning(f"生成更新下载 URL 失败: {e}") # 返回默认的 GitHub 下载 URL return f"https://github.com/SECTL/SecRandom/releases/download/{version}/SecRandom-{system}-{version}-{arch}-{struct}.zip" @@ -722,7 +722,7 @@ async def get_update_download_url_async( logger.debug(f"生成更新下载 URL 成功: {download_url}") return download_url except Exception as e: - logger.exception(f"生成更新下载 URL 失败: {e}") + logger.warning(f"生成更新下载 URL 失败: {e}") # 返回默认的 GitHub 下载 URL return f"https://github.com/SECTL/SecRandom/releases/download/{version}/SecRandom-{system}-{version}-{arch}-{struct}.zip" @@ -839,7 +839,7 @@ async def download_update_async( file_path.unlink() logger.info(f"已删除损坏的文件: {file_path}") except Exception as unlink_error: - logger.exception(f"删除损坏文件失败: {unlink_error}") + logger.warning(f"删除损坏文件失败: {unlink_error}") # 继续尝试下一个镜像源 continue @@ -853,11 +853,11 @@ async def download_update_async( file_path.unlink() logger.info(f"已删除部分下载文件: {file_path}") except Exception as unlink_error: - logger.exception(f"删除部分下载文件失败: {unlink_error}") + logger.warning(f"删除部分下载文件失败: {unlink_error}") continue # 所有镜像源都失败了 - logger.exception("所有镜像源都下载更新文件失败") + logger.warning("所有镜像源都下载更新文件失败") return None @@ -912,7 +912,7 @@ async def install_update_async(file_path: str) -> bool: # 验证更新文件存在 if not Path(file_path).exists(): - logger.exception(f"更新文件不存在: {file_path}") + logger.warning(f"更新文件不存在: {file_path}") return False # 检查文件类型 @@ -920,25 +920,25 @@ async def install_update_async(file_path: str) -> bool: # 只支持 exe 安装程序 if file_ext != ".exe": - logger.exception(f"不支持的更新文件类型: {file_ext},仅支持 EXE 安装程序") + logger.warning(f"不支持的更新文件类型: {file_ext},仅支持 EXE 安装程序") return False # 检查安装程序完整性 if not check_exe_integrity(file_path): - logger.exception(f"安装程序不完整或已损坏: {file_path}") + logger.warning(f"安装程序不完整或已损坏: {file_path}") # 删除损坏的文件 try: Path(file_path).unlink() logger.info(f"已删除损坏的安装程序: {file_path}") except Exception as e: - logger.exception(f"删除损坏的安装程序失败: {e}") + logger.warning(f"删除损坏的安装程序失败: {e}") return False # 运行安装程序并退出应用程序 logger.info("准备运行 EXE 安装程序") return await run_installer_and_exit(file_path) except Exception as e: - logger.exception(f"安装更新文件失败: {e}") + logger.warning(f"安装更新文件失败: {e}") return False @@ -1279,7 +1279,7 @@ def safe_call_update_interface(method_name, *args): if success: logger.debug("自动安装更新成功") else: - logger.exception("自动安装更新失败") + logger.warning("自动安装更新失败") return else: # 文件损坏,需要重新下载 @@ -1291,7 +1291,7 @@ def safe_call_update_interface(method_name, *args): expected_file_path.unlink() logger.debug(f"已删除损坏的文件: {expected_file_path}") except Exception as e: - logger.exception(f"删除损坏文件失败: {e}") + logger.warning(f"删除损坏文件失败: {e}") # 继续执行下载流程 if compare_result == 1: @@ -1359,7 +1359,7 @@ def format_size(size_bytes): expected_file_path.unlink() logger.debug(f"已删除损坏的文件: {expected_file_path}") except Exception as e: - logger.exception(f"删除损坏文件失败: {e}") + logger.warning(f"删除损坏文件失败: {e}") # 继续执行下载流程 # 通知更新页面开始下载 @@ -1437,7 +1437,7 @@ def format_size(size_bytes): # 更新全局状态 update_status_manager.set_download_cancelled() else: - logger.exception("自动下载更新失败") + logger.warning("自动下载更新失败") # 通知更新页面下载失败 safe_call_update_interface("set_download_failed") # 更新全局状态 @@ -1456,7 +1456,7 @@ def format_size(size_bytes): # 更新上次检查时间 safe_call_update_interface("update_last_check_time") except Exception as e: - logger.exception(f"启动时检查更新失败: {e}") + logger.warning(f"启动时检查更新失败: {e}") # 通知更新页面检查失败 safe_call_update_interface("set_check_failed") finally: diff --git a/app/view/another_window/log_viewer.py b/app/view/another_window/log_viewer.py index 5ac8a76d..ce52fb04 100644 --- a/app/view/another_window/log_viewer.py +++ b/app/view/another_window/log_viewer.py @@ -155,7 +155,7 @@ def load_log_files(self): ) except Exception as e: - logger.exception(f"加载日志文件列表失败: {e}") + logger.warning(f"加载日志文件列表失败: {e}") self.status_label.setText( get_content_name_async("log_viewer", "load_failed").format(str(e)) ) @@ -195,7 +195,7 @@ def load_log_content(self, file_path): ) except Exception as e: - logger.exception(f"加载日志内容失败: {e}") + logger.warning(f"加载日志内容失败: {e}") self.status_label.setText( get_content_name_async("log_viewer", "load_failed").format(str(e)) ) @@ -263,7 +263,7 @@ def filter_logs(self, lines=None): self.display_colored_logs(filtered_lines) except Exception as e: - logger.exception(f"过滤日志失败: {e}") + logger.warning(f"过滤日志失败: {e}") def display_colored_logs(self, lines): """显示带颜色的日志""" @@ -297,7 +297,7 @@ def display_colored_logs(self, lines): self.log_text.setHtml(html_content) except Exception as e: - logger.exception(f"显示带颜色日志失败: {e}") + logger.warning(f"显示带颜色日志失败: {e}") def clear_current_log(self): """清空当前日志文件""" @@ -331,7 +331,7 @@ def clear_current_log(self): ) except Exception as e: - logger.exception(f"清空日志文件失败: {e}") + logger.warning(f"清空日志文件失败: {e}") self.status_label.setText( get_content_name_async("log_viewer", "clear_failed").format(str(e)) ) @@ -383,7 +383,7 @@ def clear_all_logs(self): ) except Exception as e: - logger.exception(f"清空全部日志文件失败: {e}") + logger.warning(f"清空全部日志文件失败: {e}") self.status_label.setText( get_content_name_async("log_viewer", "clear_all_failed").format(str(e)) ) @@ -402,7 +402,7 @@ def open_log_folder(self): os.startfile(log_dir) except Exception as e: - logger.exception(f"打开日志文件夹失败: {e}") + logger.warning(f"打开日志文件夹失败: {e}") self.status_label.setText( get_content_name_async("log_viewer", "open_folder_failed").format( str(e) diff --git a/app/view/another_window/prize/import_prize_name.py b/app/view/another_window/prize/import_prize_name.py index f5ef54f2..252b5d6a 100644 --- a/app/view/another_window/prize/import_prize_name.py +++ b/app/view/another_window/prize/import_prize_name.py @@ -425,7 +425,7 @@ def __load_file(self, file_path: str): self.fileLoaded.emit(data, columns) except Exception as e: - logger.exception(f"加载文件失败: {e}") + logger.warning(f"加载文件失败: {e}") # 通过信号通知UI线程文件加载失败 self.fileLoadError.emit(str(e)) @@ -637,7 +637,7 @@ def __import_data(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"导入数据失败: {e}") + logger.warning(f"导入数据失败: {e}") def __save_prize_data(self, pool_name: str, prize_rows: List[Dict[str, Any]]): """保存奖品数据到班级名单文件""" diff --git a/app/view/another_window/prize/prize_name_setting.py b/app/view/another_window/prize/prize_name_setting.py index 0a151745..0fc53c1c 100644 --- a/app/view/another_window/prize/prize_name_setting.py +++ b/app/view/another_window/prize/prize_name_setting.py @@ -128,7 +128,7 @@ def __load_existing_prize_names(self): return names except Exception as e: - logger.exception(f"加载奖品名称失败: {str(e)}") + logger.warning(f"加载奖品名称失败: {str(e)}") self.initial_names = [] return [] @@ -303,7 +303,7 @@ def __save_names(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存奖品名称失败: {e}") + logger.warning(f"保存奖品名称失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/prize/prize_weight_setting.py b/app/view/another_window/prize/prize_weight_setting.py index a6c2b8b1..df575d2b 100644 --- a/app/view/another_window/prize/prize_weight_setting.py +++ b/app/view/another_window/prize/prize_weight_setting.py @@ -129,7 +129,7 @@ def __load_existing_weights(self): return weights except Exception as e: - logger.exception(f"加载奖品权重失败: {str(e)}") + logger.warning(f"加载奖品权重失败: {str(e)}") self.initial_weights = [] return [] @@ -315,7 +315,7 @@ def __save_weights(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存奖品权重失败: {e}") + logger.warning(f"保存奖品权重失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/prize/set_pool_name.py b/app/view/another_window/prize/set_pool_name.py index 7dd11cdd..ce4c1433 100644 --- a/app/view/another_window/prize/set_pool_name.py +++ b/app/view/another_window/prize/set_pool_name.py @@ -92,7 +92,7 @@ def __create_pool_name_input_area(self): self.text_edit.setPlainText("\n".join(pool_names)) self.initial_pool_names = pool_names.copy() # 保存初始奖池列表 except Exception as e: - logger.exception(f"加载奖池名称失败: {str(e)}") + logger.warning(f"加载奖池名称失败: {str(e)}") self.initial_pool_names = [] # 出错时设为空列表 input_layout.addWidget(self.text_edit) @@ -178,7 +178,7 @@ def __on_text_changed(self): # 更新初始奖池列表为当前列表,避免重复提示 self.initial_pool_names = current_pool_names.copy() except Exception as e: - logger.exception(f"检测奖池变化失败: {e}") + logger.warning(f"检测奖池变化失败: {e}") def __save_pool_names(self): """保存奖池名称""" @@ -342,7 +342,7 @@ def __save_pool_names(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存奖池名称失败: {e}") + logger.warning(f"保存奖池名称失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/student/gender_setting.py b/app/view/another_window/student/gender_setting.py index 398f0bb8..95af5456 100644 --- a/app/view/another_window/student/gender_setting.py +++ b/app/view/another_window/student/gender_setting.py @@ -131,7 +131,7 @@ def __load_existing_genders(self): return genders except Exception as e: - logger.exception(f"加载性别失败: {str(e)}") + logger.warning(f"加载性别失败: {str(e)}") self.initial_genders = [] return [] @@ -311,7 +311,7 @@ def __save_genders(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存性别失败: {e}") + logger.warning(f"保存性别失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/student/group_setting.py b/app/view/another_window/student/group_setting.py index 8644eb09..774cc06b 100644 --- a/app/view/another_window/student/group_setting.py +++ b/app/view/another_window/student/group_setting.py @@ -131,7 +131,7 @@ def __load_existing_groups(self): return groups except Exception as e: - logger.exception(f"加载小组失败: {str(e)}") + logger.warning(f"加载小组失败: {str(e)}") self.initial_groups = [] return [] @@ -309,7 +309,7 @@ def __save_groups(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存小组失败: {e}") + logger.warning(f"保存小组失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/student/import_student_name.py b/app/view/another_window/student/import_student_name.py index 8284d970..bce83f04 100644 --- a/app/view/another_window/student/import_student_name.py +++ b/app/view/another_window/student/import_student_name.py @@ -429,7 +429,7 @@ def __load_file(self, file_path: str): self.fileLoaded.emit(data, columns) except Exception as e: - logger.exception(f"加载文件失败: {e}") + logger.warning(f"加载文件失败: {e}") # 通过信号通知UI线程文件加载失败 self.fileLoadError.emit(str(e)) @@ -671,7 +671,7 @@ def __import_data(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"导入数据失败: {e}") + logger.warning(f"导入数据失败: {e}") def __save_student_data(self, class_name: str, student_data: List[Dict[str, Any]]): """保存学生数据到班级名单文件""" diff --git a/app/view/another_window/student/name_setting.py b/app/view/another_window/student/name_setting.py index bccfb721..6b3d1419 100644 --- a/app/view/another_window/student/name_setting.py +++ b/app/view/another_window/student/name_setting.py @@ -129,7 +129,7 @@ def __load_existing_names(self): return names except Exception as e: - logger.exception(f"加载姓名失败: {str(e)}") + logger.warning(f"加载姓名失败: {str(e)}") self.initial_names = [] return [] @@ -298,7 +298,7 @@ def __save_names(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存姓名失败: {e}") + logger.warning(f"保存姓名失败: {e}") def __cancel(self): """取消操作""" diff --git a/app/view/another_window/student/set_class_name.py b/app/view/another_window/student/set_class_name.py index fa61549f..81fd9767 100644 --- a/app/view/another_window/student/set_class_name.py +++ b/app/view/another_window/student/set_class_name.py @@ -92,7 +92,7 @@ def __create_class_name_input_area(self): self.text_edit.setPlainText("\n".join(class_names)) self.initial_class_names = class_names.copy() # 保存初始班级列表 except Exception as e: - logger.exception(f"加载班级名称失败: {str(e)}") + logger.warning(f"加载班级名称失败: {str(e)}") self.initial_class_names = [] # 出错时设为空列表 input_layout.addWidget(self.text_edit) @@ -178,7 +178,7 @@ def __on_text_changed(self): # 更新初始班级列表为当前列表,避免重复提示 self.initial_class_names = current_class_names.copy() except Exception as e: - logger.exception(f"检测班级变化失败: {e}") + logger.warning(f"检测班级变化失败: {e}") def __save_class_names(self): """保存班级名称""" @@ -347,7 +347,7 @@ def __save_class_names(self): duration=3000, ) show_notification(NotificationType.ERROR, config, parent=self) - logger.exception(f"保存班级名称失败: {e}") + logger.warning(f"保存班级名称失败: {e}") def __close_window(self): """关闭窗口""" diff --git a/app/view/another_window/usb/bind_usb.py b/app/view/another_window/usb/bind_usb.py index 22867876..df8f27dd 100644 --- a/app/view/another_window/usb/bind_usb.py +++ b/app/view/another_window/usb/bind_usb.py @@ -216,7 +216,7 @@ def __bind(self): f"{get_content_name_async('basic_safety_settings', 'usb_bind_success')}: {text}" ) except Exception as e: - logger.exception(f"绑定设备失败:{device}, 错误:{e}") + logger.warning(f"绑定设备失败:{device}, 错误:{e}") self._notify_error(str(e)) def __cancel(self): diff --git a/app/view/main/window.py b/app/view/main/window.py index 629478d6..db6091c5 100644 --- a/app/view/main/window.py +++ b/app/view/main/window.py @@ -163,7 +163,7 @@ def restart_ipc_server(self, new_port: int): logger.info(f"IPC服务器已在端口 {new_port} 上重新启动") return True else: - logger.exception(f"IPC服务器在端口 {new_port} 上启动失败") + logger.warning(f"IPC服务器在端口 {new_port} 上启动失败") return False else: logger.exception("无法访问URLHandler实例") @@ -663,7 +663,7 @@ def close_window_secrandom(self): CSharpIPCHandler.instance().stop_ipc_client() logger.debug("C# IPC 停止请求已发出") except Exception as e: - logger.exception(f"停止 IPC 客户端失败: {e}") + logger.warning(f"停止 IPC 客户端失败: {e}") # 显式关闭所有顶层窗口(包括悬浮窗、设置窗口等) try: diff --git a/app/view/settings/basic_settings.py b/app/view/settings/basic_settings.py index 91270503..31f811ed 100644 --- a/app/view/settings/basic_settings.py +++ b/app/view/settings/basic_settings.py @@ -487,7 +487,7 @@ def __on_url_protocol_changed(self, checked): parent=self.window(), ) except Exception as e: - logger.exception(f"URL协议设置错误: {e}") + logger.warning(f"URL协议设置错误: {e}") # 发生错误时恢复原状态 self.url_protocol_switch.setChecked(not checked) @@ -541,7 +541,7 @@ def _restart_ipc_server(self, new_port: int): if success: logger.info(f"IPC服务器已成功重启,使用新端口: {new_port}") else: - logger.exception(f"重启IPC服务器失败,端口: {new_port}") + logger.warning(f"重启IPC服务器失败,端口: {new_port}") show_notification( NotificationType.ERROR, NotificationConfig( @@ -557,7 +557,7 @@ def _restart_ipc_server(self, new_port: int): else: logger.warning("无法获取主窗口实例,无法重启IPC服务器") except Exception as e: - logger.exception(f"重启IPC服务器时发生错误: {e}") + logger.warning(f"重启IPC服务器时发生错误: {e}") show_notification( NotificationType.ERROR, NotificationConfig( @@ -813,7 +813,7 @@ def open_log_viewer(self): try: create_log_viewer_window() except Exception as e: - logger.exception(f"打开日志查看窗口失败: {e}") + logger.warning(f"打开日志查看窗口失败: {e}") show_notification( NotificationType.ERROR, NotificationConfig( diff --git a/app/view/settings/history/history_management.py b/app/view/settings/history/history_management.py index 0a2fec1b..29b11c6d 100644 --- a/app/view/settings/history/history_management.py +++ b/app/view/settings/history/history_management.py @@ -200,7 +200,7 @@ def clear_roll_call_history(self): position=InfoBarPosition.TOP, ) except Exception as e: - logger.exception(f"清除点名历史记录失败: {e}") + logger.warning(f"清除点名历史记录失败: {e}") # 显示错误通知 show_error_notification( title=get_content_name_async( @@ -430,7 +430,7 @@ def clear_lottery_history(self): position=InfoBarPosition.TOP, ) except Exception as e: - logger.exception(f"清除抽奖历史记录失败: {e}") + logger.warning(f"清除抽奖历史记录失败: {e}") # 显示错误通知 show_error_notification( title=get_content_name_async( diff --git a/app/view/settings/history/lottery_history_table.py b/app/view/settings/history/lottery_history_table.py index ac0e9cb3..3edbdcc3 100644 --- a/app/view/settings/history/lottery_history_table.py +++ b/app/view/settings/history/lottery_history_table.py @@ -418,7 +418,7 @@ def sort_key(lottery): self.current_row = end_row except Exception as e: - logger.exception(f"加载奖品数据失败: {e}") + logger.warning(f"加载奖品数据失败: {e}") Dialog("错误", f"加载奖品数据失败: {e}", self).exec() def _load_more_sessions_data(self): @@ -496,7 +496,7 @@ def sort_key(lottery): self.current_row = end_row except Exception as e: - logger.exception(f"加载会话数据失败: {e}") + logger.warning(f"加载会话数据失败: {e}") Dialog("错误", f"加载会话数据失败: {e}", self).exec() def _load_more_stats_data(self, lottery_name): @@ -573,7 +573,7 @@ def sort_key(lottery): self.current_row = end_row except Exception as e: - logger.exception(f"加载统计数据失败: {e}") + logger.warning(f"加载统计数据失败: {e}") Dialog("错误", f"加载统计数据失败: {e}", self).exec() def setup_file_watcher(self): @@ -774,7 +774,7 @@ def refresh_data(self): self.table.horizontalHeader().setSortIndicatorShown(True) except Exception as e: - logger.exception(f"刷新表格数据失败: {str(e)}") + logger.warning(f"刷新表格数据失败: {str(e)}") finally: self.table.blockSignals(False) @@ -886,5 +886,5 @@ def _update_subject_list(self): self.subject_comboBox.show() except Exception as e: - logger.exception(f"更新课程列表失败: {e}") + logger.warning(f"更新课程列表失败: {e}") self.available_subjects = [] diff --git a/app/view/settings/history/roll_call_history_table.py b/app/view/settings/history/roll_call_history_table.py index d762b87e..c46f5605 100644 --- a/app/view/settings/history/roll_call_history_table.py +++ b/app/view/settings/history/roll_call_history_table.py @@ -485,7 +485,7 @@ def sort_key(student): self.current_row = end_row except Exception as e: - logger.exception(f"加载学生数据失败: {e}") + logger.warning(f"加载学生数据失败: {e}") def _load_more_sessions_data(self): """加载更多会话数据""" @@ -587,7 +587,7 @@ def sort_key(student): self.current_row = end_row except Exception as e: - logger.exception(f"加载会话数据失败: {e}") + logger.warning(f"加载会话数据失败: {e}") def _load_more_stats_data(self, student_name): """加载更多统计数据""" @@ -702,7 +702,7 @@ def sort_key(student): self.current_row = end_row except Exception as e: - logger.exception(f"加载统计数据失败: {e}") + logger.warning(f"加载统计数据失败: {e}") def setup_file_watcher(self): """设置文件系统监视器,监控班级历史记录文件夹的变化""" @@ -866,7 +866,7 @@ def _update_subject_list(self): self.subject_comboBox.show() except Exception as e: - logger.exception(f"更新课程列表失败: {e}") + logger.warning(f"更新课程列表失败: {e}") self.available_subjects = [] def refresh_data(self): @@ -987,7 +987,7 @@ def refresh_data(self): self.table.horizontalHeader().setSortIndicatorShown(True) except Exception as e: - logger.exception(f"刷新表格数据失败: {str(e)}") + logger.warning(f"刷新表格数据失败: {str(e)}") finally: self.table.blockSignals(False) diff --git a/app/view/settings/linkage_settings/linkage_settings.py b/app/view/settings/linkage_settings/linkage_settings.py index 6092f0d2..a409a593 100644 --- a/app/view/settings/linkage_settings/linkage_settings.py +++ b/app/view/settings/linkage_settings/linkage_settings.py @@ -164,7 +164,7 @@ def _update_schedule_info(self): class_info = parser.get_class_info() total_class_periods += len(class_info) except Exception as e: - logger.exception(f"解析文件{file_name}失败: {e}") + logger.warning(f"解析文件{file_name}失败: {e}") # 判断是否有课程表数据 if total_class_periods > 0: @@ -182,7 +182,7 @@ def _update_schedule_info(self): ) except Exception as e: - logger.exception(f"更新课程表信息失败: {e}") + logger.warning(f"更新课程表信息失败: {e}") self.schedule_info_label.setText("获取课程表信息失败") def on_import_file_clicked(self): @@ -238,7 +238,7 @@ def _import_cses_file(self, file_path: str): ) except Exception as e: - logger.exception(f"导入CSES文件失败: {e}") + logger.warning(f"导入CSES文件失败: {e}") import_error_msg = get_content_name_async( "linkage_settings", "import_error" ) @@ -276,7 +276,7 @@ def on_view_current_config_clicked(self): create_current_config_viewer_window() except Exception as e: - logger.exception(f"显示当前配置失败: {e}") + logger.warning(f"显示当前配置失败: {e}") InfoBar.error( title=get_content_name_async("linkage_settings", "import_failed"), content=f"无法显示当前配置: {str(e)}", diff --git a/app/view/settings/more_settings/music_settings.py b/app/view/settings/more_settings/music_settings.py index 8d5cbf47..927de1f8 100644 --- a/app/view/settings/more_settings/music_settings.py +++ b/app/view/settings/more_settings/music_settings.py @@ -125,7 +125,7 @@ def import_music(self): shutil.copy2(src_file, dst_file) except Exception as e: - logger.exception( + logger.warning( f"导入音乐文件失败: {src_file.name}, 错误: {e}" ) @@ -147,7 +147,7 @@ def delete_music(self): try: remove_file(audio_file_path) except Exception as e: - logger.exception(f"删除音乐文件失败: {current_text}, 错误: {e}") + logger.warning(f"删除音乐文件失败: {current_text}, 错误: {e}") # 刷新音乐文件列表 self.refresh_music_files() diff --git a/app/view/settings/update.py b/app/view/settings/update.py index ccce152e..46e58cb2 100644 --- a/app/view/settings/update.py +++ b/app/view/settings/update.py @@ -354,7 +354,7 @@ def check_update_task(): # 更新全局状态 update_status_manager.set_check_failed() except Exception as e: - logger.exception(f"检查更新时发生错误: {e}") + logger.warning(f"检查更新时发生错误: {e}") # 处理异常 status_text = get_content_name_async("update", "check_update_failed") # 隐藏下载并安装按钮 @@ -500,7 +500,7 @@ def format_size(size_bytes): expected_file_path.unlink() logger.debug(f"已删除损坏的文件: {expected_file_path}") except Exception as e: - logger.exception(f"删除损坏文件失败: {e}") + logger.warning(f"删除损坏文件失败: {e}") # 如果文件完整且存在,直接使用,不需要下载 if file_exists_and_same_version: @@ -692,7 +692,7 @@ def run(self): ) self.on_complete(file_path) except Exception as e: - logger.exception(f"下载任务执行失败: {e}") + logger.warning(f"下载任务执行失败: {e}") # 确保即使发生异常也会调用完成回调 self.on_complete(None) diff --git a/app/view/settings/voice_settings/basic_voice_settings.py b/app/view/settings/voice_settings/basic_voice_settings.py index acba4e9b..80f4bacf 100644 --- a/app/view/settings/voice_settings/basic_voice_settings.py +++ b/app/view/settings/voice_settings/basic_voice_settings.py @@ -172,11 +172,11 @@ def on_voices_fetched(self, voices): logger.debug(f"Edge TTS语音列表已更新,共{len(voices)}个语音") except Exception as e: - logger.exception(f"处理Edge TTS语音列表失败: {e}") + logger.warning(f"处理Edge TTS语音列表失败: {e}") def on_voices_fetch_error(self, error): """语音列表获取失败后的处理""" - logger.exception(f"获取Edge TTS语音列表失败: {error}") + logger.warning(f"获取Edge TTS语音列表失败: {error}") def __del__(self): """析构函数,确保worker正确终止""" diff --git a/app/view/settings/voice_settings/specific_announcements.py b/app/view/settings/voice_settings/specific_announcements.py index 89ca82b2..7a97cb7c 100644 --- a/app/view/settings/voice_settings/specific_announcements.py +++ b/app/view/settings/voice_settings/specific_announcements.py @@ -294,7 +294,7 @@ def on_item_changed(self, item): item_type = "学生" if self.current_mode == 0 else "奖品" logger.debug(f"已更新{item_type} {name_field} 的语音播报设置") except Exception as e: - logger.exception(f"更新语音播报设置失败: {e}") + logger.warning(f"更新语音播报设置失败: {e}") def setup_file_watcher(self): """设置文件系统监视器,监控历史记录文件夹的变化""" @@ -462,7 +462,7 @@ def refresh_data(self): self.original_items.append(row_items) except Exception as e: - logger.exception(f"刷新表格数据失败: {str(e)}") + logger.warning(f"刷新表格数据失败: {str(e)}") finally: # 恢复信号 self.table.blockSignals(False)