make it easyer to connect to a remove browser allow it with --browser ip alias too
Testing / test (push) Failing after 13m59s
Testing / test (push) Failing after 13m59s
This commit is contained in:
+68
-22
@@ -93,29 +93,47 @@ def _remote_display_name(endpoint: str, profile_name: str, display_name: str) ->
|
||||
return f"{remote_name}:{display_name or profile_name}"
|
||||
|
||||
|
||||
def remote_browser_targets(endpoint: str, token: str | None = None) -> list[BrowserTarget]:
|
||||
"""Return browser targets advertised by a single remote endpoint."""
|
||||
remote_targets = send_command("browser-cli.targets", remote=endpoint, token=token)
|
||||
targets: list[BrowserTarget] = []
|
||||
for item in remote_targets or []:
|
||||
profile = str(item.get("profile") or "default")
|
||||
display = str(item.get("displayName") or profile)
|
||||
targets.append(
|
||||
BrowserTarget(
|
||||
profile=profile,
|
||||
display_name=_remote_display_name(endpoint, profile, display),
|
||||
socket_path="",
|
||||
remote=endpoint,
|
||||
token=token,
|
||||
)
|
||||
)
|
||||
return targets
|
||||
|
||||
|
||||
def _remote_browser_targets() -> list[BrowserTarget]:
|
||||
targets: list[BrowserTarget] = []
|
||||
for endpoint, cfg in _load_remotes().items():
|
||||
token = str(cfg.get("token") or "") or None
|
||||
try:
|
||||
remote_targets = send_command("browser-cli.targets", remote=endpoint, token=token)
|
||||
targets.extend(remote_browser_targets(endpoint, token))
|
||||
except (BrowserNotConnected, RuntimeError):
|
||||
continue
|
||||
for item in remote_targets or []:
|
||||
profile = str(item.get("profile") or "default")
|
||||
display = str(item.get("displayName") or profile)
|
||||
targets.append(
|
||||
BrowserTarget(
|
||||
profile=profile,
|
||||
display_name=_remote_display_name(endpoint, profile, display),
|
||||
socket_path="",
|
||||
remote=endpoint,
|
||||
token=token,
|
||||
)
|
||||
)
|
||||
return targets
|
||||
|
||||
|
||||
def remote_target_for_alias(alias: str | None) -> BrowserTarget | None:
|
||||
"""Resolve a user-facing remote alias such as 'host:profile' to a target."""
|
||||
if not alias:
|
||||
return None
|
||||
for target in _remote_browser_targets():
|
||||
endpoint_profile = f"{target.remote}:{target.profile}" if target.remote else None
|
||||
if alias in {target.display_name, endpoint_profile}:
|
||||
return target
|
||||
return None
|
||||
|
||||
|
||||
def active_browser_targets(*, include_remotes: bool = True) -> list[BrowserTarget]:
|
||||
targets: list[BrowserTarget] = []
|
||||
if REGISTRY_PATH.exists():
|
||||
@@ -164,10 +182,42 @@ def _resolve_socket(profile: str | None = None) -> str:
|
||||
)
|
||||
|
||||
|
||||
def _send_remote(endpoint: str, framed: bytes) -> bytes:
|
||||
host, _, port_str = endpoint.rpartition(":")
|
||||
if not host or not port_str:
|
||||
raise BrowserNotConnected(f"Invalid remote endpoint '{endpoint}': expected host:port")
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.connect((host, int(port_str)))
|
||||
sock.sendall(framed)
|
||||
return _recv_all(sock)
|
||||
|
||||
|
||||
def _auto_route_remote(endpoint: str, token: str | None) -> str | None:
|
||||
targets = remote_browser_targets(endpoint, token)
|
||||
if len(targets) == 1:
|
||||
return targets[0].profile
|
||||
if len(targets) > 1:
|
||||
aliases = [target.profile for target in targets]
|
||||
examples = "\n".join(f" browser-cli --remote {endpoint} --browser {a} ..." for a in aliases)
|
||||
raise BrowserNotConnected(
|
||||
f"Multiple remote browser instances are active: {', '.join(aliases)}\n"
|
||||
f"Use --browser <alias> to select one:\n{examples}"
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def send_command(command: str, args: dict | None = None, profile: str | None = None, remote: str | None = None, token: str | None = None) -> Any:
|
||||
"""Send a command to the browser and return the response data."""
|
||||
requested_profile = profile or os.environ.get("BROWSER_CLI_PROFILE")
|
||||
remote_endpoint = remote or os.environ.get("BROWSER_CLI_REMOTE")
|
||||
resolved_token = token or os.environ.get("BROWSER_CLI_TOKEN") or token_for_remote(remote_endpoint)
|
||||
remote_alias_target = None
|
||||
if not remote_endpoint and requested_profile:
|
||||
remote_alias_target = remote_target_for_alias(requested_profile)
|
||||
if remote_alias_target:
|
||||
remote_endpoint = remote_alias_target.remote
|
||||
requested_profile = remote_alias_target.profile
|
||||
|
||||
resolved_token = token or os.environ.get("BROWSER_CLI_TOKEN") or (remote_alias_target.token if remote_alias_target else None) or token_for_remote(remote_endpoint)
|
||||
msg = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"command": command,
|
||||
@@ -176,7 +226,9 @@ def send_command(command: str, args: dict | None = None, profile: str | None = N
|
||||
if remote_endpoint:
|
||||
if resolved_token:
|
||||
msg["token"] = resolved_token
|
||||
route_profile = profile or os.environ.get("BROWSER_CLI_PROFILE")
|
||||
route_profile = requested_profile
|
||||
if not route_profile and command != "browser-cli.targets":
|
||||
route_profile = _auto_route_remote(remote_endpoint, resolved_token)
|
||||
if route_profile:
|
||||
msg["_route"] = route_profile
|
||||
payload = json.dumps(msg).encode("utf-8")
|
||||
@@ -184,13 +236,7 @@ def send_command(command: str, args: dict | None = None, profile: str | None = N
|
||||
|
||||
try:
|
||||
if remote_endpoint:
|
||||
host, _, port_str = remote_endpoint.rpartition(":")
|
||||
if not host or not port_str:
|
||||
raise BrowserNotConnected(f"Invalid remote endpoint '{remote_endpoint}': expected host:port")
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.connect((host, int(port_str)))
|
||||
sock.sendall(framed)
|
||||
response = _recv_all(sock)
|
||||
response = _send_remote(remote_endpoint, framed)
|
||||
elif is_windows():
|
||||
sock_path = _resolve_socket(profile)
|
||||
with PipeClient(sock_path, family="AF_PIPE") as conn:
|
||||
|
||||
Reference in New Issue
Block a user