mirror of
https://github.com/Such-Software/adaptive-multi-protocol-browser.git
synced 2026-10-17 14:31:46 +02:00
Make managed i2pd startup easier on macOS
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
/.ampb/
|
||||
/docs/private/
|
||||
.DS_Store
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
@@ -395,7 +395,8 @@ def _start_i2p(
|
||||
0,
|
||||
state_dir,
|
||||
(),
|
||||
"I2P provider not found; install i2pd or set AMPB_I2PD_BIN or transports.i2p.binary_path",
|
||||
"I2P provider not found; on macOS run: brew install i2pd. "
|
||||
"Alternatively set AMPB_I2PD_BIN or transports.i2p.binary_path.",
|
||||
)
|
||||
|
||||
state_path = Path(state_dir)
|
||||
@@ -460,9 +461,37 @@ def _i2p_provider(config: AppConfig) -> I2PProvider | None:
|
||||
system_i2pd = shutil.which("i2pd")
|
||||
if system_i2pd:
|
||||
return I2PProvider("i2pd", system_i2pd)
|
||||
|
||||
homebrew_i2pd = _homebrew_i2pd_path()
|
||||
if homebrew_i2pd:
|
||||
return I2PProvider("i2pd", homebrew_i2pd)
|
||||
return None
|
||||
|
||||
|
||||
def _homebrew_i2pd_path() -> str:
|
||||
brew = shutil.which("brew")
|
||||
if not brew:
|
||||
return ""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[brew, "--prefix", "i2pd"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
text=True,
|
||||
timeout=2,
|
||||
check=False,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return ""
|
||||
if result.returncode != 0:
|
||||
return ""
|
||||
prefix = Path(result.stdout.strip())
|
||||
for candidate in (prefix / "bin/i2pd", prefix / "sbin/i2pd"):
|
||||
if candidate.exists() and candidate.is_file():
|
||||
return str(candidate)
|
||||
return ""
|
||||
|
||||
|
||||
def _i2p_command(provider: I2PProvider, *, endpoint: str, state_path: Path) -> tuple[str, ...]:
|
||||
host, port = _endpoint_host_port(endpoint)
|
||||
data_dir = state_path / "i2pd-data"
|
||||
@@ -482,8 +511,6 @@ def _i2p_command(provider: I2PProvider, *, endpoint: str, state_path: Path) -> t
|
||||
str(tunnels_path),
|
||||
"--datadir",
|
||||
str(data_dir),
|
||||
"--daemon=false",
|
||||
"--service=false",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -270,6 +270,42 @@ class TransportManagerTest(unittest.TestCase):
|
||||
self.assertEqual("missing-provider", result.status)
|
||||
self.assertFalse(result.ready)
|
||||
self.assertIn("I2P provider not found", result.message)
|
||||
self.assertIn("brew install i2pd", result.message)
|
||||
|
||||
def test_finds_homebrew_i2pd_provider_when_not_on_path(self) -> None:
|
||||
status = TransportStatus(
|
||||
transport="i2p",
|
||||
installed=True,
|
||||
running=False,
|
||||
endpoint="http://127.0.0.1:4444",
|
||||
adoptable=False,
|
||||
manage_supported=True,
|
||||
note="I2P HTTP proxy",
|
||||
)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
prefix = root / "homebrew/opt/i2pd"
|
||||
i2pd = prefix / "bin/i2pd"
|
||||
i2pd.parent.mkdir(parents=True)
|
||||
i2pd.write_text("#!/bin/sh\n", encoding="utf-8")
|
||||
|
||||
class Result:
|
||||
returncode = 0
|
||||
stdout = str(prefix) + "\n"
|
||||
|
||||
def which(name: str) -> str | None:
|
||||
return "/opt/homebrew/bin/brew" if name == "brew" else None
|
||||
|
||||
with patch("ampbrowser.transport_manager.shutil.which", side_effect=which):
|
||||
with patch("ampbrowser.transport_manager.subprocess.run", return_value=Result()):
|
||||
with patch("ampbrowser.transport_manager._wait_for_endpoint", return_value=True):
|
||||
with patch("ampbrowser.transport_manager.subprocess.Popen") as popen:
|
||||
popen.return_value.pid = 1234
|
||||
result = ensure_transport_ready("i2p", config=AppConfig(transport_modes={}), root=root, status=status)
|
||||
|
||||
self.assertEqual("started", result.status)
|
||||
self.assertEqual(str(i2pd), result.command[0])
|
||||
|
||||
def test_starts_configured_i2pd_provider_with_ampb_state(self) -> None:
|
||||
status = TransportStatus(
|
||||
@@ -300,12 +336,12 @@ class TransportManagerTest(unittest.TestCase):
|
||||
self.assertIn(str(root / ".ampb/transports/i2p/i2pd.conf"), result.command)
|
||||
self.assertIn("--datadir", result.command)
|
||||
self.assertIn(str(root / ".ampb/transports/i2p/i2pd-data"), result.command)
|
||||
self.assertIn("--daemon=false", result.command)
|
||||
self.assertIn("--service=false", result.command)
|
||||
config_text = (root / ".ampb/transports/i2p/i2pd.conf").read_text(encoding="utf-8")
|
||||
self.assertIn("[httpproxy]", config_text)
|
||||
self.assertIn("address = 127.0.0.1", config_text)
|
||||
self.assertIn("port = 4444", config_text)
|
||||
self.assertIn("daemon = false", config_text)
|
||||
self.assertIn("service = false", config_text)
|
||||
self.assertIn("notransit = true", config_text)
|
||||
state_path = root / ".ampb/transports/i2p/ampb-owned.json"
|
||||
self.assertTrue(state_path.exists())
|
||||
|
||||
Reference in New Issue
Block a user