Big upheaval of how the reports system works
* There are now Reports and ReportRecords. * Reports coordinate to what moderators see, and ReportRecords coordinate with the reports that are created by individual users. * Reports keep track of the report reason and the creating user. * ReportRecords keep track of the total weight and whether this report requires urgent attention or not. * ReportRecord keeps track of its own weight and urgency because then we can sort by weight and urgency in the admin view. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
from datetime import timedelta
|
||||
import os
|
||||
from pathlib import Path
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.dispatch import receiver
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
@@ -218,15 +218,51 @@ class ReportReason(models.Model):
|
||||
return self.reason
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
class ReportRecord(models.Model):
|
||||
# Post that this report is for
|
||||
post = models.ForeignKey("Post", on_delete=models.CASCADE)
|
||||
post = models.OneToOneField("Post", on_delete=models.CASCADE)
|
||||
# Report weight
|
||||
weight = models.IntegerField(default=0)
|
||||
# If this report is urgent or not
|
||||
urgent = models.BooleanField(default=False)
|
||||
|
||||
# def urgent(self) -> bool:
|
||||
# return self.report_set().aggregate(
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
"""
|
||||
There are two reasons why this model exists:
|
||||
|
||||
1. In the report view in the Django admin, there is probably not a good way
|
||||
to specially modify the list of reports. Since we don't want to see every
|
||||
single report, we need a way to limit this *in data* rather than in code.
|
||||
We accomplish this by having:
|
||||
- Report model, which is all reports unique to users.
|
||||
- ReportRecord model, which is the collection of all reports unique to posts.
|
||||
2. We want to keep a log of all reports created by users, in case we think
|
||||
they are abusing the system.
|
||||
"""
|
||||
|
||||
# The report that was made by this user
|
||||
record = models.ForeignKey("ReportRecord", on_delete=models.CASCADE)
|
||||
# Reason for this report
|
||||
reason = models.ForeignKey("ReportReason", on_delete=models.SET_NULL, null=True)
|
||||
# IP address of the reporter
|
||||
ip = models.GenericIPAddressField()
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=Report)
|
||||
def report_created(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
# get the total weight, this is probably going to be more reliable than
|
||||
# adding the weight every time
|
||||
weights = [report.reason.weight for report in instance.record.report_set.all()]
|
||||
instance.record.weight = sum(weights)
|
||||
instance.record.urgent |= instance.reason.urgent
|
||||
instance.record.save()
|
||||
|
||||
|
||||
class Ban(models.Model):
|
||||
# IP address of the reporter
|
||||
ip = models.GenericIPAddressField()
|
||||
@@ -239,7 +275,7 @@ class Ban(models.Model):
|
||||
# The time that this ban was created.
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
# Expiration date of this ban.
|
||||
expires = models.DateTimeField(auto_now_add=True)
|
||||
expires = models.DateTimeField()
|
||||
|
||||
|
||||
class BanTemplate(models.Model):
|
||||
@@ -249,4 +285,5 @@ class BanTemplate(models.Model):
|
||||
duration = models.DurationField()
|
||||
|
||||
def create_ban(self, ip: str) -> Ban:
|
||||
return Ban.objects.create(ip=ip, ban_reason=self.ban_reason)
|
||||
expires = timezone.now() + self.duration
|
||||
return Ban.objects.create(ip=ip, ban_reason=self.ban_reason, expires=expires)
|
||||
|
||||
Reference in New Issue
Block a user