Files
interchan/board/views.py
Alek Ratzloff e596d59e82 Trying out JSFrame for windows
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>
2022-06-25 20:42:10 -07:00

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