mirror of
https://github.com/ae-utbm/sith.git
synced 2025-11-15 17:09:21 +00:00
196 lines
6.1 KiB
Python
196 lines
6.1 KiB
Python
#
|
|
# Copyright 2023 © AE UTBM
|
|
# ae@utbm.fr / ae.info@utbm.fr
|
|
#
|
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
|
# https://ae.utbm.fr.
|
|
#
|
|
# You can find the source code of the website at https://github.com/ae-utbm/sith
|
|
#
|
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
|
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
|
#
|
|
#
|
|
|
|
from django.contrib.auth.mixins import PermissionRequiredMixin, UserPassesTestMixin
|
|
from django.db.models import F, OuterRef, Subquery
|
|
from django.db.models.functions import Coalesce
|
|
from django.http import Http404
|
|
from django.shortcuts import get_object_or_404, redirect
|
|
from django.urls import reverse_lazy
|
|
from django.utils.functional import cached_property
|
|
from django.views.generic import DetailView, ListView
|
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
|
|
|
from core.auth.mixins import CanEditPropMixin, CanViewMixin
|
|
from core.models import Page, PageRev
|
|
from core.views.forms import PageForm, PagePropForm, PageRevisionForm
|
|
|
|
|
|
class PageNotFound(Http404):
|
|
"""Http404 Exception, but specifically for when the not found object is a Page."""
|
|
|
|
def __init__(self, page_name: str):
|
|
self.page_name = page_name
|
|
|
|
|
|
def get_page_or_404(full_name: str) -> Page:
|
|
"""Like Django's get_object_or_404, but for Page, and with a custom 404 exception."""
|
|
page = Page.objects.filter(_full_name=full_name).first()
|
|
if not page:
|
|
raise PageNotFound(full_name)
|
|
return page
|
|
|
|
|
|
class PageListView(ListView):
|
|
model = Page
|
|
template_name = "core/page/list.jinja"
|
|
|
|
def get_queryset(self):
|
|
return (
|
|
Page.objects.viewable_by(self.request.user)
|
|
.annotate(
|
|
display_name=Coalesce(
|
|
Subquery(
|
|
PageRev.objects.filter(page=OuterRef("id"))
|
|
.order_by("-date")
|
|
.values("title")[:1]
|
|
),
|
|
F("name"),
|
|
)
|
|
)
|
|
.select_related("parent")
|
|
)
|
|
|
|
|
|
class BasePageDetailView(CanViewMixin, DetailView):
|
|
model = Page
|
|
slug_url_kwarg = "page_name"
|
|
_cached_object: Page | None = None
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
page = self.get_object()
|
|
if page.need_club_redirection:
|
|
return redirect("club:club_view", club_id=page.club.id)
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
if not self._cached_object:
|
|
full_name = self.kwargs.get(self.slug_url_kwarg)
|
|
self._cached_object = get_page_or_404(full_name)
|
|
return self._cached_object
|
|
|
|
def get_context_data(self, **kwargs):
|
|
return super().get_context_data(**kwargs) | {
|
|
"last_revision": self.object.revisions.last()
|
|
}
|
|
|
|
|
|
class PageView(BasePageDetailView):
|
|
template_name = "core/page/detail.jinja"
|
|
|
|
|
|
class PageHistView(BasePageDetailView):
|
|
template_name = "core/page/history.jinja"
|
|
|
|
|
|
class PageRevView(BasePageDetailView):
|
|
template_name = "core/page/detail.jinja"
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
page = self.get_object()
|
|
if page.need_club_redirection:
|
|
return redirect(
|
|
"club:club_view_rev", club_id=page.club.id, rev_id=kwargs["rev"]
|
|
)
|
|
self.revision = get_object_or_404(page.revisions, id=self.kwargs["rev"])
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
return super().get_context_data(**kwargs) | {"revision": self.revision}
|
|
|
|
|
|
class PageCreateView(PermissionRequiredMixin, CreateView):
|
|
model = Page
|
|
form_class = PageForm
|
|
template_name = "core/create.jinja"
|
|
permission_required = "core.add_page"
|
|
|
|
def get_initial(self):
|
|
init = super().get_initial()
|
|
if "page" not in self.request.GET:
|
|
return init
|
|
page_name = self.request.GET["page"].rsplit("/", maxsplit=1)
|
|
if len(page_name) == 2:
|
|
parent = Page.get_page_by_full_name(page_name[0])
|
|
if parent is not None:
|
|
init["parent"] = parent.id
|
|
init["name"] = page_name[-1]
|
|
return init
|
|
|
|
def form_valid(self, form):
|
|
form.instance.set_lock(self.request.user)
|
|
ret = super().form_valid(form)
|
|
return ret
|
|
|
|
|
|
class CanEditPagePropMixin(CanEditPropMixin):
|
|
def dispatch(self, request, *args, **kwargs):
|
|
res = super().dispatch(request, *args, **kwargs)
|
|
if self.object.is_club_page:
|
|
raise Http404
|
|
return res
|
|
|
|
|
|
class PagePropView(CanEditPagePropMixin, UpdateView):
|
|
model = Page
|
|
form_class = PagePropForm
|
|
template_name = "core/page/prop.jinja"
|
|
|
|
def get_object(self, queryset=None):
|
|
self.page = get_page_or_404(full_name=self.kwargs["page_name"])
|
|
self.page.set_lock_recursive(self.request.user)
|
|
return self.page
|
|
|
|
|
|
class BasePageEditView(UserPassesTestMixin, UpdateView):
|
|
model = PageRev
|
|
form_class = PageRevisionForm
|
|
template_name = "core/page/edit.jinja"
|
|
|
|
def test_func(self):
|
|
return self.request.user.can_edit(self.page)
|
|
|
|
@cached_property
|
|
def page(self) -> Page:
|
|
page = get_page_or_404(full_name=self.kwargs["page_name"])
|
|
page.set_lock(self.request.user)
|
|
return page
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
return self.page.revisions.last()
|
|
|
|
def get_context_data(self, **kwargs):
|
|
return super().get_context_data(**kwargs) | {"page": self.page}
|
|
|
|
def get_form_kwargs(self):
|
|
return super().get_form_kwargs() | {
|
|
"author": self.request.user,
|
|
"page": self.page,
|
|
}
|
|
|
|
|
|
class PageEditView(BasePageEditView):
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if self.page.need_club_redirection:
|
|
return redirect("club:club_edit_page", club_id=self.page.club.id)
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class PageDeleteView(CanEditPagePropMixin, DeleteView):
|
|
model = Page
|
|
template_name = "core/delete_confirm.jinja"
|
|
pk_url_kwarg = "page_id"
|
|
success_url = reverse_lazy("core:page_list")
|