from __future__ import annotations from typing import Any from yuxi.utils.logging_config import logger class InviteManager: def __init__( self, auto_accept_groups: bool = False, group_invite_allowlist: list[str] | None = None, auto_accept_dm: bool = False, dm_allowlist: list[str] | None = None, ): self.auto_accept_groups = auto_accept_groups self.group_invite_allowlist = [s.lstrip("~").lower() for s in (group_invite_allowlist or [])] self.auto_accept_dm = auto_accept_dm self.dm_allowlist = [s.lstrip("~").lower() for s in (dm_allowlist or [])] self._pending_invites: dict[str, dict[str, Any]] = {} def should_auto_accept_group_invite(self, inviter_ship: str) -> bool: if not self.auto_accept_groups: return False ship = inviter_ship.lstrip("~").lower() if not self.group_invite_allowlist: return False return ship in self.group_invite_allowlist def should_auto_accept_dm(self, inviter_ship: str) -> bool: if not self.auto_accept_dm: return False ship = inviter_ship.lstrip("~").lower() if not self.dm_allowlist: return False return ship in self.dm_allowlist async def handle_foreign_update(self, foreign_update: dict[str, Any]) -> dict[str, Any] | None: group = foreign_update.get("group", "") ship = foreign_update.get("ship", "").lstrip("~") join = foreign_update.get("join", False) if not group or not ship: return None invite_id = f"{group}:{ship}" if join: self._pending_invites[invite_id] = foreign_update if self.should_auto_accept_group_invite(ship): logger.info(f"[Urbit] Auto-accepting group invite from ~{ship} for {group}") await self._accept_invite(group, ship) self._pending_invites.pop(invite_id, None) return {"action": "auto_accepted", "group": group, "ship": ship} logger.info(f"[Urbit] Group invite pending: {group} from ~{ship}") return {"action": "pending", "group": group, "ship": ship, "invite_id": invite_id} if not join and invite_id in self._pending_invites: self._pending_invites.pop(invite_id, None) logger.info(f"[Urbit] Ship ~{ship} left {group}, invite resolved") return {"action": "left", "group": group, "ship": ship} async def _accept_invite(self, group: str, inviter: str) -> None: logger.info(f"[Urbit] Would accept group invite: {group} from ~{inviter}") def get_pending_invites(self) -> list[dict[str, Any]]: return list(self._pending_invites.values())