Add user post wiping

If a user has spammed a lot of posts and made a mess of the board, this
will allow us to delete all posts by the offending user from the same
IP.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2022-07-17 16:59:23 -07:00
parent 8ea95a927c
commit 1856adaf3b
6 changed files with 90 additions and 1 deletions

View File

@@ -134,6 +134,7 @@ class Post(models.Model):
("set_sticky", "Can sticky post"),
("set_bump", "Can bumplock post"),
("set_lock", "Can lock post"),
("wipe_user", "Can wipe all posts by a user"),
]
def save(self, *args, **kwargs):

View File

@@ -7,6 +7,7 @@
if (typeof window.banWindowName === "undefined") {
window.banWindowName = "ban-window";
window.modifyWindowName = "modify-window";
window.wipeWindowName = "wipe-window";
}
if (typeof window.menuItemFactories !== "undefined") {
@@ -28,6 +29,15 @@ if (typeof window.menuItemFactories !== "undefined") {
openModifyWindow($(postElement).attr("data-modify-url"));
})
);
window.menuItemFactories.push(
(postElement) => $("<a>")
.text("Wipe user posts")
.attr("href", "#")
.on("click", (e) => {
e.preventDefault();
openWipeWindow($(postElement).attr("data-wipe-url"));
})
);
}
////////////////////////////////////////////////////////////////////////////////
@@ -88,4 +98,30 @@ function openModifyWindow(modifyUrl) {
modifyWindow.iframe.contentWindow.thisWindow = modifyWindow;
});
modifyWindow.show();
}
////////////////////////////////////////////////////////////////////////////////
// Wipe window
////////////////////////////////////////////////////////////////////////////////
function getWipeWindow() {
return window.top.jsFrame.getWindowByName(wipeWindowName);
}
function openWipeWindow(wipeUrl) {
if (window.top.jsFrame.containsWindowName(wipeWindowName)) {
getWipeWindow().closeFrame();
}
let wipeWindow = window.top.jsFrame.create({
title: "Wipe post",
name: wipeWindowName,
width: 475,
url: wipeUrl,
});
$(wipeWindow.iframe, "iframe").on("load", () => {
fitWindowToContent(wipeWindow);
wipeWindow.setResizable(false);
wipeWindow.iframe.contentWindow.thisWindow = wipeWindow;
});
wipeWindow.show();
}

View File

@@ -8,6 +8,7 @@
{% if user.is_staff %}
data-ban-url="{% url 'board:ban_create' board.url post.id %}"
data-modify-url="{% url 'board:post_modify' post.id %}"
data-wipe-url="{% url 'board:post_wipe' post.id %}"
{% endif %}
>

View File

@@ -0,0 +1,10 @@
{% extends "board/base.html" %}
{% load i18n %}
{% block content %}
{% blocktranslate %}This will delete {{all_posts_count}} posts.{% endblocktranslate %}
<form method="post" {# action="{% url 'board:post_wipe_success' %}" #}>
{% csrf_token %}
<input type="submit" value="Wipe all posts by this user" />
</form>
{% endblock content %}

View File

@@ -42,6 +42,14 @@ urlpatterns = [
ActionSuccessView.as_view(window_timeout=settings.ACTION_SUCCESS_CLOSE_TIMEOUT),
name="post_delete_success",
),
path("post/wipe/<int:pk>/", PostWipeView.as_view(), name="post_wipe"),
path(
"post/wipe/success/",
ActionSuccessView.as_view(
window_timeout=settings.ACTION_SUCCESS_CLOSE_TIMEOUT, message="Posts wiped."
),
name="post_wipe_success",
),
# Board views
path("post/success/", PostSuccessView.as_view(), name="post_success"),
path("<slug:url>/page/<int:page>/", BoardView.as_view(), name="board_detail"),

View File

@@ -8,7 +8,7 @@ from django.http import Http404, HttpResponseRedirect
from django.http.request import QueryDict
from django.shortcuts import get_object_or_404
from django.views.generic.base import TemplateView
from django.views.generic import edit, list
from django.views.generic import detail, edit, list
from django.urls import reverse, reverse_lazy
from django.utils import timezone
@@ -31,6 +31,7 @@ __all__ = (
"PostView",
"PostSuccessView",
"PostDeleteView",
"PostWipeView",
"ReplyCreateView",
"ReportView",
)
@@ -279,6 +280,38 @@ class PostDeleteView(PermissionRequiredMixin, edit.DeleteView):
return HttpResponseRedirect(success_url)
class PostWipeView(PermissionRequiredMixin, detail.SingleObjectMixin, TemplateView):
model = Post
permission_required = ("wipe_user",)
template_name = "board/post_wipe.html"
success_url = reverse_lazy("board:post_wipe_success")
@property
def all_posts(self):
return Post.objects.filter(ip=self.object.ip)
def dispatch(self, request, *args, **kwargs):
self.object = self.get_object()
return super(PostWipeView, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
# Wipe user's posts
self.all_posts.delete()
# Success redirect
success_url = self.get_success_url()
return HttpResponseRedirect(success_url)
def get_context_data(self, **kwargs):
context = super(PostWipeView, self).get_context_data(**kwargs)
# context["all_posts"] = self.all_posts
# for some reason, {{all_posts.count}} does not seem to work in the template.
context["all_posts_count"] = self.all_posts.count()
return context
def get_success_url(self):
return self.success_url
class ReportView(CreateView):
model = Report
form_class = ReportForm