mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 02:31:08 -05:00
- Cleaned up and standardized assertions in ApiTestMixin for API response validation. - Updated ASGI settings to use os.environ for setting the DJANGO_SETTINGS_MODULE. - Removed unused imports and improved formatting in settings.py. - Refactored URL patterns in urls.py for better readability and organization. - Enhanced view functions in views.py for consistency and clarity. - Added .flake8 configuration for linting and style enforcement. - Introduced type stubs for django-environ to improve type checking with Pylance.
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
"""
|
|
Analytics and tracking middleware for Django application.
|
|
"""
|
|
|
|
import pghistory
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.core.handlers.wsgi import WSGIRequest
|
|
from django.utils.deprecation import MiddlewareMixin
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.views.generic.detail import DetailView
|
|
from core.analytics import PageView
|
|
|
|
|
|
class RequestContextProvider(pghistory.context):
|
|
"""Custom context provider for pghistory that extracts information from the request."""
|
|
|
|
def __call__(self, request: WSGIRequest) -> dict:
|
|
return {
|
|
"user": (
|
|
str(request.user)
|
|
if request.user and not isinstance(request.user, AnonymousUser)
|
|
else None
|
|
),
|
|
"ip": request.META.get("REMOTE_ADDR"),
|
|
"user_agent": request.META.get("HTTP_USER_AGENT"),
|
|
"session_key": (
|
|
request.session.session_key if hasattr(request, "session") else None
|
|
),
|
|
}
|
|
|
|
|
|
# Initialize the context provider
|
|
request_context = RequestContextProvider()
|
|
|
|
|
|
class PgHistoryContextMiddleware:
|
|
"""
|
|
Middleware that ensures request object is available to pghistory context.
|
|
"""
|
|
|
|
def __init__(self, get_response):
|
|
self.get_response = get_response
|
|
|
|
def __call__(self, request):
|
|
response = self.get_response(request)
|
|
return response
|
|
|
|
|
|
class PageViewMiddleware(MiddlewareMixin):
|
|
"""Middleware to track page views for DetailView-based pages."""
|
|
|
|
def process_view(self, request, view_func, view_args, view_kwargs):
|
|
# Only track GET requests
|
|
if request.method != "GET":
|
|
return None
|
|
|
|
# Get view class if it exists
|
|
view_class = getattr(view_func, "view_class", None)
|
|
if not view_class or not issubclass(view_class, DetailView):
|
|
return None
|
|
|
|
# Get the object if it's a detail view
|
|
try:
|
|
view_instance = view_class()
|
|
view_instance.request = request
|
|
view_instance.args = view_args
|
|
view_instance.kwargs = view_kwargs
|
|
obj = view_instance.get_object()
|
|
except (AttributeError, Exception):
|
|
return None
|
|
|
|
# Record the page view
|
|
try:
|
|
PageView.objects.create(
|
|
content_type=ContentType.objects.get_for_model(obj.__class__),
|
|
object_id=obj.pk,
|
|
ip_address=request.META.get("REMOTE_ADDR", ""),
|
|
user_agent=request.META.get("HTTP_USER_AGENT", "")[:512],
|
|
)
|
|
except Exception:
|
|
# Fail silently to not interrupt the request
|
|
pass
|
|
|
|
return None
|