Add report record admin and template search

When creating a ban, you can type in to do a search, this is useful for
quickly banning users.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2022-06-23 18:16:00 -07:00
parent 789bd0efe9
commit b64559aba9
4 changed files with 88 additions and 15 deletions

View File

@@ -1,10 +1,15 @@
from django import forms
from django.contrib import admin
from django.http.response import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.utils.safestring import mark_safe
from board.models import Ban, Board, Post, RangeBan, ReportReason, ReportRecord
from board.models import (
Ban,
BanTemplate,
Board,
Post,
RangeBan,
ReportReason,
ReportRecord,
)
#
# Admin sites
@@ -24,10 +29,6 @@ class ReportReasonAdmin(admin.ModelAdmin):
pass
class BanFromReportForm(forms.ModelForm):
pass
@admin.register(ReportRecord)
class ReportRecordAdmin(admin.ModelAdmin):
ordering = (
@@ -76,3 +77,8 @@ class RangeBanAdmin(admin.ModelAdmin):
@admin.register(Ban)
class BanAdmin(admin.ModelAdmin):
pass
@admin.register(BanTemplate)
class BanTemplateAdmin(admin.ModelAdmin):
ordering = ("board__url", "name")

View File

@@ -311,11 +311,21 @@ class Ban(BanCommon):
class BanTemplate(models.Model):
# The name of this template
name = models.CharField(max_length=100)
# The reason for this ban
ban_reason = models.TextField(blank=False)
# The duration of the ban
duration = models.DurationField()
# The duration of the ban, in days
duration = models.IntegerField(blank=True, null=True)
# The board that this template is for, or none.
board = models.ForeignKey("Board", on_delete=models.CASCADE, null=True, blank=True)
def create_ban(self, ip: str) -> Ban:
expires = timezone.now() + self.duration
return Ban.objects.create(ip=ip, ban_reason=self.ban_reason, expires=expires)
def __str__(self) -> str:
if self.board:
return f"/{self.board.url}/ - {self.name}"
else:
return self.name

View File

@@ -2,7 +2,7 @@
{% load i18n %}
{% block content %}
<form id="form" action="{% url 'board:ban_create' url=board.url id=post.id %}" method="post">
<form id="form" action="{% url 'board:ban_create' url=board.url id=post.id %}" method="post" autocomplete="off">
{% csrf_token %}
<table>
<tr>
@@ -17,13 +17,28 @@
<th>IP:</th>
<td>{{post.ip}}</td>
</tr>
<tr>
<th>{% translate 'Template search' %}:</th>
<td><input id="template_search" type="text" /></td>
</tr>
<tr>
<th>{% translate 'Template' %}</th>
<td>
<select id="templates">
<option class="template_option" data-reason="" data-duration="">Custom</option>
{% for template in templates %}
<option class="template_option" data-reason="{{template.ban_reason}}" data-duration="{{template.duration}}">{{template.name}}</option>
{% endfor %}
</select>
</td>
</tr>
{{form.as_table}}
<tr>
<th>{% translate "Previous bans" %}</th>
<th>{% translate "Previous bans" %}:</th>
<td>{{previous_bans|length}}</td>
</tr>
<tr>
<th>{% translate "Current bans" %}</th>
<th>{% translate "Current bans" %}:</th>
<td id="current_bans">{{current_bans|length}}</td>
</tr>
<tr>
@@ -35,7 +50,6 @@
<script>
function submitConfirm(e) {
console.log($("#current_bans").text());
if($("#current_bans").text() !== '0') {
let result = window.confirm("There is already at least one ban for this IP address on this board, are you sure you want to continue?");
if (!result) {
@@ -45,6 +59,45 @@ function submitConfirm(e) {
}
}
function templateSelect(e) {
let selected = $($(e.target).find(":selected"));
// uh oh, mixing django templates and JS
let banReason = $("#{{form.ban_reason.auto_id}}");
let duration = $("#{{form.duration.auto_id}}");
banReason.val(selected.attr("data-reason"));
duration.val(selected.attr("data-duration"));
if(selected.val() === "Custom") {
// unlock the controls
banReason.attr("readonly", false);
duration.attr("readonly", false);
} else {
// lock all controls
banReason.attr("readonly", true);
duration.attr("readonly", true);
}
}
function templateSearch(e) {
let search = $(e.target).val();
let element = $("#templates option").toArray().find(element => {
let re = new RegExp(search, "i");
return element.value.search(re) !== -1;
});
if(typeof element === "undefined") {
return;
}
$("#templates")
.val(element.value)
.trigger("change");
}
$("#submit").on("click", submitConfirm);
$("#templates").on("change", templateSelect);
$("#template_search").on("input propertychange paste", templateSearch);
$("#template_search").select();
</script>
{% endblock content %}

View File

@@ -1,6 +1,7 @@
from typing import Any, Dict
from django.conf import settings
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.db.models import Q
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.views.generic.base import TemplateView
@@ -8,7 +9,7 @@ from django.views.generic.edit import CreateView
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from board.forms import BanForm, PostForm, ReplyForm, ReportForm
from board.models import Ban, Board, Post, Report
from board.models import Ban, BanTemplate, Board, Post, Report
from board.utils import get_client_ip, get_ip_bans
__all__ = (
@@ -186,6 +187,9 @@ class BanCreateView(PermissionRequiredMixin, CreateView):
context["current_bans"] = [
ban for ban in bans if ban.expires is None or ban.expires > now
]
context["templates"] = BanTemplate.objects.filter(
Q(board=self.board) | Q(board=None)
)
return context