Fields are only displayed via the PostModifyForm if the user has specific permissions to do things, like set stickies. Also, add PostModifySuccessView that will close the modify window when the process is complete. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
338 lines
11 KiB
Python
338 lines
11 KiB
Python
from typing import Any, Dict
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model, get_user
|
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
|
from django.db.models import Q
|
|
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
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils import timezone
|
|
|
|
from guardian.shortcuts import get_objects_for_user
|
|
|
|
from board.forms import *
|
|
from board.models import Ban, BanTemplate, Board, Post, Report
|
|
from board.utils import *
|
|
|
|
__all__ = (
|
|
"BanCreateView",
|
|
"BanSuccessView",
|
|
"BannedView",
|
|
"BoardView",
|
|
"PostCreateView",
|
|
"PostModifyView",
|
|
"PostModifySuccessView",
|
|
"PostView",
|
|
"PostSuccessView",
|
|
"ReplyCreateView",
|
|
"ReportView",
|
|
"ReportSuccessView",
|
|
)
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
def can_modify(user):
|
|
if not user:
|
|
return False
|
|
# TODO add more permissions as required
|
|
return user.has_perm("board.set_sticky")
|
|
|
|
|
|
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 not ban.expires or 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(TemplateView):
|
|
model = Board
|
|
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 dispatch(self, request, *args, **kwargs):
|
|
self.board = get_object_or_404(Board, url=kwargs["url"])
|
|
return super(BoardView, self).dispatch(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("-sticky", "-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
|
|
kwargs["can_modify"] = can_modify(self.request.user)
|
|
|
|
return super(BoardView, self).get_context_data(**kwargs)
|
|
|
|
|
|
class PostCreateView(CreateView):
|
|
model = Post
|
|
form_class = PostForm
|
|
slug_field = "url"
|
|
slug_url_kwarg = "url"
|
|
template_name = "board/post_create_view.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["board"] = self.board
|
|
context["max_upload_size"] = settings.MAX_UPLOAD_SIZE
|
|
context["capcodes"] = get_objects_for_user(
|
|
get_user(self.request), "board.use_capcode"
|
|
)
|
|
kwargs["can_modify"] = can_modify(self.request.user)
|
|
return context
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(PostCreateView, self).get_form_kwargs()
|
|
kwargs["user"] = self.request.user
|
|
return kwargs
|
|
|
|
def get_success_url(self) -> str:
|
|
query = QueryDict(mutable=True)
|
|
query["next"] = self.get_form().instance.get_absolute_url()
|
|
return reverse("board:post_success") + "?" + query.urlencode()
|
|
|
|
|
|
class PostModifyView(PermissionRequiredMixin, edit.UpdateView):
|
|
model = Post
|
|
form_class = PostModifyForm
|
|
template_name = "board/post_modify_view.html"
|
|
success_url = reverse_lazy("board:post_modify_success")
|
|
|
|
def has_permission(self) -> bool:
|
|
return can_modify(self.request.user)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
self.post_obj = get_object_or_404(Post, id=kwargs["pk"])
|
|
self.board = self.post_obj.board
|
|
return super(PostModifyView, self).dispatch(request, *args, **kwargs)
|
|
|
|
def get_form_kwargs(self) -> Dict[str, Any]:
|
|
kwargs = super(PostModifyView, self).get_form_kwargs()
|
|
kwargs["user"] = self.request.user
|
|
return kwargs
|
|
|
|
|
|
class PostModifySuccessView(PermissionRequiredMixin, TemplateView):
|
|
template_name = "board/post_modify_success.html"
|
|
|
|
def has_permission(self) -> bool:
|
|
return can_modify(self.request.user)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["window_timeout"] = settings.BAN_WINDOW_CLOSE_TIMEOUT
|
|
context["can_modify"] = self.has_permission()
|
|
return context
|
|
|
|
|
|
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
|
|
context["capcodes"] = get_objects_for_user(
|
|
get_user(self.request), "board.use_capcode"
|
|
)
|
|
kwargs["can_modify"] = can_modify(self.request.user)
|
|
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["user"] = self.request.user
|
|
return kwargs
|
|
|
|
def get_success_url(self) -> str:
|
|
query = QueryDict(mutable=True)
|
|
query["next"] = self.get_form().instance.get_absolute_url()
|
|
return reverse("board:post_success") + "?" + query.urlencode()
|
|
|
|
|
|
class PostView(TemplateView):
|
|
model = Post
|
|
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 dispatch(self, request, *args, **kwargs):
|
|
# Set the board on this object
|
|
self.board = get_object_or_404(Board, url=kwargs["url"])
|
|
return super(PostView, self).dispatch(request, *args, **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 = "board.add_ban"
|
|
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 and ban.expires < now
|
|
]
|
|
context["current_bans"] = [
|
|
ban for ban in bans if not ban.expires 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
|