"""调用 jiangchang_desktop_wake(只调不复制注入逻辑)。 - 主窗 WeWorkWindow → ``ensure_ui_ready("wecom")`` - 搜索浮层 SearchResultWindow2 → ``ensure_ui_ready("wecom_search")`` 未安装 kit 时降级为跳过,不阻断采集。 """ from __future__ import annotations import time from typing import Any, Optional _CACHE_TTL_SEC = 45.0 # profile -> cache _caches: dict[str, dict[str, Any]] = {} _PROFILE_WECOM = "wecom" _PROFILE_WECOM_SEARCH = "wecom_search" _THRESHOLDS = { _PROFILE_WECOM: 80, _PROFILE_WECOM_SEARCH: 20, } def resolve_wake_profile(*, class_name: str = "", title: str = "") -> Optional[str]: """返回应调用的 kit profile id;非企微相关则 None。""" cls = (class_name or "").strip() title = title or "" if cls == "SearchResultWindow2": return _PROFILE_WECOM_SEARCH if cls == "WeWorkWindow": return _PROFILE_WECOM if "WeWork" in cls and ("企业微信" in title or "WeCom" in title or "wecom" in title.lower()): return _PROFILE_WECOM return None def looks_like_wecom(*, class_name: str = "", title: str = "") -> bool: return resolve_wake_profile(class_name=class_name, title=title) is not None def kit_available() -> bool: try: from jiangchang_desktop_wake import ensure_ui_ready # noqa: F401 return True except ImportError: return False def auto_ensure_if_wecom( *, class_name: str = "", title: str = "", hwnd: Optional[int] = None, force: bool = False, findall_hint: Optional[int] = None, ) -> dict[str, Any]: """若目标像企微主窗/搜索浮层则静默 ensure;否则跳过。""" profile = resolve_wake_profile(class_name=class_name, title=title) if profile is None: return { "applicable": False, "skipped": True, "reason": "not_wecom", "available": kit_available(), } warm_min = int(_THRESHOLDS.get(profile, 80)) cache = _caches.setdefault( profile, {"t": 0.0, "warm": False, "hwnd": 0, "findall": 0} ) now = time.monotonic() hint = int(findall_hint) if findall_hint is not None else -1 if ( not force and cache.get("warm") and (now - float(cache.get("t") or 0.0)) < _CACHE_TTL_SEC and (hint < 0 or hint >= warm_min) ): return { "applicable": True, "available": True, "skipped": True, "reason": "cache_warm", "ok": True, "warm": True, "wake_applied": False, "findall": int(cache.get("findall") or 0), "hwnd": int(cache.get("hwnd") or 0), "profile": profile, } try: from jiangchang_desktop_wake import ensure_ui_ready from jiangchang_desktop_wake.errors import DesktopWakeError except ImportError: return { "applicable": True, "available": False, "skipped": True, "reason": "kit_not_installed", "ok": False, "profile": profile, "hint": "请安装 jiangchang-platform-kit>=1.2.6(含 wecom_search)后再采企微", } t0 = time.perf_counter() try: result = ensure_ui_ready( profile, hwnd=int(hwnd) if hwnd else None, raise_on_cold=True, ) except DesktopWakeError as exc: raw = (getattr(exc, "code", None) or "").strip() code = raw[6:] if raw.startswith("ERROR:") else (raw or "WAKE_FAILED") return { "applicable": True, "available": True, "skipped": False, "ok": False, "warm": False, "wake_applied": False, "error_code": code, "message": str(getattr(exc, "message", None) or exc), "elapsed_ms": int(round((time.perf_counter() - t0) * 1000)), "profile": profile, } except Exception as exc: return { "applicable": True, "available": True, "skipped": False, "ok": False, "warm": False, "error_code": "ENSURE_EXCEPTION", "message": f"{type(exc).__name__}: {exc}", "elapsed_ms": int(round((time.perf_counter() - t0) * 1000)), "profile": profile, } after = result.probe_after findall = int(after.findall_count) if after is not None else 0 report = { "applicable": True, "available": True, "skipped": False, "ok": bool(result.warm), "warm": bool(result.warm), "wake_applied": bool(result.wake_applied), "findall": findall, "hwnd": int(result.hwnd) if result.hwnd else 0, "elapsed_ms": int(round((time.perf_counter() - t0) * 1000)), "profile": profile, "markers_found": list(after.markers_found) if after is not None else [], } if result.warm: cache["t"] = now cache["warm"] = True cache["hwnd"] = report["hwnd"] cache["findall"] = findall else: cache["warm"] = False return report def format_kit_wake_line(report: Optional[dict[str, Any]]) -> str: if not report: return "kit_wake: (none)" if not report.get("applicable"): return "kit_wake: n/a (非企微)" if report.get("reason") == "kit_not_installed": return "kit_wake: 未安装 platform-kit(企微可能冷树)" prof = report.get("profile") or "?" if report.get("skipped") and report.get("reason") == "cache_warm": return ( f"kit_wake[{prof}]: cache warm=True findall={report.get('findall')} " f"hwnd={report.get('hwnd')}" ) if report.get("ok"): return ( f"kit_wake[{prof}]: warm={report.get('warm')} " f"wake_applied={report.get('wake_applied')} " f"findall={report.get('findall')} elapsed_ms={report.get('elapsed_ms')}" ) return ( f"kit_wake[{prof}]: FAILED code={report.get('error_code')} " f"msg={report.get('message')}" )