From 7c5ed78952839be0958f1b2156569a0c45bde48b Mon Sep 17 00:00:00 2001 From: rakshitjain23 Date: Wed, 17 Dec 2025 13:24:36 +0530 Subject: [PATCH 1/3] fix: QR code URL generation and WebSocket robustness - Fix: Ensure defaults to if not explicitly set, fixing incorrect QR codes (localhost). - Fix: Determine dynamically from environment variables in production. - Refactor: Add in to prevent WebSocket consumer crashes when the video server is unconfigured (common in dev/partial deployments). --- app/eventyay/config/next_settings.py | 10 ++++- app/eventyay/features/live/modules/bbb.py | 45 +++++++++++++++-------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/app/eventyay/config/next_settings.py b/app/eventyay/config/next_settings.py index 0516959878..158b5db86f 100644 --- a/app/eventyay/config/next_settings.py +++ b/app/eventyay/config/next_settings.py @@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _ from kombu import Queue from pycountry import currencies -from pydantic import Field, HttpUrl +from pydantic import Field, HttpUrl, model_validator from pydantic_settings import BaseSettings as _BaseSettings from pydantic_settings import PydanticBaseSettingsSource, SettingsConfigDict, TomlConfigSettingsSource from redis.asyncio.retry import Retry @@ -128,7 +128,7 @@ class BaseSettings(_BaseSettings): # Override it to match the domain the website is running on, # or you will get "DisallowedHost" error. site_url: HttpUrl = 'http://localhost:8000' - short_url: HttpUrl = 'http://localhost:8000' + short_url: HttpUrl | None = None talk_hostname: str = 'http://localhost:8000' sentry_dsn: str = '' instance_name: str = 'eventyay' @@ -146,6 +146,12 @@ class BaseSettings(_BaseSettings): zoom_key: str = '' zoom_secret: str = '' control_secret: str = '' + + @model_validator(mode='after') + def default_short_url(self) -> 'BaseSettings': + if self.short_url is None: + self.short_url = self.site_url + return self statsd_host: str = '' statsd_port: int = 8125 statsd_prefix: str = 'eventyay' diff --git a/app/eventyay/features/live/modules/bbb.py b/app/eventyay/features/live/modules/bbb.py index 6cc353538e..5474b1f1cc 100644 --- a/app/eventyay/features/live/modules/bbb.py +++ b/app/eventyay/features/live/modules/bbb.py @@ -1,3 +1,4 @@ +from django.db.utils import IntegrityError from eventyay.core.permissions import Permission from eventyay.base.services.bbb import BBBService from eventyay.features.live.decorators import command, room_action @@ -20,15 +21,20 @@ async def room_url(self, body): service = BBBService(self.consumer.event) if not self.consumer.user.profile.get("display_name"): raise ConsumerException("bbb.join.missing_profile") - url = await service.get_join_url_for_room( - self.room, - self.consumer.user, - moderator=await self.consumer.event.has_permission_async( - user=self.consumer.user, - permission=Permission.ROOM_BBB_MODERATE, - room=self.room, - ), - ) + try: + url = await service.get_join_url_for_room( + self.room, + self.consumer.user, + moderator=await self.consumer.event.has_permission_async( + user=self.consumer.user, + permission=Permission.ROOM_BBB_MODERATE, + room=self.room, + ), + ) + except IntegrityError: + # This happens in dev environment when no BBB server is configured + raise ConsumerException("bbb.failed") + if not url: raise ConsumerException("bbb.failed") await self.consumer.send_success({"url": url}) @@ -38,10 +44,14 @@ async def call_url(self, body): service = BBBService(self.consumer.event) if not self.consumer.user.profile.get("display_name"): raise ConsumerException("bbb.join.missing_profile") - url = await service.get_join_url_for_call_id( - body.get("call"), - self.consumer.user, - ) + try: + url = await service.get_join_url_for_call_id( + body.get("call"), + self.consumer.user, + ) + except IntegrityError: + raise ConsumerException("bbb.failed") + if not url: raise ConsumerException("bbb.failed") await self.consumer.send_success({"url": url}) @@ -53,7 +63,10 @@ async def call_url(self, body): ) async def recordings(self, body): service = BBBService(self.consumer.event) - recordings = await service.get_recordings_for_room( - self.room, - ) + try: + recordings = await service.get_recordings_for_room( + self.room, + ) + except IntegrityError: + recordings = [] await self.consumer.send_success({"results": recordings}) From 7365b9b050a0be5a9669d081c0afe30396cf129b Mon Sep 17 00:00:00 2001 From: rakshitjain23 Date: Thu, 18 Dec 2025 19:48:22 +0530 Subject: [PATCH 2/3] feat: Add short_url configuration to settings and simplify BBB service error handling by removing IntegrityError catches. --- app/eventyay/config/eventyay.development.toml | 2 + app/eventyay/config/eventyay.production.toml | 2 + app/eventyay/config/next_settings.py | 8 +--- app/eventyay/features/live/modules/bbb.py | 43 +++++++------------ 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/app/eventyay/config/eventyay.development.toml b/app/eventyay/config/eventyay.development.toml index 8ebdec8e5c..936b29c9e9 100644 --- a/app/eventyay/config/eventyay.development.toml +++ b/app/eventyay/config/eventyay.development.toml @@ -8,3 +8,5 @@ allowed_hosts = ['*'] site_url = 'https://test.eventyay.com' redis_url = 'redis://localhost/0' + +short_url = 'https://test.eventyay.com' diff --git a/app/eventyay/config/eventyay.production.toml b/app/eventyay/config/eventyay.production.toml index 50d8c23027..94a9d02ea0 100644 --- a/app/eventyay/config/eventyay.production.toml +++ b/app/eventyay/config/eventyay.production.toml @@ -23,3 +23,5 @@ talk_hostname = 'https://next.eventyay.com/' redis_url = 'redis://eventyay-next-redis/0' celery_always_eager = false + +short_url = 'https://next.eventyay.com' diff --git a/app/eventyay/config/next_settings.py b/app/eventyay/config/next_settings.py index 158b5db86f..5abf556615 100644 --- a/app/eventyay/config/next_settings.py +++ b/app/eventyay/config/next_settings.py @@ -128,7 +128,7 @@ class BaseSettings(_BaseSettings): # Override it to match the domain the website is running on, # or you will get "DisallowedHost" error. site_url: HttpUrl = 'http://localhost:8000' - short_url: HttpUrl | None = None + short_url: HttpUrl = 'http://localhost:8000' talk_hostname: str = 'http://localhost:8000' sentry_dsn: str = '' instance_name: str = 'eventyay' @@ -147,11 +147,7 @@ class BaseSettings(_BaseSettings): zoom_secret: str = '' control_secret: str = '' - @model_validator(mode='after') - def default_short_url(self) -> 'BaseSettings': - if self.short_url is None: - self.short_url = self.site_url - return self + statsd_host: str = '' statsd_port: int = 8125 statsd_prefix: str = 'eventyay' diff --git a/app/eventyay/features/live/modules/bbb.py b/app/eventyay/features/live/modules/bbb.py index 5474b1f1cc..267bac0042 100644 --- a/app/eventyay/features/live/modules/bbb.py +++ b/app/eventyay/features/live/modules/bbb.py @@ -1,4 +1,3 @@ -from django.db.utils import IntegrityError from eventyay.core.permissions import Permission from eventyay.base.services.bbb import BBBService from eventyay.features.live.decorators import command, room_action @@ -21,19 +20,15 @@ async def room_url(self, body): service = BBBService(self.consumer.event) if not self.consumer.user.profile.get("display_name"): raise ConsumerException("bbb.join.missing_profile") - try: - url = await service.get_join_url_for_room( - self.room, - self.consumer.user, - moderator=await self.consumer.event.has_permission_async( - user=self.consumer.user, - permission=Permission.ROOM_BBB_MODERATE, - room=self.room, - ), - ) - except IntegrityError: - # This happens in dev environment when no BBB server is configured - raise ConsumerException("bbb.failed") + url = await service.get_join_url_for_room( + self.room, + self.consumer.user, + moderator=await self.consumer.event.has_permission_async( + user=self.consumer.user, + permission=Permission.ROOM_BBB_MODERATE, + room=self.room, + ), + ) if not url: raise ConsumerException("bbb.failed") @@ -44,13 +39,10 @@ async def call_url(self, body): service = BBBService(self.consumer.event) if not self.consumer.user.profile.get("display_name"): raise ConsumerException("bbb.join.missing_profile") - try: - url = await service.get_join_url_for_call_id( - body.get("call"), - self.consumer.user, - ) - except IntegrityError: - raise ConsumerException("bbb.failed") + url = await service.get_join_url_for_call_id( + body.get("call"), + self.consumer.user, + ) if not url: raise ConsumerException("bbb.failed") @@ -63,10 +55,7 @@ async def call_url(self, body): ) async def recordings(self, body): service = BBBService(self.consumer.event) - try: - recordings = await service.get_recordings_for_room( - self.room, - ) - except IntegrityError: - recordings = [] + recordings = await service.get_recordings_for_room( + self.room, + ) await self.consumer.send_success({"results": recordings}) From 44b2b67071fac5afe8ede1413d967f9076088708 Mon Sep 17 00:00:00 2001 From: rakshitjain23 Date: Sat, 20 Dec 2025 15:20:34 +0530 Subject: [PATCH 3/3] Fix: remove unused model_validator import from next_settings.py --- app/eventyay/config/next_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/eventyay/config/next_settings.py b/app/eventyay/config/next_settings.py index 5abf556615..2b28f933e9 100644 --- a/app/eventyay/config/next_settings.py +++ b/app/eventyay/config/next_settings.py @@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _ from kombu import Queue from pycountry import currencies -from pydantic import Field, HttpUrl, model_validator +from pydantic import Field, HttpUrl from pydantic_settings import BaseSettings as _BaseSettings from pydantic_settings import PydanticBaseSettingsSource, SettingsConfigDict, TomlConfigSettingsSource from redis.asyncio.retry import Retry