69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, TYPE_CHECKING
|
|
|
|
from yuxi.utils.logging_config import logger
|
|
|
|
if TYPE_CHECKING:
|
|
from .client import UrbitClient
|
|
|
|
|
|
class DirectoryQuery:
|
|
def __init__(self, client: UrbitClient):
|
|
self._client = client
|
|
|
|
async def list_contacts(self) -> list[dict[str, Any]]:
|
|
from .scry import scry_contacts
|
|
|
|
try:
|
|
data = await scry_contacts(self._client)
|
|
if not data or not isinstance(data, dict):
|
|
return []
|
|
|
|
contacts: list[dict[str, Any]] = []
|
|
for ship, info in data.items():
|
|
if isinstance(info, dict):
|
|
contacts.append(
|
|
{
|
|
"ship": f"~{ship.lstrip('~')}",
|
|
"nickname": info.get("nickname", ""),
|
|
"bio": info.get("bio", ""),
|
|
"status": info.get("status", ""),
|
|
"avatar": info.get("avatar", ""),
|
|
"color": info.get("color", ""),
|
|
}
|
|
)
|
|
|
|
logger.info(f"[Urbit] Directory: found {len(contacts)} contacts")
|
|
return contacts
|
|
|
|
except Exception as e:
|
|
logger.warning(f"[Urbit] Directory query failed: {e}")
|
|
return []
|
|
|
|
async def list_peers(self) -> list[str]:
|
|
try:
|
|
r = await self._client.get("/~/peers", timeout=10.0)
|
|
if r.status_code != 200:
|
|
logger.warning(f"[Urbit] Directory: /~/peers returned {r.status_code}")
|
|
return []
|
|
data = r.json()
|
|
peers = []
|
|
for peer_key in data:
|
|
if isinstance(peer_key, str):
|
|
peers.append(f"~{peer_key.lstrip('~')}")
|
|
logger.info(f"[Urbit] Directory: found {len(peers)} peers")
|
|
return peers
|
|
except Exception as e:
|
|
logger.warning(f"[Urbit] Directory peers query failed: {e}")
|
|
return []
|
|
|
|
async def search_contact(self, query: str) -> list[dict[str, Any]]:
|
|
contacts = await self.list_contacts()
|
|
query_lower = query.lower()
|
|
return [
|
|
c
|
|
for c in contacts
|
|
if query_lower in c.get("ship", "").lower() or query_lower in c.get("nickname", "").lower()
|
|
]
|