Release v1.0.66: table default_sort_json for data management
All checks were successful
技能自动化发布 / release (push) Successful in 10s

This commit is contained in:
2026-08-02 12:17:55 +08:00
parent 0002e86729
commit 46bc573777
17 changed files with 3565 additions and 8 deletions

View File

@@ -0,0 +1,192 @@
"""调用 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')}"
)