from __future__ import annotations from typing import TYPE_CHECKING from yuxi.utils.logging_config import logger if TYPE_CHECKING: from nio import AsyncClient _DIRECT_ROOM_TYPE = "m.direct" async def inspect_direct_room( client: AsyncClient, room_id: str, ) -> dict: try: members_resp = await client.joined_members(room_id) members = getattr(members_resp, "members", []) name_resp = await client.room_get_state_event(room_id, "m.room.name") name = getattr(name_resp, "name", "") if name_resp else "" join_rules = await client.room_get_state_event(room_id, "m.room.join_rules") rule = getattr(join_rules, "join_rule", "") if join_rules else "" return { "room_id": room_id, "name": name, "member_count": len(members), "join_rule": rule, "is_direct": _is_direct_room(client, room_id), } except Exception as e: logger.debug(f"Matrix direct room inspect failed for {room_id}: {e}") return {"room_id": room_id, "error": str(e)} async def repair_direct_room( client: AsyncClient, room_id: str, target_user_id: str, ) -> dict: try: await client.room_set_account_data( room_id=room_id, event_type="m.direct", content={"room_id": room_id, "user_id": target_user_id}, ) return { "status": "repaired", "room_id": room_id, "user_id": target_user_id, "action": "set_account_data_m.direct", } except Exception as e: logger.error(f"Matrix direct room repair failed for {room_id}: {e}") return {"status": "error", "room_id": room_id, "error": str(e)} async def promote_room_to_direct( client: AsyncClient, room_id: str, user_id: str, ) -> dict: try: direct_rooms = await client.get_account_data(_DIRECT_ROOM_TYPE) current = getattr(direct_rooms, "content", {}) if direct_rooms else {} current.setdefault(user_id, []) if room_id not in current[user_id]: current[user_id].append(room_id) await client.set_account_data(_DIRECT_ROOM_TYPE, current) return { "status": "promoted", "room_id": room_id, "user_id": user_id, } except Exception as e: logger.error(f"Matrix promote to direct room failed: {e}") return {"status": "error", "error": str(e)} async def demote_direct_room( client: AsyncClient, room_id: str, user_id: str, ) -> dict: try: direct_rooms = await client.get_account_data(_DIRECT_ROOM_TYPE) current = getattr(direct_rooms, "content", {}) if direct_rooms else {} if user_id in current and room_id in current[user_id]: current[user_id].remove(room_id) if not current[user_id]: del current[user_id] await client.set_account_data(_DIRECT_ROOM_TYPE, current) return {"status": "demoted", "room_id": room_id, "user_id": user_id} except Exception as e: logger.error(f"Matrix demote direct room failed: {e}") return {"status": "error", "error": str(e)} def _is_direct_room(client: AsyncClient, room_id: str) -> bool: try: account_data = client.account_data if client else {} if account_data: direct_data = account_data.get("m.direct", {}) if isinstance(direct_data, dict): for room_ids in direct_data.values(): if isinstance(room_ids, list) and room_id in room_ids: return True except Exception: pass return False