11import importlib .util
2- import os
32import json
3+ import logging
4+ import os
5+ from mimetypes import guess_type
46
57from django .apps import apps
8+ from django .core .serializers .json import DjangoJSONEncoder
9+ from django .http import Http404 , HttpResponse
610from django .urls import include , path , re_path
11+ from django .utils .encoding import force_str
12+ from django .utils .functional import Promise
713from django .views .generic import TemplateView , View
8- from django .http import HttpResponse , Http404
914from django .views .static import serve as static_serve
10- from django .conf import settings
1115from django_scopes import scope
12- from mimetypes import guess_type
13- from django .core .serializers .json import DjangoJSONEncoder
14- from django .utils .functional import Promise
15- from django .utils .encoding import force_str
1616from i18nfield .strings import LazyI18nString
1717
18- # Ticket-video integration: plugin URLs are auto-included via plugin handler below.
18+ from eventyay .base .models import Event # Added for /video event context
19+ from eventyay .common .urls import OrganizerSlugConverter # noqa: F401 (registers converter)
1920
21+ # Ticket-video integration: plugin URLs are auto-included via plugin handler below.
2022from eventyay .config .urls import common_patterns
21- from eventyay .multidomain .plugin_handler import plugin_event_urls
2223from eventyay .multidomain import redirects
24+ from eventyay .multidomain .plugin_handler import plugin_event_urls
2325from eventyay .presale .urls import (
2426 event_patterns ,
2527 locale_patterns ,
2628 organizer_patterns ,
2729)
28- from eventyay .base .models import Event # Added for /video event context
2930
3031BASE_DIR = os .path .abspath (os .path .join (os .path .dirname (__file__ ), '..' ))
3132WEBAPP_DIST_DIR = os .path .normpath (os .path .join (BASE_DIR , 'static' , 'webapp' ))
33+ logger = logging .getLogger (__name__ )
3234
3335EXCLUDED_LEGACY_PREFIXES = (
3436 "common" ,
@@ -82,14 +84,14 @@ def get(self, request, *args, **kwargs):
8284 )
8385 except Event .DoesNotExist :
8486 return HttpResponse ('Event not found' , status = 404 )
85-
87+
8688 index_path = os .path .join (WEBAPP_DIST_DIR , 'index.html' )
8789 if os .path .exists (index_path ):
8890 with open (index_path , 'r' ) as f :
8991 content = f .read ()
9092 else :
9193 content = '<!-- /video build missing: {} -->' .format (index_path )
92-
94+
9395 base_href = '/video/'
9496 if event :
9597 # Inject window.venueless config (frontend still expects this name)
@@ -104,11 +106,11 @@ def safe_reverse(name, **kw):
104106 except Exception :
105107 return None
106108 cfg = event .config or {}
107-
109+
108110 with scope (event = event ):
109111 schedule = event .current_schedule or event .wip_schedule
110112 schedule_data = schedule .build_data (all_talks = False ) if schedule else None
111-
113+
112114 base_path = event .urls .video_base .rstrip ('/' )
113115 base_href = event .urls .video_base
114116 injected = {
@@ -182,9 +184,9 @@ def get(self, request, path='', *args, **kwargs):
182184 (
183185 locale_patterns
184186 + [
185- re_path (r'^(?P<organizer>[^/ ]+)/' , include (organizer_patterns )),
187+ re_path (r'^(?P<organizer>[a-zA-Z0-9_.- ]+)/' , include (organizer_patterns )),
186188 re_path (
187- r'^(?P<organizer>[^/ ]+)/(?P<event>[^/]+)/' ,
189+ r'^(?P<organizer>[a-zA-Z0-9_.- ]+)/(?P<event>[^/]+)/' ,
188190 include (event_patterns ),
189191 ),
190192 path (
@@ -210,14 +212,15 @@ def get(self, request, path='', *args, **kwargs):
210212 if hasattr (urlmod , 'event_patterns' ):
211213 patterns = plugin_event_urls (urlmod .event_patterns , plugin = app .name )
212214 single_plugin_patterns .append (
213- re_path ( r'^(?P< organizer>[^/]+)/(?P< event>[^/]+) /' , include (patterns ))
215+ path ( '<orgslug: organizer>/<slug: event>/' , include (patterns ))
214216 )
215217 if hasattr (urlmod , 'organizer_patterns' ):
216218 patterns = urlmod .organizer_patterns
217219 single_plugin_patterns .append (
218- re_path ( r'^(?P< organizer>[^/]+) /' , include (patterns ))
220+ path ( '<orgslug: organizer>/' , include (patterns ))
219221 )
220222 raw_plugin_patterns .append (path ('' , include ((single_plugin_patterns , app .label ))))
223+ logger .debug ('Registered URLs under "%s" namespace:\n %s' , app .label , single_plugin_patterns )
221224
222225# Fallback: include pretix_venueless plugin URLs even if lacking EventyayPluginMeta
223226try :
@@ -229,16 +232,16 @@ def get(self, request, path='', *args, **kwargs):
229232 if hasattr (urlmod , 'event_patterns' ):
230233 patterns = plugin_event_urls (urlmod .event_patterns , plugin = 'pretix_venueless' )
231234 single_plugin_patterns .append (
232- re_path (r'^(?P<organizer>[^/ ]+)/(?P<event>[^/]+)/' , include (patterns ))
235+ re_path (r'^(?P<organizer>[a-zA-Z0-9_.- ]+)/(?P<event>[^/]+)/' , include (patterns ))
233236 )
234237 if hasattr (urlmod , 'organizer_patterns' ):
235238 patterns = urlmod .organizer_patterns
236239 single_plugin_patterns .append (
237- re_path (r'^(?P<organizer>[^/ ]+)/' , include (patterns ))
240+ re_path (r'^(?P<organizer>[a-zA-Z0-9_.- ]+)/' , include (patterns ))
238241 )
239242 raw_plugin_patterns .append (path ('' , include ((single_plugin_patterns , 'pretix_venueless' ))))
240- except Exception :
241- pass
243+ except TypeError :
244+ logger . exception ( 'Error including pretix_venueless plugin URLs' )
242245
243246plugin_patterns = [path ('' , include ((raw_plugin_patterns , 'plugins' )))]
244247
@@ -249,7 +252,7 @@ def get(self, request, path='', *args, **kwargs):
249252
250253unified_event_patterns = [
251254 re_path (
252- r'^(?P<organizer>[^/ ]+)/(?P<event>[^/]+)/' ,
255+ r'^(?P<organizer>[a-zA-Z0-9_.- ]+)/(?P<event>[^/]+)/' ,
253256 include (
254257 [
255258 # Video patterns under {organizer}/{event}/video/
@@ -301,10 +304,12 @@ def get(self, request, path='', *args, **kwargs):
301304urlpatterns = (
302305 common_patterns
303306 + storage_patterns
307+ # The plugins patterns must be before legacy_redirect_patterns and presale_patterns_main
308+ # to avoid misdetection of plugin prefixes and organizer/event slugs.
309+ + plugin_patterns
304310 + legacy_redirect_patterns
305311 + presale_patterns_main
306312 + unified_event_patterns
307- + plugin_patterns
308313)
309314
310315handler404 = 'eventyay.base.views.errors.page_not_found'
0 commit comments