This commit is contained in:
2026-01-14 14:32:46 -08:00
parent 187a230e98
commit 7def5c4464
2 changed files with 101 additions and 82 deletions

View File

@@ -736,7 +736,7 @@ class ConfigModal(ModalScreen):
# 1. Choose Network
joined = zt.list_networks()
if not joined:
self.notify("Error: Join a ZeroTier network first in 'Networking'", severity="error")
self.notify("Error: Join a ZeroTier network first in 'Connectors'", severity="error")
return
net_options = [f"{n.name or 'Network'} ({n.id})" for n in joined]
@@ -786,87 +786,60 @@ class ConfigModal(ModalScreen):
self.app.push_screen(SelectionModal("Select Local Store to Share", local_stores), callback=on_share_selected)
else:
# 3b. Connect to Remote Peer
# Discover Peers (Port 999 only)
central_token = self.config_data.get("networking", {}).get("zerotier", {}).get("api_key")
self.notify(f"Scanning Network {net_id} for peers...")
try:
probes = zt.discover_services_on_network(net_id, ports=[999], api_token=central_token)
except Exception as e:
self.notify(f"Discovery error: {e}", severity="error")
return
# 3b. Connect to Remote Peer - Background Discovery
@work
async def run_discovery():
self.notify(f"Discovery: Scanning {net_id} for peers...", timeout=5)
central_token = self.config_data.get("networking", {}).get("zerotier", {}).get("api_key")
try:
import asyncio
from functools import partial
loop = asyncio.get_event_loop()
probes = await loop.run_in_executor(None, partial(
zt.discover_services_on_network, net_id, ports=[999, 45869], api_token=central_token
))
except Exception as e:
self.notify(f"Discovery error: {e}", severity="error")
return
if not probes:
self.notify("No peers found on port 999. Use manual setup.", severity="warning")
# Create empty template
new_name = f"zt_remote"
if not probes:
self.notify("No peers found. Check firewall or server status.", severity="warning")
return
peer_options = []
for p in probes:
label = "Remote"
if isinstance(p.payload, dict):
label = p.payload.get("name") or p.payload.get("peer_id") or label
status = " [Locked]" if p.status_code == 401 else ""
peer_options.append(f"{p.address} ({label}){status}")
def on_peer_selected(choice: str):
if not choice: return
addr = choice.split(" ")[0]
match = next((p for p in probes if p.address == addr), None)
if match:
save_connected_store(match)
self.app.push_screen(SelectionModal("Select Peer to Connect", peer_options), callback=on_peer_selected)
def save_connected_store(p: zt.ZeroTierServiceProbe):
new_name = f"zt_{p.address.replace('.', '_')}"
if "store" not in self.config_data: self.config_data["store"] = {}
store_cfg = self.config_data["store"].setdefault("zerotier", {})
store_cfg[new_name] = {
"NAME": new_name,
"NETWORK_ID": net_id,
"HOST": "",
"PORT": "999",
"SERVICE": "remote"
"HOST": p.address,
"PORT": str(p.port),
"SERVICE": p.service_hint or "remote"
}
try:
self.save_all()
self.notify("ZeroTier manual template created.")
except Exception as e:
self.notify(f"Auto-save failed: {e}", severity="error")
self.editing_item_type = "store-zerotier"
self.editing_item_name = new_name
self.save_all()
self.notify(f"Connected to {p.address}")
self.refresh_view()
return
peer_options = []
for p in probes:
peer_name = "Unnamed Peer"
if isinstance(p.payload, dict):
peer_name = p.payload.get("name") or p.payload.get("NAME") or peer_name
status_label = ""
if p.status_code == 401:
status_label = " [Locked/401]"
peer_options.append(f"{p.address} ({peer_name}){status_label}")
def on_peer_selected(peer_choice: str):
if not peer_choice: return
p_addr = peer_choice.split(" ")[0]
match = next((p for p in probes if p.address == p_addr), None)
new_name = f"zt_{p_addr.replace('.', '_')}"
if "store" not in self.config_data: self.config_data["store"] = {}
store_cfg = self.config_data["store"].setdefault("zerotier", {})
new_config = {
"NAME": new_name,
"NETWORK_ID": net_id,
"HOST": p_addr,
"PORT": "999",
"SERVICE": "remote"
}
if match:
if match.service_hint == "hydrus":
new_config["SERVICE"] = "hydrus"
new_config["PORT"] = "45869"
if match.status_code == 401:
self.notify("This peer requires an API Key. Please enter it in the settings panel.", severity="warning")
store_cfg[new_name] = new_config
try:
self.save_all()
self.notify(f"ZeroTier auto-saved: Store '{new_name}' added.")
except Exception as e:
self.notify(f"Auto-save failed: {e}", severity="error")
self.editing_item_type = "store-zerotier"
self.editing_item_name = new_name
self.refresh_view()
run_discovery()
self.app.push_screen(SelectionModal("Select Remote Peer", peer_options), callback=on_peer_selected)