from __future__ import annotations import logging import re logger = logging.getLogger(__name__) CHANNEL_PREFIX = "nextcloud-talk" _PURE_TOKEN_PATTERN = re.compile(r"^[a-z0-9]{20,64}$") def is_pure_token(target: str) -> bool: return bool(_PURE_TOKEN_PATTERN.match(target.strip())) def resolve_target_with_hint(target: str) -> tuple[str, dict[str, str]]: target = target.strip().lower() hints: dict[str, str] = {} if is_pure_token(target): hints["resolver_hint"] = "direct_token" return f"{CHANNEL_PREFIX}:{target}", hints if target.startswith("room:"): hints["resolver_hint"] = "room_token" elif target.startswith("user:"): hints["resolver_hint"] = "user_id" result = normalize_nc_target(target) return result, hints def normalize_nc_target(target: str) -> str: target = target.strip().lower() for prefix in ("nextcloud-talk:", "nextcloudtalk:", "nc-talk:", "nc:"): if target.startswith(prefix): target = target[len(prefix) :] break return f"{CHANNEL_PREFIX}:{target}" def strip_nc_prefix(target: str) -> str: target = target.strip().lower() for prefix in ("nextcloud-talk:", "nextcloudtalk:", "nc-talk:", "nc:"): if target.startswith(prefix): return target[len(prefix) :] return target def looks_like_nc_target(target_id: str) -> bool: target_id = target_id.strip().lower() prefixes = ("nextcloud-talk:", "nextcloudtalk:", "nc-talk:", "nc:") return any(target_id.startswith(p) for p in prefixes) def normalize_room_target(token: str) -> str: return f"{CHANNEL_PREFIX}:room:{token}" def normalize_user_target(user_id: str) -> str: return f"{CHANNEL_PREFIX}:{user_id}"