Add Live tab world chain map with hop geo arcs.

Plots YOU through each hop to EXIT on an equirectangular map with great-circle connectors, extends exit intel with lat/lon, and auto-refreshes on chain rotation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Indiana Holmes
2026-05-19 15:43:18 -07:00
parent 26863fc2a5
commit 23e4b0b019
4 changed files with 547 additions and 11 deletions

View File

@@ -344,5 +344,81 @@ class TestLeakAuditPure(unittest.TestCase):
self.assertEqual(len(rep.findings), 2)
class TestExitIntelGeo(unittest.TestCase):
def test_parse_ipapi_lat_lon(self) -> None:
from proxy_chain_manager.exit_intel import _parse_ipapi
out = _parse_ipapi(
{
"status": "success",
"query": "8.8.8.8",
"country": "United States",
"countryCode": "US",
"regionName": "Virginia",
"city": "Ashburn",
"lat": 39.03,
"lon": -77.5,
"timezone": "America/New_York",
"isp": "Google LLC",
"org": "Google Public DNS",
"as": "AS15169 Google LLC",
"mobile": False,
"proxy": False,
"hosting": True,
}
)
self.assertTrue(out.ok)
self.assertAlmostEqual(out.lat or 0, 39.03)
self.assertAlmostEqual(out.lon or 0, -77.5)
def test_parse_ipwhois_lat_lon(self) -> None:
from proxy_chain_manager.exit_intel import _parse_ipwhois
out = _parse_ipwhois(
{
"success": True,
"ip": "1.1.1.1",
"country": "Australia",
"country_code": "AU",
"city": "Sydney",
"region": "New South Wales",
"latitude": -33.86,
"longitude": 151.2,
"timezone": {"id": "Australia/Sydney"},
"connection": {"asn": 13335, "org": "Cloudflare", "isp": "Cloudflare"},
}
)
self.assertTrue(out.ok)
self.assertAlmostEqual(out.lat or 0, -33.86)
self.assertAlmostEqual(out.lon or 0, 151.2)
class TestChainMap(unittest.TestCase):
def test_extract_hop_host(self) -> None:
from proxy_chain_manager.chain_map import extract_hop_host
self.assertEqual(extract_hop_host("http://203.0.113.10:8080"), "203.0.113.10")
self.assertEqual(extract_hop_host("socks5://proxy.example:1080"), "proxy.example")
self.assertIsNone(extract_hop_host(""))
def test_project_corners(self) -> None:
from proxy_chain_manager.chain_map import _project
x, y = _project(0, 0, 360, 180, 0)
self.assertAlmostEqual(x, 180.0)
self.assertAlmostEqual(y, 90.0)
def test_render_chain_map_with_points(self) -> None:
from proxy_chain_manager.chain_map import MapPoint, render_chain_map
pts = [
MapPoint("you", "YOU", 40.0, -74.0, detail="NYC"),
MapPoint("hop", "H1", 51.5, -0.1, detail="London"),
MapPoint("exit", "EXIT", 35.6, 139.7, detail="Tokyo"),
]
img = render_chain_map(pts, width=640, height=200, status="healthy")
self.assertEqual(img.size, (640, 200))
if __name__ == "__main__":
unittest.main()