This commit is contained in:
Your Name
2026-07-31 18:34:44 +08:00
parent f22cc1a70d
commit 5ac803f7a6
197 changed files with 7570 additions and 329 deletions
+68 -4
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
"""企业微信 RPA 桌面控制台。"""
import glob
import json
import os
import queue
@@ -210,18 +211,70 @@ PAGES = (
class LogQueue:
"""把后台线程的标准输出转发到界面"""
"""把后台线程的标准输出转发到界面,同时留一份带时间戳的磁盘副本。
界面日志随窗口关闭就没了,出问题时无从回溯——真正卡住发送的那一行往往
几分钟前就被刷走了。落盘副本让事后还查得到。
"""
LOG_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "logs")
KEEP_FILES = 20
def __init__(self, target_queue):
self.target_queue = target_queue
self._handle = None
self._open_log_file()
def _open_log_file(self):
try:
os.makedirs(self.LOG_DIR, exist_ok=True)
self._prune_old_logs()
stamp = time.strftime("%Y%m%d_%H%M%S")
self._handle = open(
os.path.join(self.LOG_DIR, f"gui_{stamp}.log"),
"a",
encoding="utf-8",
buffering=1,
)
except Exception:
self._handle = None
def _prune_old_logs(self):
try:
files = sorted(
glob.glob(os.path.join(self.LOG_DIR, "gui_*.log")),
key=os.path.getmtime,
)
for path in files[: max(0, len(files) - self.KEEP_FILES + 1)]:
os.unlink(path)
except Exception:
pass
def write(self, message):
text = str(message).rstrip()
if text:
self.target_queue.put(("log", text))
if not text:
return
self.target_queue.put(("log", text))
if self._handle is not None:
try:
self._handle.write(f"{time.strftime('%H:%M:%S')} {text}\n")
except Exception:
self._handle = None
def flush(self):
pass
if self._handle is not None:
try:
self._handle.flush()
except Exception:
pass
def close(self):
if self._handle is not None:
try:
self._handle.close()
except Exception:
pass
self._handle = None
class BotThread(threading.Thread):
@@ -249,6 +302,14 @@ class BotThread(threading.Thread):
if bot is not None:
bot.message_batch_window_seconds = seconds
def _report_progress(self, text):
"""把机器人此刻在做什么送到界面上那行进度文字。"""
try:
self.target_queue.put(("progress", str(text or "")))
except Exception:
# 进度提示纯属好看,永远不该把轮询带下去
pass
def run(self):
bot = None
failed = False
@@ -264,6 +325,7 @@ class BotThread(threading.Thread):
bot._stop_check = self.stop_event
bot.safe_window_mode = True
bot.auto_activate_window = True
bot.progress_cb = self._report_progress
if not bot.connect(activate=False, wait_if_missing=True):
failed = True
@@ -3793,6 +3855,8 @@ class App(tk.Tk):
self._stop_button.set_enabled(False)
if sys.stdout is self._stdout_proxy:
sys.stdout = self._original_stdout
if self._stdout_proxy is not None:
self._stdout_proxy.close()
self._stdout_proxy = None
if final_state == "error":
self._set_status("error", "连接失败")