mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 07:51:08 -05:00
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols. - Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage. - Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
192 lines
6.6 KiB
Python
192 lines
6.6 KiB
Python
from django.shortcuts import render
|
|
from django.views.generic import TemplateView
|
|
from django.db.models import Q
|
|
from django.core.cache import cache
|
|
from apps.parks.models import Park, Company
|
|
from apps.rides.models import Ride
|
|
from apps.core.analytics import PageView
|
|
from django.conf import settings
|
|
import logging
|
|
import os
|
|
import secrets
|
|
|
|
from apps.core.logging import log_exception
|
|
|
|
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},
|
|
)
|