130 lines
4.5 KiB
Python
130 lines
4.5 KiB
Python
"""
|
|
Views for moderation app.
|
|
"""
|
|
from django.shortcuts import get_object_or_404, redirect
|
|
from django.views.generic import ListView, DetailView, UpdateView
|
|
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
|
from django.contrib.messages.views import SuccessMessageMixin
|
|
from django.urls import reverse_lazy
|
|
from django.utils import timezone
|
|
from reports.models import ScamReport
|
|
from .models import ModerationQueue, ModerationAction
|
|
|
|
|
|
class ModeratorRequiredMixin(UserPassesTestMixin):
|
|
"""Mixin to require moderator role."""
|
|
def test_func(self):
|
|
return self.request.user.is_authenticated and self.request.user.is_moderator()
|
|
|
|
|
|
class ModerationDashboardView(LoginRequiredMixin, ModeratorRequiredMixin, ListView):
|
|
"""Moderation dashboard."""
|
|
template_name = 'moderation/dashboard.html'
|
|
context_object_name = 'reports'
|
|
|
|
def get_queryset(self):
|
|
return ScamReport.objects.filter(
|
|
status__in=['pending', 'under_review']
|
|
).order_by('-created_at')[:10]
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['pending_count'] = ScamReport.objects.filter(status='pending').count()
|
|
context['under_review_count'] = ScamReport.objects.filter(status='under_review').count()
|
|
context['verified_count'] = ScamReport.objects.filter(status='verified').count()
|
|
return context
|
|
|
|
|
|
class ModerationQueueView(LoginRequiredMixin, ModeratorRequiredMixin, ListView):
|
|
"""Moderation queue."""
|
|
model = ModerationQueue
|
|
template_name = 'moderation/queue.html'
|
|
context_object_name = 'queue_items'
|
|
paginate_by = 20
|
|
|
|
def get_queryset(self):
|
|
return ModerationQueue.objects.select_related(
|
|
'report', 'assigned_to'
|
|
).order_by('-priority', 'created_at')
|
|
|
|
|
|
class ReportModerationView(LoginRequiredMixin, ModeratorRequiredMixin, DetailView):
|
|
"""View report for moderation."""
|
|
model = ScamReport
|
|
template_name = 'moderation/report_detail.html'
|
|
context_object_name = 'report'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['osint_results'] = self.object.osint_results.all()
|
|
context['verifications'] = self.object.verifications.all()
|
|
context['moderation_actions'] = self.object.moderation_actions.all()[:10]
|
|
return context
|
|
|
|
|
|
class ApproveReportView(LoginRequiredMixin, ModeratorRequiredMixin, SuccessMessageMixin, UpdateView):
|
|
"""Approve a report."""
|
|
model = ScamReport
|
|
fields = []
|
|
template_name = 'moderation/approve.html'
|
|
success_message = "Report approved successfully!"
|
|
|
|
def form_valid(self, form):
|
|
previous_status = form.instance.status
|
|
form.instance.status = 'verified'
|
|
form.instance.verified_at = timezone.now()
|
|
response = super().form_valid(form)
|
|
|
|
# Create moderation action
|
|
ModerationAction.objects.create(
|
|
report=form.instance,
|
|
moderator=self.request.user,
|
|
action_type='approve',
|
|
previous_status=previous_status,
|
|
new_status='verified'
|
|
)
|
|
|
|
# Remove from queue
|
|
ModerationQueue.objects.filter(report=form.instance).delete()
|
|
|
|
return response
|
|
|
|
def get_success_url(self):
|
|
return reverse_lazy('moderation:queue')
|
|
|
|
|
|
class RejectReportView(LoginRequiredMixin, ModeratorRequiredMixin, SuccessMessageMixin, UpdateView):
|
|
"""Reject a report."""
|
|
model = ScamReport
|
|
fields = []
|
|
template_name = 'moderation/reject.html'
|
|
success_message = "Report rejected."
|
|
|
|
def form_valid(self, form):
|
|
previous_status = form.instance.status
|
|
form.instance.status = 'rejected'
|
|
response = super().form_valid(form)
|
|
|
|
# Get reason from form
|
|
reason = self.request.POST.get('reason', '').strip()
|
|
notes = self.request.POST.get('notes', '').strip()
|
|
|
|
# Create moderation action
|
|
ModerationAction.objects.create(
|
|
report=form.instance,
|
|
moderator=self.request.user,
|
|
action_type='reject',
|
|
previous_status=previous_status,
|
|
new_status='rejected',
|
|
reason=reason,
|
|
notes=notes
|
|
)
|
|
|
|
# Remove from queue
|
|
ModerationQueue.objects.filter(report=form.instance).delete()
|
|
|
|
return response
|
|
|
|
def get_success_url(self):
|
|
return reverse_lazy('moderation:queue')
|