Schedules automod task

This commit is contained in:
Mouse Reeve 2022-02-26 10:13:44 -08:00
parent 95e9119817
commit 2a436800c4
8 changed files with 105 additions and 14 deletions

View file

@ -8,6 +8,7 @@ from django.forms import ModelForm, PasswordInput, widgets, ChoiceField
from django.forms.widgets import Textarea
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django_celery_beat.models import IntervalSchedule
from bookwyrm import models
from bookwyrm.models.fields import ClearableFileInputWithWarning
@ -556,3 +557,9 @@ class AutoModRuleForm(CustomForm):
class Meta:
model = models.AutoMod
fields = ["string_match", "flag_users", "flag_statuses", "created_by"]
class IntervalScheduleForm(CustomForm):
class Meta:
model = IntervalSchedule
fields = ["every", "period"]

View file

@ -54,6 +54,7 @@ class AutoMod(models.Model):
@app.task(queue="low_priority")
def automod_task():
"""Create reports"""
print("TASK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
if not AutoMod.objects.exists():
return
reporter = AutoMod.objects.first().created_by

View file

@ -90,7 +90,7 @@ INSTALLED_APPS = [
"sass_processor",
"bookwyrm",
"celery",
'django_celery_beat',
"django_celery_beat",
"imagekit",
"storages",
]

View file

@ -1,5 +1,6 @@
{% extends 'settings/layout.html' %}
{% load i18n %}
{% load humanize %}
{% load utilities %}
{% block title %}
@ -16,12 +17,46 @@
<p>
{% trans "Auto-moderation rules will create reports for any local user or status with fields matching the provided string." %}
{% trans "Users or statuses that have already been reported (regardless of whether the report was resolved) will not be flagged." %}
{% trans "At this time, reports are <em>not</em> being generated automatically, and you must manually trigger a scan." %}
</p>
<form name="run-scan" method="POST" action="{% url 'settings-automod-run' %}">
{% if task %}
<dl>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Schedule:" %}
</dt>
<dd>
{{ task.schedule }}
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Last run:" %}
</dt>
<dd>
{{ task.last_run_at|naturaltime }}
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Total run count:" %}
</dt>
<dd>
{{ task.total_run_count }}
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Enabled:" %}
</dt>
<dd>
<span class="tag {% if task.enabled %}is-success{% else %}is-danger{% endif %}">
{{ task.enabled|yesno }}
</span>
</dd>
</dl>
{% else %}
<form name="schedule-scan" method="POST" action="{% url 'settings-automod-schedule' %}">
{% csrf_token %}
<button class="button is-warning">{% trans "Run scan" %}</button>
{{ task_form.as_p }}
<button class="button is-warning">{% trans "Schedule scan" %}</button>
</form>
{% endif %}
</div>
{% if success %}

View file

@ -217,11 +217,18 @@ urlpatterns = [
# auto-moderation rules
re_path(r"^settings/automod/?$", views.AutoMod.as_view(), name="settings-automod"),
re_path(
r"^settings/automod/(?P<rule_id>\d+)/delete?$",
r"^settings/automod/(?P<rule_id>\d+)/delete/?$",
views.automod_delete,
name="settings-automod-delete",
),
re_path(r"^settings/automod/run?$", views.run_automod, name="settings-automod-run"),
re_path(
r"^settings/automod/schedule/?$",
views.schedule_automod_task,
name="settings-automod-schedule",
),
re_path(
r"^settings/automod/run/?$", views.run_automod, name="settings-automod-run"
),
# moderation
re_path(
r"^settings/reports/?$", views.ReportsAdmin.as_view(), name="settings-reports"

View file

@ -2,7 +2,7 @@
# site admin
from .admin.announcements import Announcements, Announcement
from .admin.announcements import EditAnnouncement, delete_announcement
from .admin.automod import AutoMod, automod_delete, run_automod
from .admin.automod import AutoMod, automod_delete, run_automod, schedule_automod_task
from .admin.dashboard import Dashboard
from .admin.federation import Federation, FederatedServer
from .admin.federation import AddFederatedServer, ImportServerBlocklist

View file

@ -1,10 +1,12 @@
""" moderation via flagged posts and users """
from django.contrib.auth.decorators import login_required, permission_required
from django.db import transaction
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from django_celery_beat.models import PeriodicTask
from bookwyrm import forms, models
@ -24,8 +26,9 @@ class AutoMod(View):
def get(self, request):
"""view rules"""
data = {"rules": models.AutoMod.objects.all(), "form": forms.AutoModRuleForm()}
return TemplateResponse(request, "settings/automod/rules.html", data)
return TemplateResponse(
request, "settings/automod/rules.html", automod_view_data()
)
def post(self, request):
"""add rule"""
@ -35,14 +38,32 @@ class AutoMod(View):
form.save()
form = forms.AutoModRuleForm()
data = {
"rules": models.AutoMod.objects.all(),
"form": form,
"success": success,
}
data = automod_view_data()
data["form"] = form
return TemplateResponse(request, "settings/automod/rules.html", data)
@require_POST
@permission_required("bookwyrm.moderate_user", raise_exception=True)
@permission_required("bookwyrm.moderate_post", raise_exception=True)
def schedule_automod_task(request):
"""scheduler"""
form = forms.IntervalScheduleForm(request.POST)
if not form.is_valid():
data = automod_view_data()
data["task_form"] = form
return TemplateResponse(request, "settings/automod/rules.html", data)
with transaction.atomic():
schedule = form.save()
PeriodicTask.objects.get_or_create(
interval=schedule,
name="automod-task",
task="bookwyrm.models.antispam.automod_task",
)
return redirect("settings-automod")
@require_POST
@permission_required("bookwyrm.moderate_user", raise_exception=True)
@permission_required("bookwyrm.moderate_post", raise_exception=True)
@ -62,3 +83,18 @@ def run_automod(request):
"""run scan"""
models.automod_task.delay()
return redirect("settings-automod")
def automod_view_data():
"""helper to get data used in the template"""
try:
task = PeriodicTask.objects.get(name="automod-task")
except PeriodicTask.DoesNotExist:
task = None
return {
"task": task,
"task_form": forms.IntervalScheduleForm(),
"rules": models.AutoMod.objects.all(),
"form": forms.AutoModRuleForm(),
}

View file

@ -3,6 +3,7 @@
# pylint: disable=unused-wildcard-import
from bookwyrm.settings import *
# pylint: disable=line-too-long
REDIS_BROKER_PASSWORD = requests.utils.quote(env("REDIS_BROKER_PASSWORD", None))
REDIS_BROKER_HOST = env("REDIS_BROKER_HOST", "redis_broker")
REDIS_BROKER_PORT = env("REDIS_BROKER_PORT", 6379)
@ -16,6 +17,10 @@ CELERY_DEFAULT_QUEUE = "low_priority"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
CELERY_TIMEZONE = env("TIME_ZONE", "UTC")
FLOWER_PORT = env("FLOWER_PORT")
INSTALLED_APPS = INSTALLED_APPS + [