Winbox has this annoying bug where you can't move the window below the calculated area of the document, so you can't drag it over blank space. JSFrame fixes this and does basically what we want as well. This has been implemented for post replies and I am going to implement it for reports and ban creation too. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
250 lines
7.8 KiB
Python
250 lines
7.8 KiB
Python
from typing import Any, Dict
|
|
from django.conf import settings
|
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
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
|
|
from django.views.generic import edit
|
|
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, BanTemplate, Board, Post, Report
|
|
from board.utils import *
|
|
|
|
__all__ = (
|
|
"BanCreateView",
|
|
"BanSuccessView",
|
|
"BannedView",
|
|
"BoardView",
|
|
"PostView",
|
|
"PostSuccessView",
|
|
"ReplyCreateView",
|
|
"ReportView",
|
|
"ReportSuccessView",
|
|
)
|
|
|
|
|
|
class BannedView(TemplateView):
|
|
template_name = "board/banned.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TemplateView, self).get_context_data(**kwargs)
|
|
ip = get_client_ip(self.request)
|
|
bans = get_ip_bans(ip)
|
|
|
|
now = timezone.now()
|
|
active_bans = [ban for ban in bans if ban.expires > now]
|
|
context["bans"] = bans
|
|
context["active_bans"] = active_bans
|
|
context["ip"] = ip
|
|
|
|
return context
|
|
|
|
|
|
class CreateView(edit.CreateView):
|
|
"""
|
|
Helper class that sets a few variables for posts and check against bans.
|
|
This should not be used by itself.
|
|
|
|
This class sets the following variables on GET and POST:
|
|
* self.board
|
|
"""
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(CreateView, self).get_form_kwargs()
|
|
kwargs["board"] = self.board
|
|
kwargs["ip"] = get_client_ip(self.request)
|
|
return kwargs
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
# Set the board on this object
|
|
self.board = get_object_or_404(Board, url=kwargs["url"])
|
|
|
|
# Check for bans
|
|
ip = get_client_ip(request)
|
|
if request.method == "POST" and is_banned(ip, self.board):
|
|
return HttpResponseRedirect(reverse("board:banned"))
|
|
else:
|
|
return super(CreateView, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class BoardView(CreateView):
|
|
model = Post
|
|
form_class = PostForm
|
|
slug_field = "url"
|
|
slug_url_kwarg = "url"
|
|
template_name = "board/board_detail.html"
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
# If the page isn't set, then redirect to the /page/1 url
|
|
if "page" not in kwargs:
|
|
return HttpResponseRedirect(
|
|
reverse("board:board_detail", kwargs={"url": kwargs["url"], "page": 1})
|
|
)
|
|
return super(BoardView, self).get(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
page = self.kwargs["page"]
|
|
|
|
if page not in range(1, self.board.max_pages + 1):
|
|
raise Http404()
|
|
|
|
threads_per_page = self.board.threads_per_page
|
|
start = (page - 1) * threads_per_page
|
|
end = start + threads_per_page
|
|
thread_count = self.board.threads.count()
|
|
last_page = (thread_count // threads_per_page) + 1
|
|
|
|
kwargs["board"] = self.board
|
|
kwargs["threads"] = self.board.threads.order_by("-last_bump")[start:end]
|
|
kwargs["current_page"] = page
|
|
kwargs["pages"] = range(1, last_page + 1)
|
|
kwargs["last_page"] = last_page
|
|
kwargs["max_upload_size"] = settings.MAX_UPLOAD_SIZE
|
|
|
|
return super(BoardView, self).get_context_data(**kwargs)
|
|
|
|
|
|
class ReplyCreateView(CreateView):
|
|
model = Post
|
|
form_class = ReplyForm
|
|
slug_field = "url"
|
|
slug_url_kwarg = "url"
|
|
template_name = "board/reply_create_view.html"
|
|
success_url = reverse_lazy("board:post_success")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["board"] = self.board
|
|
post_id = self.kwargs["id"]
|
|
context["post"] = get_object_or_404(Post, id=post_id)
|
|
context["max_upload_size"] = settings.MAX_UPLOAD_SIZE
|
|
print(context["board"])
|
|
return context
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(ReplyCreateView, self).get_form_kwargs()
|
|
post_id = self.kwargs["id"]
|
|
post = get_object_or_404(Post, id=post_id)
|
|
kwargs["op"] = post
|
|
kwargs["reply"] = post
|
|
return kwargs
|
|
|
|
|
|
class PostView(CreateView):
|
|
model = Post
|
|
form_class = ReplyForm
|
|
slug_field = "url"
|
|
slug_url_kwarg = "url"
|
|
|
|
template_name = "board/post_detail.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
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 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)
|
|
kwargs["op"] = post
|
|
kwargs["reply"] = post
|
|
return kwargs
|
|
|
|
|
|
class PostSuccessView(TemplateView):
|
|
template_name = "board/post_success.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["window_timeout"] = settings.POST_WINDOW_CLOSE_TIMEOUT
|
|
return context
|
|
|
|
|
|
class ReportView(CreateView):
|
|
model = Report
|
|
form_class = ReportForm
|
|
success_url = reverse_lazy("board:report_success")
|
|
|
|
@property
|
|
def board_url(self) -> str:
|
|
return self.kwargs["url"]
|
|
|
|
@property
|
|
def post_id(self) -> int:
|
|
return self.kwargs["id"]
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(ReportView, self).get_form_kwargs()
|
|
post_id = self.kwargs["id"]
|
|
post = get_object_or_404(Post, id=post_id)
|
|
kwargs["op"] = post
|
|
return kwargs
|
|
|
|
|
|
class ReportSuccessView(TemplateView):
|
|
template_name = "board/report_success.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["window_timeout"] = settings.REPORT_WINDOW_CLOSE_TIMEOUT
|
|
return context
|
|
|
|
|
|
class BanCreateView(PermissionRequiredMixin, edit.CreateView):
|
|
model = Ban
|
|
form_class = BanForm
|
|
permission_required = "ban.create"
|
|
success_url = reverse_lazy("board:ban_success")
|
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
context = super().get_context_data(**kwargs)
|
|
context["board"] = self.board
|
|
context["post"] = self.post_obj
|
|
ip = self.post_obj.ip
|
|
now = timezone.now()
|
|
bans = [
|
|
ban
|
|
for ban in get_ip_bans(ip)
|
|
if ban.board == self.board or ban.board is None
|
|
]
|
|
context["previous_bans"] = [
|
|
ban for ban in bans if ban.expires is not None and ban.expires < now
|
|
]
|
|
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
|
|
|
|
def get_form_kwargs(self) -> Dict[str, Any]:
|
|
kwargs = super(edit.CreateView, self).get_form_kwargs()
|
|
post_id = self.kwargs["id"]
|
|
post = get_object_or_404(Post, id=post_id)
|
|
kwargs["op"] = post
|
|
return kwargs
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
self.board = get_object_or_404(Board, url=kwargs["url"])
|
|
self.post_obj = get_object_or_404(Post, pk=kwargs["id"])
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class BanSuccessView(PermissionRequiredMixin, TemplateView):
|
|
permission_required = "ban.create"
|
|
template_name = "board/ban_success.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["window_timeout"] = settings.BAN_WINDOW_CLOSE_TIMEOUT
|
|
return context
|