from __future__ import annotations import logging import time from typing import Any from yuxi.channels.models import ChatType logger = logging.getLogger(__name__) _CACHE_TTL_SUCCESS = 300 _CACHE_TTL_ERROR = 30 _room_kind_cache: dict[str, tuple[float, str | None]] = {} async def resolve_room_kind( client, api_base: str, token: str, api_user: str = "", api_password: str = "", ) -> dict[str, Any]: now = time.time() cached = _room_kind_cache.get(token) if cached: cached_ts, cached_kind = cached if cached_kind is not None and now - cached_ts < _CACHE_TTL_SUCCESS: return _kind_result(cached_kind) if cached_kind is None and now - cached_ts < _CACHE_TTL_ERROR: return _kind_result(None) try: path = f"{api_base}/room/{token}" result = await client.get(path) ocs = result.get("ocs", {}) data = ocs.get("data", {}) room_type = data.get("type") kind = _map_room_type(room_type) _room_kind_cache[token] = (now, kind) return _kind_result(kind) except Exception as e: logger.warning(f"[NextcloudTalk] Room type query failed for {token}: {e}") _room_kind_cache[token] = (now, None) return _kind_result(None) def _map_room_type(room_type: int | None) -> str | None: if room_type is None: return None if room_type in (1, 5, 6): return "direct" if room_type in (2, 3, 4): return "group" return None def _kind_result(kind: str | None) -> dict[str, Any]: if kind == "direct": return {"kind": "direct", "chat_type": ChatType.DIRECT} if kind == "group": return {"kind": "group", "chat_type": ChatType.GROUP} return {"kind": None, "chat_type": ChatType.GROUP, "source": "cache_fallback"} def invalidate_room_cache(token: str | None = None) -> None: if token: _room_kind_cache.pop(token, None) else: _room_kind_cache.clear()