import logging import os import secrets from django.conf import settings from django.core.cache import cache from django.db.models import Q from django.shortcuts import render from django.views.generic import TemplateView from apps.core.analytics import PageView from apps.core.logging import log_exception from apps.parks.models import Company, Park from apps.rides.models import Ride logger = logging.getLogger(__name__) def handler404(request, exception): return render(request, "404.html", status=404) def handler500(request): return render(request, "500.html", status=500) class HomeView(TemplateView): template_name = "home.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Get stats context["stats"] = { "total_parks": Park.objects.count(), "ride_count": Ride.objects.count(), "coaster_count": Ride.objects.filter(category="RC").count(), } # Try to get trending items from cache first trending_parks = cache.get("trending_parks") trending_rides = cache.get("trending_rides") # If not in cache, get them directly and cache them if trending_parks is None: try: trending_parks = list( PageView.get_trending_items(Park, hours=24, limit=10) ) if trending_parks: cache.set( "trending_parks", trending_parks, 3600 ) # Cache for 1 hour else: # Fallback to highest rated parks if no trending data trending_parks = Park.objects.exclude( average_rating__isnull=True ).order_by("-average_rating")[:10] except Exception as e: log_exception( logger, e, context={"operation": "get_trending_parks", "fallback": True}, request=self.request, ) # Fallback to highest rated parks if trending calculation fails trending_parks = Park.objects.exclude( average_rating__isnull=True ).order_by("-average_rating")[:10] if trending_rides is None: try: trending_rides = list( PageView.get_trending_items(Ride, hours=24, limit=10) ) if trending_rides: cache.set( "trending_rides", trending_rides, 3600 ) # Cache for 1 hour else: # Fallback to highest rated rides if no trending data trending_rides = Ride.objects.exclude( average_rating__isnull=True ).order_by("-average_rating")[:10] except Exception as e: log_exception( logger, e, context={"operation": "get_trending_rides", "fallback": True}, request=self.request, ) # Fallback to highest rated rides if trending calculation fails trending_rides = Ride.objects.exclude( average_rating__isnull=True ).order_by("-average_rating")[:10] # Get highest rated items (mix of parks and rides) highest_rated_parks = list( Park.objects.exclude(average_rating__isnull=True).order_by( "-average_rating" )[:20] ) # Get more items to randomly select from highest_rated_rides = list( Ride.objects.exclude(average_rating__isnull=True).order_by( "-average_rating" )[:20] ) # Get more items to randomly select from # Combine and shuffle highest rated items all_highest_rated = highest_rated_parks + highest_rated_rides secrets.SystemRandom().shuffle(all_highest_rated) # Keep the same context variable names for template compatibility context["popular_parks"] = trending_parks context["popular_rides"] = trending_rides context["highest_rated"] = all_highest_rated[ :10 ] # Take first 10 after shuffling return context class SearchView(TemplateView): template_name = "search_results.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if query := self.request.GET.get("q", "").strip(): # Search parks context["parks"] = ( Park.objects.filter( Q(name__icontains=query) | Q(location__icontains=query) | Q(description__icontains=query) ) .select_related("operating_company") .prefetch_related("photos")[:10] ) # Search rides context["rides"] = ( Ride.objects.filter( Q(name__icontains=query) | Q(description__icontains=query) | Q(manufacturer__name__icontains=query) ) .select_related("park", "coaster_stats") .prefetch_related("photos")[:10] ) # Search companies context["companies"] = Company.objects.filter( Q(name__icontains=query) | Q(description__icontains=query) ).prefetch_related("operated_parks", "owned_parks")[:10] logger.info( f"Search query: '{query}' returned {len(context['parks'])} parks, " f"{len(context['rides'])} rides, {len(context['companies'])} companies", extra={ "query": query, "parks_count": len(context["parks"]), "rides_count": len(context["rides"]), "companies_count": len(context["companies"]), "user_id": ( self.request.user.id if self.request.user.is_authenticated else None ), }, ) return context def environment_and_settings_view(request): # Get all environment variables env_vars = dict(os.environ) # Get all Django settings as a dictionary settings_vars = { setting: getattr(settings, setting) for setting in dir(settings) if setting.isupper() } return render( request, "environment_and_settings.html", {"env_vars": env_vars, "settings_vars": settings_vars}, )