from django.views.generic import ListView, TemplateView from django.shortcuts import get_object_or_404 from django.http import HttpResponse, JsonResponse from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.decorators import login_required from django.template.loader import render_to_string from django.db.models import Q from django.core.exceptions import PermissionDenied from .models import EditSubmission, PhotoSubmission class ModeratorRequiredMixin(UserPassesTestMixin): def test_func(self): if not hasattr(self, 'request'): return False if not self.request.user.is_authenticated: return False return getattr(self.request.user, 'role', None) in ['MODERATOR', 'ADMIN', 'SUPERUSER'] def handle_no_permission(self): if not self.request.user.is_authenticated: return super().handle_no_permission() raise PermissionDenied("You do not have moderator permissions.") class DashboardView(LoginRequiredMixin, ModeratorRequiredMixin, TemplateView): template_name = 'moderation/dashboard.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['submissions'] = EditSubmission.objects.all().order_by('-created_at')[:10] return context class EditSubmissionListView(LoginRequiredMixin, ModeratorRequiredMixin, ListView): template_name = 'moderation/edit_submission_list.html' context_object_name = 'submissions' def get_queryset(self): queryset = EditSubmission.objects.all().order_by('-created_at') status = self.request.GET.get('status') if status: queryset = queryset.filter(status=status) submission_type = self.request.GET.get('type') if submission_type: queryset = queryset.filter(submission_type=submission_type) content_type = self.request.GET.get('content_type') if content_type: queryset = queryset.filter(content_type__model=content_type) return queryset class PhotoSubmissionListView(LoginRequiredMixin, ModeratorRequiredMixin, ListView): template_name = 'moderation/photo_submission_list.html' context_object_name = 'submissions' def get_queryset(self): queryset = PhotoSubmission.objects.all().order_by('-created_at') status = self.request.GET.get('status') if status: queryset = queryset.filter(status=status) return queryset @login_required def submission_list(request): """HTMX endpoint for filtered submission list""" if not request.user.role in ['MODERATOR', 'ADMIN', 'SUPERUSER']: return HttpResponse(status=403) status = request.GET.get('status') submission_type = request.GET.get('type') content_type = request.GET.get('content_type') queryset = EditSubmission.objects.all().order_by('-created_at') if status: queryset = queryset.filter(status=status) if submission_type: queryset = queryset.filter(submission_type=submission_type) if content_type: queryset = queryset.filter(content_type__model=content_type) context = { 'submissions': queryset } html = render_to_string('moderation/partials/submission_list.html', context, request=request) return HttpResponse(html) @login_required def approve_submission(request, submission_id): """HTMX endpoint for approving a submission""" if not request.user.role in ['MODERATOR', 'ADMIN', 'SUPERUSER']: return HttpResponse(status=403) submission = get_object_or_404(EditSubmission, id=submission_id) notes = request.POST.get('notes', '') try: submission.approve(request.user) if notes: submission.notes = notes submission.save() context = {'submission': submission} html = render_to_string('moderation/partials/submission_list.html', context, request=request) return HttpResponse(html) except ValueError as e: return HttpResponse(str(e), status=400) @login_required def reject_submission(request, submission_id): """HTMX endpoint for rejecting a submission""" if not request.user.role in ['MODERATOR', 'ADMIN', 'SUPERUSER']: return HttpResponse(status=403) submission = get_object_or_404(EditSubmission, id=submission_id) notes = request.POST.get('notes', '') submission.reject(request.user) if notes: submission.notes = notes submission.save() context = {'submission': submission} html = render_to_string('moderation/partials/submission_list.html', context, request=request) return HttpResponse(html) @login_required def escalate_submission(request, submission_id): """HTMX endpoint for escalating a submission""" if not request.user.role == 'MODERATOR': return HttpResponse(status=403) submission = get_object_or_404(EditSubmission, id=submission_id) notes = request.POST.get('notes', '') submission.escalate(request.user) if notes: submission.notes = notes submission.save() context = {'submission': submission} html = render_to_string('moderation/partials/submission_list.html', context, request=request) return HttpResponse(html) @login_required def approve_photo(request, submission_id): """HTMX endpoint for approving a photo submission""" if not request.user.role in ['MODERATOR', 'ADMIN', 'SUPERUSER']: return HttpResponse(status=403) submission = get_object_or_404(PhotoSubmission, id=submission_id) notes = request.POST.get('notes', '') try: submission.approve(request.user, notes) context = {'submission': submission} html = render_to_string('moderation/partials/photo_submission.html', context, request=request) return HttpResponse(html) except Exception as e: return HttpResponse(str(e), status=400) @login_required def reject_photo(request, submission_id): """HTMX endpoint for rejecting a photo submission""" if not request.user.role in ['MODERATOR', 'ADMIN', 'SUPERUSER']: return HttpResponse(status=403) submission = get_object_or_404(PhotoSubmission, id=submission_id) notes = request.POST.get('notes', '') submission.reject(request.user, notes) context = {'submission': submission} html = render_to_string('moderation/partials/photo_submission.html', context, request=request) return HttpResponse(html)