Files
adaptive-multi-protocol-bro…/ampbrowser/transports.py
T
2026-07-05 20:14:46 -04:00

97 lines
2.4 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
import shutil
import socket
@dataclass(frozen=True)
class TransportStatus:
transport: str
installed: bool
running: bool
endpoint: str
adoptable: bool
manage_supported: bool
note: str
TRANSPORTS = ("tor", "i2p", "reticulum", "gemini")
def inspect_transports() -> list[TransportStatus]:
return [
_inspect_tor(),
_inspect_i2p(),
_inspect_reticulum(),
_inspect_gemini(),
]
def inspect_transport(name: str) -> TransportStatus | None:
for status in inspect_transports():
if status.transport == name:
return status
return None
def _inspect_tor() -> TransportStatus:
installed = shutil.which("tor") is not None
running = _can_connect("127.0.0.1", 9050)
return TransportStatus(
transport="tor",
installed=installed,
running=running,
endpoint="socks5://127.0.0.1:9050",
adoptable=running,
manage_supported=True,
note="Tor SOCKS proxy",
)
def _inspect_i2p() -> TransportStatus:
installed = shutil.which("i2pd") is not None or shutil.which("i2prouter") is not None
running = _can_connect("127.0.0.1", 4444)
return TransportStatus(
transport="i2p",
installed=installed,
running=running,
endpoint="http://127.0.0.1:4444",
adoptable=running,
manage_supported=True,
note="I2P HTTP proxy",
)
def _inspect_reticulum() -> TransportStatus:
installed = any(shutil.which(command) for command in ("rnsd", "rnstatus", "rnodeconf"))
return TransportStatus(
transport="reticulum",
installed=installed,
running=False,
endpoint="rns://local",
adoptable=False,
manage_supported=False,
note="Reticulum adapter is planned; interface readiness needs explicit config",
)
def _inspect_gemini() -> TransportStatus:
return TransportStatus(
transport="gemini",
installed=True,
running=True,
endpoint="builtin://gemtext-renderer",
adoptable=True,
manage_supported=True,
note="Built-in Gemtext fetch/render path",
)
def _can_connect(host: str, port: int) -> bool:
try:
with socket.create_connection((host, port), timeout=0.2):
return True
except OSError:
return False