3838
3939class ScheduleMixin :
4040 MY_STARRED_ICS_TOKEN_SESSION_KEY = 'my_starred_ics_token'
41-
41+
4242 @cached_property
4343 def version (self ):
4444 if version := self .kwargs .get ("version" ):
@@ -372,28 +372,25 @@ class CalendarRedirectView(EventPermissionRequired, ScheduleMixin, TemplateView)
372372 def get (self , request , * args , ** kwargs ):
373373 # Get URL name from resolver
374374 url_name = request .resolver_match .url_name if request .resolver_match else None
375-
376375 # Determine calendar type and starred status from URL pattern
377376 is_google = "google" in url_name
378377 is_my = "my" in url_name
379378
380379 if is_my :
381380 # For starred sessions
382381 if not request .user .is_authenticated :
383- login_url = f"{ self .request .event .urls .login } ?next= { request .get_full_path ()} "
382+ login_url = f"{ self .request .event .urls .login } ?{ urlencode ({ 'next' : request .get_full_path ()} )} "
384383 return HttpResponseRedirect (login_url )
385384
386385 # Check for existing valid token
387386 existing_token = request .session .get (self .MY_STARRED_ICS_TOKEN_SESSION_KEY )
388387 generate_new_token = True
389-
390388 # If we have an existing token, check if it's still valid and not expiring soon
391389 if existing_token :
392390 token_status = self .check_token_expiry (existing_token )
393391 if token_status is True : # Token is valid and has at least 4 days left
394392 token = existing_token
395393 generate_new_token = False
396-
397394 # Generate new token if needed (this will invalidate any existing token)
398395 if generate_new_token :
399396 token = self .generate_ics_token (request , request .user .id )
@@ -419,20 +416,23 @@ def get(self, request, *args, **kwargs):
419416 if is_google :
420417 # Google Calendar requires special URL format
421418 google_url = f"https://calendar.google.com/calendar/render?{ urlencode ({'cid' : ics_url })} "
419+ # HTML-based redirection works more reliably across calendar clients like Outlook and Apple Calendar which often mishandle HTTP 302s.
420+ # Redirecting via browser ensures consistent behavior and user fallback options. this HTML based redirection helps us avoid this hit or miss behaviour
422421 response = HttpResponse (
423422 f'<html><head><meta http-equiv="refresh" content="0;url={ google_url } "></head>'
424423 f'<body><p style="text-align: center; padding:2vw; font-family: Roboto,Helvetica Neue,HelveticaNeue,Helvetica,Arial,sans-serif;">Redirecting to Google Calendar: { google_url } </p><script>window.location.href="{ google_url } ";</script></body></html>' ,
425424 content_type = 'text/html'
426425 )
427426 return response
428- else :
429- # Other calendars use webcal protocol
430- parsed = urlparse (ics_url )
431- webcal_url = urlunparse (('webcal' ,) + parsed [1 :])
432- # Create a simple HTML redirect with meta refresh
433- response = HttpResponse (
434- f'<html><head><meta http-equiv="refresh" content="0;url={ webcal_url } "></head>'
435- f'<body><p style="text-align: center; padding:2vw; font-family: Roboto,Helvetica Neue,HelveticaNeue,Helvetica,Arial,sans-serif;">Redirecting to: { webcal_url } </p><script>window.location.href="{ webcal_url } ";</script></body></html>' ,
436- content_type = 'text/html'
437- )
438- return response
427+
428+ # Other calendars use webcal protocol
429+ parsed = urlparse (ics_url )
430+ webcal_url = urlunparse (('webcal' ,) + parsed [1 :])
431+ # HTML-based redirection works more reliably across calendar clients like Outlook and Apple Calendar which often mishandle HTTP 302s.
432+ # Redirecting via browser ensures consistent behavior and user fallback options. this HTML based redirection helps us avoid this hit or miss behaviour
433+ response = HttpResponse (
434+ f'<html><head><meta http-equiv="refresh" content="0;url={ webcal_url } "></head>'
435+ f'<body><p style="text-align: center; padding:2vw; font-family: Roboto,Helvetica Neue,HelveticaNeue,Helvetica,Arial,sans-serif;">Redirecting to: { webcal_url } </p><script>window.location.href="{ webcal_url } ";</script></body></html>' ,
436+ content_type = 'text/html'
437+ )
438+ return response
0 commit comments