from __future__ import annotations import time from typing import Any from ... import windows_automation from ..context import WorkflowContext from ..registry import control_ports, field_def, register_node def _number(value: Any, default: float = 0) -> float: try: return float(value) except (TypeError, ValueError): return default def _boolean(value: Any, default: bool = False) -> bool: if value in (None, ""): return default if isinstance(value, str): return value.strip().lower() in {"1", "true", "yes", "y", "on"} return bool(value) def ensure_browser_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]: params = node.get("params", {}) browser = str(inputs.get("browser", params.get("browser")) or "edge") url = str(inputs.get("url", params.get("url")) or "").strip() maximize = _boolean(inputs.get("maximize", params.get("maximize")), True) wait_seconds = max(0, min(_number(inputs.get("wait_seconds", params.get("wait_seconds")), 2), 30)) if url: opened = windows_automation.open_url(url=url, browser=browser, new_window=bool(params.get("new_window", True))) elif browser.lower() in {"edge", "msedge"}: opened = windows_automation.start_program("cmd.exe /c start msedge", shell=True) else: opened = windows_automation.start_program("cmd.exe /c start chrome", shell=True) context.remember_pid(opened.get("pid")) if wait_seconds: time.sleep(wait_seconds) if maximize: windows_automation.keyboard_action("hotkey", keys=["win", "up"]) return {"action": "ensure_browser", "browser": browser, "url": url, "opened": opened, "maximized": maximize} def browser_key_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]: params = node.get("params", {}) action = str(inputs.get("action", params.get("action")) or "fullscreen") if action == "fullscreen": result = windows_automation.keyboard_action("press", key="f11") elif action == "back": result = windows_automation.keyboard_action("hotkey", keys=["alt", "left"]) elif action == "forward": result = windows_automation.keyboard_action("hotkey", keys=["alt", "right"]) elif action == "refresh": result = windows_automation.keyboard_action("press", key="f5") elif action == "escape": result = windows_automation.keyboard_action("press", key="escape") elif action == "close_tab": result = windows_automation.keyboard_action("hotkey", keys=["ctrl", "w"]) elif action == "close_window": result = windows_automation.keyboard_action("hotkey", keys=["alt", "f4"]) else: result = {"action": "browser_noop", "key": None} return {"action": action, "keyboard": result} register_node( { "type": "browser.ensure_foreground", "category": "browser", "label": "确保浏览器前台", "description": "打开或唤起浏览器,可选打开指定网址,并尝试最大化窗口。", "params": { "url": field_def("text", "网址", "", description="为空时仅尝试启动浏览器。"), "browser": field_def("select", "浏览器", "edge", options=["default", "edge"]), "new_window": field_def("boolean", "新窗口", True), "maximize": field_def("boolean", "最大化", True), "wait_seconds": field_def("number", "等待秒数", 2, minimum=0, maximum=30), }, "inputs": { "url": field_def("string", "网址"), "browser": field_def("string", "浏览器"), "maximize": field_def("boolean", "最大化"), "wait_seconds": field_def("number", "等待秒数"), }, "outputs": { "action": {"type": "string", "label": "动作"}, "browser": {"type": "string", "label": "浏览器"}, "url": {"type": "string", "label": "网址"}, "opened": {"type": "object", "label": "启动结果"}, "maximized": {"type": "boolean", "label": "是否最大化"}, }, "control_ports": control_ports(), }, ensure_browser_node, ) register_node( { "type": "browser.control", "category": "browser", "label": "浏览器快捷控制", "description": "对当前浏览器窗口执行全屏、返回、刷新、关闭标签页等快捷操作。", "params": { "action": field_def( "select", "动作", "fullscreen", options=["fullscreen", "back", "forward", "refresh", "escape", "close_tab", "close_window"], ), }, "inputs": {"action": field_def("string", "动作")}, "outputs": { "action": {"type": "string", "label": "动作"}, "keyboard": {"type": "object", "label": "键盘结果"}, }, "control_ports": control_ports(), }, browser_key_node, )