159 lines
8.3 KiB
Python
159 lines
8.3 KiB
Python
from pathlib import Path
|
|
import os
|
|
import shutil
|
|
|
|
methods = ''' def _refresh_wechat_database(
|
|
self, *, selected_account: str | None = None,
|
|
selected_conversation: str | None = None, query: str | None = None,
|
|
refresh_cache: bool = False, acquire_keys: bool = False,
|
|
) -> None:
|
|
"""Display local messages first; coalesce navigation while disk work runs."""
|
|
state = dict(getattr(self, "_wechat_db_state", {}) or {})
|
|
if selected_account is not None:
|
|
self._wechat_db_selected_account = str(selected_account or "").strip()
|
|
if selected_conversation is not None:
|
|
self._wechat_db_selected_conversation = str(selected_conversation or "").strip()
|
|
if query is not None:
|
|
self._wechat_db_query = str(query or "").strip()[:100]
|
|
if state.get("loading"):
|
|
# Repeated refresh clicks need no extra scan. Keep the latest actual
|
|
# navigation/search intent instead of silently dropping it.
|
|
if any(value is not None for value in (selected_account, selected_conversation, query)):
|
|
self._wechat_db_pending_request = {
|
|
"selected_account": self._wechat_db_selected_account,
|
|
"selected_conversation": self._wechat_db_selected_conversation,
|
|
"query": self._wechat_db_query,
|
|
}
|
|
return
|
|
auto_initialize = refresh_cache or not state.get("initializationAttempted")
|
|
if (selected_account is None and selected_conversation is None and query is None
|
|
and not refresh_cache and not acquire_keys and state.get("initializationAttempted")):
|
|
return
|
|
self._wechat_db_load_serial += 1
|
|
serial = self._wechat_db_load_serial
|
|
account = self._wechat_db_selected_account
|
|
conversation = self._wechat_db_selected_conversation
|
|
needle = self._wechat_db_query
|
|
state.update({
|
|
"loading": True,
|
|
"loadingMessage": "正在读取本机消息库;仅缺少可用密钥时进行初始化…" if auto_initialize or acquire_keys else "正在读取所选会话…",
|
|
"error": "", "query": needle,
|
|
"selectedAccount": account, "selectedConversation": conversation,
|
|
"patientContext": {},
|
|
})
|
|
self._wechat_db_state = state
|
|
self._schedule_console_push(urgent=True)
|
|
|
|
def load() -> None:
|
|
try:
|
|
from wxwork_message_browser import load_browser_snapshot
|
|
if acquire_keys:
|
|
from wxwork_local_setup import acquire_local_keys
|
|
acquire_local_keys()
|
|
result = load_browser_snapshot(
|
|
selected_account=account, selected_conversation=conversation,
|
|
query=needle, refresh_cache=refresh_cache,
|
|
auto_initialize=auto_initialize and not acquire_keys,
|
|
conversation_limit=8, message_limit=12,
|
|
)
|
|
result["initializationAttempted"] = True
|
|
if not auto_initialize and not acquire_keys and state.get("manualSetupRequired"):
|
|
result["manualSetupRequired"] = True
|
|
result["warning"] = result.get("warning") or state.get("warning") or state.get("error", "")
|
|
result["patientContext"] = {
|
|
"loading": True, "available": False, "reason": "正在加载患者关联…",
|
|
} if result.get("selectedAccount") and result.get("selectedConversation") else {}
|
|
except Exception as exc:
|
|
result = {**state, "loading": False, "initializationAttempted": True,
|
|
"manualSetupRequired": True, "error": f"读取微信消息库失败:{exc}"}
|
|
result["_serial"] = serial
|
|
try:
|
|
self.wechatDatabaseLoaded.emit(result)
|
|
except RuntimeError:
|
|
pass
|
|
threading.Thread(target=load, name="wechat-database-browser", daemon=True).start()
|
|
|
|
def _request_wechat_patient_context(self, serial: int, account: str, conversation: str) -> None:
|
|
"""At most one remote request plus the newest queued selection."""
|
|
request = (serial, account, conversation)
|
|
if getattr(self, "_wechat_patient_loading", False):
|
|
self._wechat_patient_pending = request
|
|
return
|
|
self._wechat_patient_loading = True
|
|
|
|
def load() -> None:
|
|
try:
|
|
import backend_client
|
|
context = dict(backend_client.desktop_patient_context(account, conversation))
|
|
context["loading"] = False
|
|
except Exception as exc:
|
|
context = {"loading": False, "available": False,
|
|
"error": f"患者关联读取失败:{exc}", "reason": "",
|
|
"people": [], "patient_bindings": []}
|
|
try:
|
|
self.wechatDatabaseLoaded.emit({
|
|
"_kind": "patientContext", "_serial": serial,
|
|
"selectedAccount": account, "selectedConversation": conversation,
|
|
"patientContext": context,
|
|
})
|
|
except RuntimeError:
|
|
pass
|
|
threading.Thread(target=load, name="wechat-patient-context", daemon=True).start()
|
|
|
|
@Slot(object)
|
|
def _wechat_database_loaded(self, result: object) -> None:
|
|
if not isinstance(result, dict):
|
|
return
|
|
result = dict(result)
|
|
serial = int(result.pop("_serial", 0) or 0)
|
|
if result.pop("_kind", "") == "patientContext":
|
|
self._wechat_patient_loading = False
|
|
current = dict(getattr(self, "_wechat_db_state", {}) or {})
|
|
if (serial == self._wechat_db_load_serial and not current.get("loading")
|
|
and result.get("selectedAccount") == current.get("selectedAccount")
|
|
and result.get("selectedConversation") == current.get("selectedConversation")):
|
|
current["patientContext"] = result.get("patientContext") or {}
|
|
self._wechat_db_state = current
|
|
self._schedule_console_push(urgent=True)
|
|
pending = getattr(self, "_wechat_patient_pending", None)
|
|
self._wechat_patient_pending = None
|
|
if pending and pending[0] == self._wechat_db_load_serial:
|
|
self._request_wechat_patient_context(*pending)
|
|
return
|
|
if serial != self._wechat_db_load_serial:
|
|
return
|
|
pending = getattr(self, "_wechat_db_pending_request", None)
|
|
self._wechat_db_pending_request = None
|
|
self._wechat_db_state = result
|
|
self._wechat_db_selected_account = str(result.get("selectedAccount") or "")
|
|
self._wechat_db_selected_conversation = str(result.get("selectedConversation") or "")
|
|
self._wechat_db_query = str(result.get("query") or "")
|
|
error = str(result.get("error") or "")
|
|
if error:
|
|
self.append_log(error, "warn")
|
|
self._push_console_state(force=True)
|
|
if isinstance(pending, dict):
|
|
self._refresh_wechat_database(**pending)
|
|
elif self._wechat_db_selected_account and self._wechat_db_selected_conversation and not error:
|
|
self._request_wechat_patient_context(
|
|
serial, self._wechat_db_selected_account, self._wechat_db_selected_conversation)
|
|
|
|
'''
|
|
|
|
for root in (Path(r'C:\kefu\wechat_rpa'), Path(r'C:\wechat_rpa')):
|
|
path = root / 'wechat_gui_qt.py'
|
|
backup = root / 'backups/loading-performance-20260917'
|
|
backup.mkdir(parents=True, exist_ok=True)
|
|
if (backup / path.name).exists():
|
|
raise RuntimeError('already backed up: ' + str(path))
|
|
shutil.copy2(path, backup / path.name)
|
|
text = path.read_text(encoding='utf-8')
|
|
start = text.index(' def _refresh_wechat_database(')
|
|
end = text.index(' def _console_select_task(', start)
|
|
text = text[:start] + methods + text[end:]
|
|
text = text.replace(' self._wechat_db_load_serial = 0\n', ' self._wechat_db_load_serial = 0\n self._wechat_db_pending_request = None\n self._wechat_patient_loading = False\n self._wechat_patient_pending = None\n', 1)
|
|
compile(text, str(path), 'exec')
|
|
temp = path.with_suffix('.performance-tmp')
|
|
temp.write_text(text, encoding='utf-8');os.replace(temp, path)
|
|
print(str(root) + ': local database result decoupled from remote patient context')
|