Port meetups, discussions, gigs, dating/chat, VIP pay (ZPay/XorPay), MiroTalk live, digital academy, and ebook reader. Add persistent community_store, git-first deploy docs, and env template for production secrets. Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
"""Meetup live room URL builders — ported from NomadCNA."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import re
|
|
from urllib.parse import urlencode
|
|
|
|
MIROTALK_URL = os.getenv("MIROTALK_URL", "https://mirotalk.nomadro.com")
|
|
LOUNGE_URL = os.getenv("LOUNGE_URL", "https://lounge.nomadro.com")
|
|
|
|
VIP_ROLES = frozenset({"admin", "owner", "host", "organizer", "moderator"})
|
|
|
|
|
|
def normalize_room(value: str) -> str:
|
|
slug = re.sub(r"[^a-z0-9]+", "-", (value or "").lower()).strip("-")
|
|
return slug[:64] or "nomadro-live"
|
|
|
|
|
|
def create_mirotalk_room_slug(meetup: dict) -> str:
|
|
city = normalize_room(meetup.get("city") or "online")
|
|
date = (meetup.get("date") or "").replace("-", "")[:8]
|
|
time_part = (meetup.get("time") or "0000").replace(":", "")[:4]
|
|
mid = normalize_room(meetup.get("id") or "room")
|
|
return f"nomadro-{city}-{date}-{time_part}-{mid}"
|
|
|
|
|
|
def create_lounge_channel(meetup: dict) -> str:
|
|
if meetup.get("loungeChannel"):
|
|
ch = meetup["loungeChannel"].strip()
|
|
return ch if ch.startswith("#") else f"#{ch}"
|
|
if meetup.get("mirotalkRoom"):
|
|
return f"#{normalize_room(meetup['mirotalkRoom'])}"
|
|
return f"#{create_mirotalk_room_slug(meetup)}"
|
|
|
|
|
|
def build_mirotalk_join_url(meetup: dict, display_name: str = "nomadro") -> str:
|
|
explicit = (meetup.get("meetingUrl") or "").strip()
|
|
if explicit.startswith("http"):
|
|
return explicit
|
|
room = meetup.get("mirotalkRoom") or create_mirotalk_room_slug(meetup)
|
|
return f"{MIROTALK_URL.rstrip('/')}/join?{urlencode({'room': room, 'name': display_name})}"
|
|
|
|
|
|
def build_lounge_chat_url(meetup: dict) -> str:
|
|
channel = create_lounge_channel(meetup).lstrip("#")
|
|
return f"{LOUNGE_URL.rstrip('/')}/#/chan-{channel}"
|
|
|
|
|
|
def can_access_meetup(meetup: dict, user: dict | None, is_vip: bool = False) -> tuple[bool, str]:
|
|
level = meetup.get("access_level") or "public"
|
|
if level == "public":
|
|
return True, ""
|
|
if not user:
|
|
return False, "login_required"
|
|
if level == "members":
|
|
return True, ""
|
|
if level == "vip":
|
|
role = (user.get("role") or "").lower()
|
|
if is_vip or role in VIP_ROLES:
|
|
return True, ""
|
|
return False, "vip_required"
|
|
if level == "hosts":
|
|
role = (user.get("role") or "").lower()
|
|
if role in VIP_ROLES:
|
|
return True, ""
|
|
return False, "host_required"
|
|
return True, ""
|