from __future__ import annotations import re from typing import Any from urllib.parse import urlencode from .settings import get_settings def normalize_room(value: str) -> str: cleaned = re.sub(r"[^a-z0-9-]+", "-", value.strip().lower()) return cleaned.strip("-")[:80] def normalize_lounge_channel(value: str) -> str: channel = value.strip() if not channel: return "" return channel if channel.startswith("#") else f"#{channel}" def create_mirotalk_room_slug(meetup: dict[str, Any]) -> str: date_part = re.sub(r"[^0-9]", "", str(meetup.get("date") or "")[:10]) time_part = re.sub(r"[^0-9]", "", str(meetup.get("time") or "")[:5]) city_part = normalize_room(str(meetup.get("city") or "online")) meetup_id = normalize_room(str(meetup.get("id") or "")) return normalize_room("-".join(part for part in ["nomadcna", city_part, date_part, time_part, meetup_id] if part)) def create_lounge_channel(meetup: dict[str, Any]) -> str: explicit = normalize_lounge_channel(str(meetup.get("loungeChannel") or "")) if explicit: return explicit room = normalize_room(str(meetup.get("mirotalkRoom") or "")) if room: return f"#{room}" return f"#{create_mirotalk_room_slug(meetup)}" def build_mirotalk_join_url(meetup: dict[str, Any], display_name: str = "NomadCNA") -> str: settings = get_settings() meeting_url = str(meetup.get("meetingUrl") or "").strip() if meeting_url.startswith(("http://", "https://")): return meeting_url room = normalize_room(str(meetup.get("mirotalkRoom") or "")) or create_mirotalk_room_slug(meetup) name = display_name.strip() or "NomadCNA" params = urlencode({"room": room, "name": name}) return f"{settings.mirotalk_url.rstrip('/')}/join?{params}" def build_lounge_chat_url(meetup: dict[str, Any]) -> str: settings = get_settings() channel = create_lounge_channel(meetup).lstrip("#") base = settings.lounge_url.rstrip("/") return f"{base}/#/chan-{channel}" def viewer_display_name(user: dict[str, Any] | None) -> str: if not user: return "NomadCNA" name = str(user.get("name") or "").strip() if name: return name email = str(user.get("email") or "").strip() return email.split("@")[0] if email else "NomadCNA" def is_host_user(user: dict[str, Any] | None) -> bool: if not user: return False role = str(user.get("role") or user.get("memberRole") or user.get("siteRole") or "").lower() return role in {"admin", "owner", "host", "organizer", "moderator"} def can_access_meetup(meetup: dict[str, Any], user: dict[str, Any] | None, *, vip: bool) -> bool: access = str(meetup.get("accessLevel") or "public").lower() if access == "public": return True if access == "members": return bool(user) if access == "vip": return bool(vip or user and user.get("vip")) if access == "hosts": return is_host_user(user) return False def access_lock_reason(meetup: dict[str, Any]) -> str: access = str(meetup.get("accessLevel") or "public").lower() if access == "members": return "login_required" if access == "vip": return "vip_required" if access == "hosts": return "host_required" return "no_access"