mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-17 23:13:03 +08:00
feat(MsgBase, gui, operators): 增强日志输出功能
- 为 _showTrace 方法添加 no_log 参数,支持控制日志写入 - 在主窗口各关键操作点添加日志输出 - 优化错误信息输出策略,分离 trace 和 log 输出 - 改进配置目录初始化过程的日志记录
This commit is contained in:
+3
-2
@@ -70,12 +70,13 @@ class MsgBase:
|
||||
def _showTrace(
|
||||
self,
|
||||
msg: str,
|
||||
level: int = logging.INFO
|
||||
level: int = logging.INFO,
|
||||
no_log: bool = False
|
||||
):
|
||||
|
||||
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||
self._output_queue.put(f"{timestamp}-[{self._class_name:<15}] : {msg}")
|
||||
if self._logger:
|
||||
if self._logger and not no_log:
|
||||
self._logger.log(level, msg)
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
self.connectSignals()
|
||||
self.startMsgPolling()
|
||||
self.startTimerTaskPolling()
|
||||
self._showLog("主窗口初始化完成")
|
||||
|
||||
|
||||
def modifyUi(
|
||||
@@ -186,6 +187,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
if self.__alConfigWidget:
|
||||
self.__alConfigWidget.close()
|
||||
# the config widget is already deleted in the 'self.onConfigWidgetClosed'
|
||||
self._showLog("主窗口关闭")
|
||||
QMainWindow.closeEvent(self, event)
|
||||
|
||||
|
||||
@@ -300,6 +302,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
self.__alConfigWidget = None
|
||||
self.__config_paths = ConfigManager.getValidateAutomationConfigPaths()
|
||||
self.setControlButtons(True, None, None)
|
||||
self._showLog("配置窗口已关闭,配置文件路径已更新")
|
||||
|
||||
@Slot(dict)
|
||||
def onTimerTaskIsReady(
|
||||
@@ -347,6 +350,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
self.__alTimerTaskManageWidget.raise_()
|
||||
self.__alTimerTaskManageWidget.activateWindow()
|
||||
self.TimerTaskManageWidgetButton.setEnabled(False)
|
||||
self._showLog("打开定时任务管理窗口")
|
||||
|
||||
@Slot()
|
||||
def onConfigButtonClicked(
|
||||
@@ -360,6 +364,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
self.__alConfigWidget.raise_()
|
||||
self.__alConfigWidget.activateWindow()
|
||||
self.ConfigButton.setEnabled(False)
|
||||
self._showLog("打开配置窗口")
|
||||
|
||||
@Slot()
|
||||
def onStartButtonClicked(
|
||||
@@ -376,6 +381,7 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
self.__auto_lib_thread.autoLibWorkerIsFinished.connect(self.onStopButtonClicked)
|
||||
self.__auto_lib_thread.autoLibWorkerFinishedWithError.connect(self.onStopButtonClicked)
|
||||
self.__auto_lib_thread.start()
|
||||
self._showLog("开始手动执行任务")
|
||||
|
||||
@Slot()
|
||||
def onStopButtonClicked(
|
||||
@@ -383,14 +389,15 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
||||
):
|
||||
|
||||
if self.__auto_lib_thread:
|
||||
self._showTrace("正在停止操作......")
|
||||
self._showTrace("正在停止操作......", no_log=True)
|
||||
self.__auto_lib_thread.wait(2000)
|
||||
self._showTrace("操作已停止")
|
||||
self._showTrace("操作已停止", no_log=True)
|
||||
self.__auto_lib_thread.autoLibWorkerIsFinished.disconnect(self.onStopButtonClicked)
|
||||
self.__auto_lib_thread.autoLibWorkerFinishedWithError.disconnect(self.onStopButtonClicked)
|
||||
self.__auto_lib_thread.deleteLater()
|
||||
self.__auto_lib_thread = None
|
||||
self.setControlButtons(None, False, True)
|
||||
self._showLog("任务已停止")
|
||||
|
||||
@Slot()
|
||||
def onSendButtonClicked(
|
||||
|
||||
+29
-11
@@ -44,9 +44,11 @@ class AutoLibWorker(MsgBase, QThread):
|
||||
current_time = time.strftime("%H:%M", time.localtime())
|
||||
if current_time >= "23:30" or current_time <= "07:30":
|
||||
self._showTrace(
|
||||
"当前时间不在图书馆开放时间内, 请在 07:30 - 23:30 之间尝试"
|
||||
"当前时间不在图书馆开放时间内, 请在 07:30 - 23:30 之间尝试",
|
||||
self.TraceLevel.WARNING
|
||||
)
|
||||
return False
|
||||
self._showLog(f"时间检查通过, 当前时间: {current_time}", self.TraceLevel.INFO)
|
||||
return True
|
||||
|
||||
|
||||
@@ -57,8 +59,12 @@ class AutoLibWorker(MsgBase, QThread):
|
||||
if not all(
|
||||
os.path.exists(path) for path in self.__config_paths.values()
|
||||
):
|
||||
self._showTrace("配置文件路径不存在, 请检查配置文件路径是否正确")
|
||||
self._showTrace(
|
||||
"配置文件路径不存在, 请检查配置文件路径是否正确",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
return False
|
||||
self._showLog(f"配置文件路径检查通过, 路径: {self.__config_paths}", self.TraceLevel.INFO)
|
||||
return True
|
||||
|
||||
|
||||
@@ -67,22 +73,28 @@ class AutoLibWorker(MsgBase, QThread):
|
||||
) -> bool:
|
||||
|
||||
self._showTrace(
|
||||
f"正在加载配置文件, 运行配置文件路径: {self.__config_paths["run"]}"
|
||||
f"正在加载配置文件, 运行配置文件路径: {self.__config_paths["run"]}",
|
||||
no_log=True
|
||||
)
|
||||
self.__run_config = JSONReader(self.__config_paths["run"]).data()
|
||||
self._showTrace(
|
||||
f"正在加载配置文件, 用户配置文件路径: {self.__config_paths["user"]}"
|
||||
f"正在加载配置文件, 用户配置文件路径: {self.__config_paths["user"]}",
|
||||
no_log=True
|
||||
)
|
||||
self.__user_config = JSONReader(self.__config_paths["user"]).data()
|
||||
if self.__run_config is None or self.__user_config is None:
|
||||
self._showTrace("配置文件加载失败, 请检查配置文件是否正确")
|
||||
self._showTrace("配置文件加载失败, 请检查配置文件是否正确")
|
||||
self._showTrace(
|
||||
"配置文件加载失败, 请检查配置文件是否正确",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
return False
|
||||
if not self.__user_config.get("groups"):
|
||||
self._showTrace(
|
||||
"用户配置文件中无有效任务组, 请检查用户配置文件是否正确"
|
||||
"用户配置文件中无有效任务组, 请检查用户配置文件是否正确",
|
||||
self.TraceLevel.WARNING
|
||||
)
|
||||
return False
|
||||
self._showLog(f"配置文件加载成功, 任务组数量: {len(self.__user_config.get('groups', []))}", self.TraceLevel.INFO)
|
||||
return True
|
||||
|
||||
|
||||
@@ -108,14 +120,17 @@ class AutoLibWorker(MsgBase, QThread):
|
||||
groups = self.__user_config.get("groups")
|
||||
for group in groups:
|
||||
if not group["enabled"]:
|
||||
self._showTrace(f"任务组 {group["name"]} 已跳过")
|
||||
self._showTrace(f"任务组 {group["name"]} 已跳过", no_log=True)
|
||||
continue
|
||||
self._showTrace(f"正在运行任务组 {group["name"]}")
|
||||
self._showTrace(f"正在运行任务组 {group["name"]}", no_log=True)
|
||||
auto_lib.run(
|
||||
{ "users": group.get("users", []) }
|
||||
)
|
||||
except Exception as e:
|
||||
self._showTrace(f"AutoLibrary 运行时发生异常 : {e}")
|
||||
self._showTrace(
|
||||
f"AutoLibrary 运行时发生异常 : {e}",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
self.autoLibWorkerFinishedWithError.emit()
|
||||
return
|
||||
if auto_lib:
|
||||
@@ -154,7 +169,10 @@ class TimerTaskWorker(AutoLibWorker):
|
||||
self
|
||||
):
|
||||
|
||||
self._showTrace(f"定时任务 {self.__timer_task['name']} 运行时发生异常")
|
||||
self._showTrace(
|
||||
f"定时任务 {self.__timer_task['name']} 运行时发生异常",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
self.timerTaskWorkerIsFinished.emit(True, self.__timer_task)
|
||||
|
||||
@Slot()
|
||||
|
||||
@@ -54,7 +54,7 @@ class AutoLib(MsgBase):
|
||||
self
|
||||
) -> bool:
|
||||
|
||||
self._showTrace("正在初始化浏览器驱动......")
|
||||
self._showTrace("正在初始化浏览器驱动......", no_log=True)
|
||||
|
||||
web_driver_config = self.__run_config.get("web_driver", None)
|
||||
self.__driver_type = web_driver_config.get("driver_type")
|
||||
@@ -126,7 +126,7 @@ class AutoLib(MsgBase):
|
||||
service = ChromeService(executable_path=self.__driver_path)
|
||||
self.__driver = webdriver.Chrome(service=service, options=driver_options)
|
||||
case "firefox":
|
||||
self._showTrace(f"Firefox 浏览器驱动初始化略慢, 请耐心等待...")
|
||||
self._showTrace(f"Firefox 浏览器驱动初始化略慢, 请耐心等待...", no_log=True)
|
||||
service = FirefoxService(executable_path=self.__driver_path)
|
||||
self.__driver = webdriver.Firefox(service=service, options=driver_options)
|
||||
case _: # actually will not happen, beacuse we have checked it at the initlization
|
||||
@@ -245,8 +245,10 @@ class AutoLib(MsgBase):
|
||||
else:
|
||||
self._showTrace(f"用户 {username} 无法预约,已跳过")
|
||||
result = 2
|
||||
|
||||
# checkin
|
||||
if run_mode["auto_checkin"] and result != 1:
|
||||
last_result = result
|
||||
if run_mode["auto_checkin"] and last_result != 1:
|
||||
if self.__lib_checker.canCheckin():
|
||||
if self.__lib_checkin.checkin(username):
|
||||
result = 0
|
||||
@@ -255,8 +257,12 @@ class AutoLib(MsgBase):
|
||||
else:
|
||||
self._showTrace(f"用户 {username} 无法签到,已跳过")
|
||||
result = 2
|
||||
if last_result == 0: # partly success
|
||||
result = 0
|
||||
|
||||
# renewal
|
||||
if run_mode["auto_renewal"] and result != 1:
|
||||
last_result = result
|
||||
if run_mode["auto_renewal"] and last_result != 1:
|
||||
can_renew, record = self.__lib_checker.canRenew()
|
||||
if can_renew:
|
||||
if self.__lib_renew.renew(username, record, reserve_info):
|
||||
@@ -264,12 +270,18 @@ class AutoLib(MsgBase):
|
||||
self._showTrace(f"用户 {username} 续约成功 !")
|
||||
result = 0
|
||||
else:
|
||||
result = 1
|
||||
if result != 1: # partly success
|
||||
result = 0
|
||||
else:
|
||||
result = 1
|
||||
else:
|
||||
result = 1
|
||||
else:
|
||||
self._showTrace(f"用户 {username} 无法续约,已跳过")
|
||||
result = 2
|
||||
if last_result == 0: # partly success
|
||||
result = 0
|
||||
|
||||
# logout
|
||||
if not self.__lib_logout.logout(
|
||||
username
|
||||
@@ -294,7 +306,8 @@ class AutoLib(MsgBase):
|
||||
for user in users:
|
||||
user_counter["current"] += 1
|
||||
self._showTrace(
|
||||
f"正在处理第 {user_counter["current"]}/{len(users)} 个用户: {user["username"]}......"
|
||||
f"正在处理第 {user_counter["current"]}/{len(users)} 个用户: {user["username"]}......",
|
||||
no_log=True
|
||||
)
|
||||
if not user["enabled"]:
|
||||
self._showTrace(f"用户 {user["username"]} 已跳过")
|
||||
@@ -333,11 +346,14 @@ class AutoLib(MsgBase):
|
||||
|
||||
if self.__driver:
|
||||
if self.__driver_type.lower() == "firefox":
|
||||
self._showTrace(f"Firefox 浏览器驱动关闭略慢, 请耐心等待...")
|
||||
self._showTrace(
|
||||
f"Firefox 浏览器驱动关闭略慢, 请耐心等待...",
|
||||
no_log=True
|
||||
)
|
||||
self.__driver.quit()
|
||||
self.__driver = None
|
||||
self._showTrace(f"浏览器驱动已关闭")
|
||||
return True
|
||||
else:
|
||||
self._showTrace(f"浏览器驱动未初始化, 无需关闭")
|
||||
self._showTrace(f"浏览器驱动未初始化, 无需关闭", no_log=True)
|
||||
return False
|
||||
@@ -213,7 +213,7 @@ class LibChecker(LibOperator):
|
||||
if wanted_date is None:
|
||||
self._showTrace("日期未指定, 无法检查当前预约状态", self.TraceLevel.WARNING)
|
||||
return None
|
||||
self._showTrace(f"正在检查用户在 {wanted_date} 是否有预约状态为 {wanted_status} 的预约记录......")
|
||||
self._showTrace(f"正在检查用户在 {wanted_date} 是否有预约状态为 {wanted_status} 的预约记录......", no_log=True)
|
||||
|
||||
checked_count = 0
|
||||
max_check_times = 6 # we only check (4*(6-1)=)20 reservations, the last time cant be checked
|
||||
@@ -245,7 +245,8 @@ class LibChecker(LibOperator):
|
||||
self._showTrace(
|
||||
f"寻找到用户第 {checked_count} 条状态为 {wanted_status} 的预约记录, "
|
||||
f"详细信息: {record["date"]} "
|
||||
f"{record["time"]["begin"]} - {record["time"]["end"]} {record["info"]["location"]}"
|
||||
f"{record["time"]["begin"]} - {record["time"]["end"]} {record["info"]["location"]}",
|
||||
no_log=True
|
||||
)
|
||||
return record
|
||||
if not self.__showMoreReserveRecords():
|
||||
|
||||
@@ -107,7 +107,7 @@ class LibCheckin(LibOperator):
|
||||
result = self.__driver.execute_script(script)
|
||||
time.sleep(0.1)
|
||||
if result:
|
||||
self._showTrace("签到按钮已启用")
|
||||
self._showTrace("签到按钮已启用", no_log=True)
|
||||
else:
|
||||
self._showTrace("签到按钮启用失败", self.TraceLevel.WARNING)
|
||||
return result
|
||||
@@ -129,13 +129,13 @@ class LibCheckin(LibOperator):
|
||||
self._showTrace(f"用户 {username} 签到界面加载失败 !", self.TraceLevel.ERROR)
|
||||
return False
|
||||
if "disabled" in checkin_btn.get_attribute("class"):
|
||||
self._showTrace("签到按钮不可用, 可能不在场馆内, 正在尝试启用......")
|
||||
self._showTrace("签到按钮不可用, 可能不在场馆内, 正在尝试启用......", no_log=True)
|
||||
if not self.__enableCheckinBtn():
|
||||
self._showTrace(f"签到按钮启用失败 !", self.TraceLevel.ERROR)
|
||||
return False
|
||||
checkin_btn.click()
|
||||
if self._waitResponseLoad():
|
||||
self._showTrace(f"用户 {username} 签到成功 !")
|
||||
self._showTrace(f"用户 {username} 签到成功 !", no_log=True)
|
||||
return True
|
||||
else:
|
||||
self._showTrace(f"用户 {username} 签到失败 !", self.TraceLevel.ERROR)
|
||||
|
||||
@@ -91,7 +91,7 @@ class LibLogin(LibOperator):
|
||||
captcha_img = base64.b64decode(base64_str)
|
||||
captcha_text = self.__ddddocr.classification(captcha_img)
|
||||
captcha_text = ''.join(filter(str.isalnum, captcha_text)).lower()
|
||||
self._showTrace(f"识别到验证码为 : '{captcha_text}'")
|
||||
self._showTrace(f"识别到验证码为 : '{captcha_text}'", no_log=True)
|
||||
if len(captcha_text) != 4:
|
||||
self._showLog("识别到的验证码长度不等于 4 个字符 !", self.TraceLevel.WARNING)
|
||||
raise Exception("识别到的验证码长度不等于 4 个字符 !")
|
||||
@@ -109,7 +109,7 @@ class LibLogin(LibOperator):
|
||||
try:
|
||||
self._showMsg("请输入验证码:")
|
||||
captcha_text = self._waitMsg(timeout=15)
|
||||
self._showTrace(f"输入的验证码为 : '{captcha_text}'")
|
||||
self._showTrace(f"输入的验证码为 : '{captcha_text}'", no_log=True)
|
||||
if len(captcha_text) != 4:
|
||||
self._showLog("输入的验证码长度不等于 4 个字符 !", self.TraceLevel.WARNING)
|
||||
raise Exception("输入的验证码长度不等于 4 个字符 !")
|
||||
@@ -125,7 +125,7 @@ class LibLogin(LibOperator):
|
||||
|
||||
# refresh captcha
|
||||
try:
|
||||
self._showTrace("刷新验证码......")
|
||||
self._showTrace("刷新验证码......", no_log=True)
|
||||
self.__driver.find_element(
|
||||
By.ID, "loadImgId"
|
||||
).click()
|
||||
@@ -145,7 +145,7 @@ class LibLogin(LibOperator):
|
||||
if auto_captcha:
|
||||
captcha_text = self.__autoRecognizeCaptcha()
|
||||
else:
|
||||
self._showTrace(f"用户未配置自动识别验证码, 请手动输入验证码 !")
|
||||
self._showTrace(f"用户未配置自动识别验证码, 请手动输入验证码 !", no_log=True)
|
||||
captcha_text = self.__manualRecognizeCaptcha()
|
||||
if captcha_text:
|
||||
return captcha_text
|
||||
@@ -187,7 +187,7 @@ class LibLogin(LibOperator):
|
||||
return False
|
||||
# begin login process
|
||||
for attempt in range(max_attempts):
|
||||
self._showTrace(f"用户 {username} 第 {attempt + 1} 次尝试登录......")
|
||||
self._showTrace(f"用户 {username} 第 {attempt + 1} 次尝试登录......", no_log=True)
|
||||
if not self.__fillLogInElements(
|
||||
username,
|
||||
password,
|
||||
@@ -198,7 +198,7 @@ class LibLogin(LibOperator):
|
||||
continue
|
||||
if not self.__fillCaptchaElement(captcha_text):
|
||||
continue
|
||||
self._showTrace("尝试登录...")
|
||||
self._showTrace("尝试登录...", no_log=True)
|
||||
try:
|
||||
self.__driver.find_element(
|
||||
By.XPATH,
|
||||
|
||||
@@ -61,7 +61,7 @@ class LibRenew(LibTimeSelector):
|
||||
result_message = result_message.text.strip()
|
||||
self._showTrace(f"\n"\
|
||||
f" 续约失败 !\n"\
|
||||
f" {result_message}")
|
||||
f" {result_message}", no_log=True)
|
||||
return False
|
||||
try:
|
||||
WebDriverWait(self.__driver, 2).until(
|
||||
@@ -186,7 +186,8 @@ class LibRenew(LibTimeSelector):
|
||||
self._showTrace(f"用户 {username} 续约界面加载失败 !", self.TraceLevel.ERROR)
|
||||
return False
|
||||
if "disabled" in renew_btn.get_attribute("class"):
|
||||
self._showTrace(f"用户 {username} 续约按钮不可用, 可能不在场馆内, 请连接图书馆网络后重试")
|
||||
self._showLog(f"用户 {username} 续约按钮不可用, 可能不在场馆内")
|
||||
self._showTrace(f"用户 {username} 续约按钮不可用, 可能不在场馆内, 请连接图书馆网络后重试", no_log=True)
|
||||
return False
|
||||
renew_btn.click()
|
||||
if not self.__waitRenewDialog():
|
||||
|
||||
@@ -125,9 +125,14 @@ class LibReserve(LibTimeSelector):
|
||||
except ValueError as e:
|
||||
self._showTrace(
|
||||
f"预约信息错误 ! : {e}, "\
|
||||
f"由于缺少必要的预约信息, 无法开始预约流程, 请检查预约信息是否完整",
|
||||
f"由于缺少必要的预约信息, 无法开始预约流程",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
self._showTrace(
|
||||
f"预约信息错误 ! : {e}, "\
|
||||
f"由于缺少必要的预约信息, 无法开始预约流程, 请检查预约信息是否完整",
|
||||
no_log=True
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
@@ -481,7 +486,8 @@ class LibReserve(LibTimeSelector):
|
||||
seat_status = seat_link.get_attribute("title")
|
||||
self._showTrace(f"座位 {seat_id} 选择成功 ! : 当前状态 - '{seat_status}'")
|
||||
return True
|
||||
self._showTrace(f"座位 {seat_id} 在该楼层区域中不存在, 请检查座位号是否正确", self.TraceLevel.WARNING)
|
||||
self._showLog(f"座位 {seat_id} 在该楼层区域中不存在", self.TraceLevel.WARNING)
|
||||
self._showTrace(f"座位 {seat_id} 在该楼层区域中不存在, 请检查座位号是否正确", no_log=True)
|
||||
except:
|
||||
self._showTrace(f"座位选择失败 !", self.TraceLevel.ERROR)
|
||||
return False
|
||||
|
||||
@@ -18,15 +18,21 @@ from utils.LogManager import instance as logInstance
|
||||
def initializeConfigManager(
|
||||
) -> bool:
|
||||
|
||||
logger = logInstance().getLogger("AppInitializer")
|
||||
|
||||
app_dir = QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppDataLocation)
|
||||
old_config_dir = os.path.join(app_dir, "config")
|
||||
new_config_dir = os.path.join(app_dir, "configs")
|
||||
if QDir(old_config_dir).exists(): # old config dir exists
|
||||
#we rename it to compatible with new version
|
||||
logger.info("存在旧配置目录 %s,将其重命名为 %s", old_config_dir, new_config_dir)
|
||||
if not QDir().rename(old_config_dir, new_config_dir):
|
||||
logger.error("重命名旧配置目录 %s 到 %s 失败", old_config_dir, new_config_dir)
|
||||
return False
|
||||
elif not QDir(new_config_dir).exists():
|
||||
logger.info("初始化配置目录 %s", new_config_dir)
|
||||
if not QDir().mkpath(new_config_dir):
|
||||
logger.error("创建配置目录 %s 失败", new_config_dir)
|
||||
return False
|
||||
configInstance(new_config_dir)
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user