Add posting cooldown

If a user tries to post more than once in a certain amount of time, they
will be blocked from doing so until their cooldown is over. This
required a little bit of hacking to get the board and IP address set
*before* the validation checks were made, but it all appears to work.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2022-05-07 13:24:43 -07:00
parent 771dba1515
commit 3a35a35caf
3 changed files with 99 additions and 37 deletions

View File

@@ -4,6 +4,7 @@ from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView
from django.views.generic.edit import CreateView
from board.models import Post, Board
from board.forms import PostForm, ReplyForm
__all__ = ("BoardView", "PostView")
@@ -18,70 +19,77 @@ def get_client_ip(request):
return ip
class BoardView(CreateView):
class CreatePostView(CreateView):
"""
Helper class that sets a few variables for posts. This should not be used by itself.
This class sets the following variables on GET and POST:
* self.board
"""
def get(self, request, *args, **kwargs):
self._set_board(kwargs["url"])
return super(CreatePostView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self._set_board(kwargs["url"])
return super(CreatePostView, self).post(request, *args, **kwargs)
def _set_board(self, board_url: str):
board = get_object_or_404(Board, url=board_url)
self.board = board
def get_form_kwargs(self):
kwargs = super(CreatePostView, self).get_form_kwargs()
kwargs["board"] = self.board
kwargs["ip"] = get_client_ip(self.request)
return kwargs
class BoardView(CreatePostView):
model = Post
fields = ["subject", "name", "text", "image"]
form_class = PostForm
# fields = ["subject", "name", "text", "image"]
slug_field = "url"
slug_url_kwarg = "url"
template_name = "board/board_detail.html"
def get_context_data(self, **kwargs):
board_url = self.kwargs["url"]
board = get_object_or_404(Board, url=board_url)
kwargs["board"] = board
kwargs["board"] = self.board
page = self.kwargs.get("page", 1)
if page not in range(1, board.max_pages + 1):
if page not in range(1, self.board.max_pages + 1):
raise Http404()
start = (page - 1) * board.threads_per_page
end = start + board.threads_per_page
kwargs["threads"] = board.threads.order_by("-last_bump")[start:end]
start = (page - 1) * self.board.threads_per_page
end = start + self.board.threads_per_page
kwargs["threads"] = self.board.threads.order_by("-last_bump")[start:end]
kwargs["page"] = page
kwargs["max_upload_size"] = settings.MAX_UPLOAD_SIZE
return super(BoardView, self).get_context_data(**kwargs)
def form_valid(self, form):
board_url = self.kwargs["url"]
board = get_object_or_404(Board, url=board_url)
form.instance.board = board
form.instance.ip = get_client_ip(self.request)
self.object = form.save()
return HttpResponseRedirect(self.get_success_url())
class PostView(CreateView):
class PostView(CreatePostView):
model = Post
fields = ["name", "text", "image"]
# fields = ["name", "text", "image"]
form_class = ReplyForm
slug_field = "url"
slug_url_kwarg = "url"
template_name = "board/post_detail.html"
def get_context_data(self, **kwargs):
board_url = self.kwargs["url"]
kwargs["board"] = get_object_or_404(Board, url=board_url)
kwargs["board"] = self.board
post_id = self.kwargs["id"]
kwargs["post"] = get_object_or_404(Post, id=post_id)
kwargs["max_upload_size"] = settings.MAX_UPLOAD_SIZE
return super(PostView, self).get_context_data(**kwargs)
def form_valid(self, form):
board_url = self.kwargs["url"]
board = get_object_or_404(Board, url=board_url)
def get_form_kwargs(self):
kwargs = super(PostView, self).get_form_kwargs()
post_id = self.kwargs["id"]
post = get_object_or_404(Post, id=post_id)
form.instance.board = board
form.instance.ip = get_client_ip(self.request)
form.instance.op = post
form.instance.reply = post
self.object = form.save()
return HttpResponseRedirect(post.get_absolute_url())
kwargs["op"] = post
kwargs["reply"] = post
return kwargs