2025.09.17-19:07:57

This commit is contained in:
2025-09-17 19:07:58 +02:00
parent ff37c9cd8b
commit 38a85cb9d5
47 changed files with 1530 additions and 38 deletions

View File

@@ -0,0 +1,2 @@
from .home import *
from .page import *

43
tinywiki/views/base.py Normal file
View File

@@ -0,0 +1,43 @@
from .. import settings
from django.views import View as DjangoView
from django.views.generic import FormView as DjangoFormView
from typing import Any
class Base:
base_template_name = settings.TINYWIKI_BASE_TEMPLATE
@classmethod
def get_base_template_name(cls)->str:
return cls.base_template_name
@classmethod
def get_template_name(cls)->str:
return cls.template_name
def get_tinywiki_context_data(self):
create_pages = False
if self.request.user.is_authenticated:
if self.request.user.is_staff or self.request.user.has_perm('tinywiki.tinywiki-create'):
create_pages = True
return {
'brand_logo': settings.TINYWIKI_BRAND_LOGO,
'brand_name': settings.TINYWIKI_BRAND_NAME,
'base_template': self.get_base_template_name(),
'use_bootstrap': settings.USE_BOOTSTRAP,
'user_can_create_wiki_pages':create_pages
}
class View(Base,DjangoView):
template_name = "tinywiki"
def get_context_data(self,**kwargs):
context = self.get_tinywiki_context_data()
context.update(kwargs)
return context
class FormView(Base,DjangoFormView):
def get_context_data(self, **kwargs) -> dict[str, Any]:
context = self.get_tinywiki_context_data()
context.update(kwargs)
return super().get_context_data(**context)

94
tinywiki/views/home.py Normal file
View File

@@ -0,0 +1,94 @@
from curses.ascii import isalpha
from django.shortcuts import render
from tinywiki import settings
from .base import View
from django.http import HttpRequest,HttpResponse
from django.db.models.functions import Lower
import string
from ..models import Page
from ..enums import WikiPageStatus
from django.utils.translation import ngettext, gettext as _
# Create your views here.
class HomeView(View):
template_name = "tinywiki/home/home.html"
def get(self,request):
try:
page = Page.objects.get(slug='tw-home')
except Page.DoesNotExist:
page = None
return render(request,
self.get_template_name(),
self.get_context_data(page=page))
class TocView(View):
template_name = "tinywiki/home/wiki-content.html"
bs_template_name = "tinywiki/home/bs-wiki-content.html"
@classmethod
def get_template_name(cls):
if settings.USE_BOOTSTRAP:
return cls.bs_template_name
return cls.template_name
def get(self,request):
def mkdict(page:Page):
return {'slug':page.slug,'title':page.title, 'is_system':page.slug.startswith('tw-')}
user = self.request.user
if (user.is_staff or user.has_perm('page.read_all')):
pages = Page.objects.all()
else:
pages = Page.objects.filter(status_data=WikiPageStatus.PUBLISHED.value)
toc_mapping = {}
for page in pages:
first_char = page.title.lstrip()[0].upper()
if first_char.isdigit():
if '0-9' not in toc_mapping:
toc_mapping['0-9'] = [mkdict(page)]
else:
toc_mapping['0-9'].append(mkdict(page))
elif first_char in string.punctuation:
if '#' not in toc_mapping:
toc_mapping['#'] = [mkdict(page)]
else:
toc_mapping['#'].append(mkdict(page))
else:
if first_char not in toc_mapping:
toc_mapping[first_char] = [mkdict(page)]
else:
toc_mapping[first_char].append(mkdict(page))
toc = []
for key in sorted(toc_mapping.keys()):
toc_entries = toc_mapping[key]
count = len(toc_mapping[key])
split = (count + 1) // 2
pages_0 = toc_entries[:split]
if split >= count:
pages_1 = []
else:
pages_1 = toc_entries[split:]
if (key.startswith('0') or key == '#'):
toc_section = key
else:
toc_section = f"{key}..."
toc_section = ngettext("{toc_section} ({n} page)","{toc_section} ({n} pages)", count).format(
toc_section=toc_section,
n=count,
)
toc.append((toc_section,pages_0,pages_1))
return render(request,
self.get_template_name(),
self.get_context_data(toc=toc,subtitle=_("Table of Contents")))

261
tinywiki/views/page.py Normal file
View File

@@ -0,0 +1,261 @@
from django.shortcuts import render,get_object_or_404,redirect
from django.urls import reverse, reverse_lazy
from django.http import HttpRequest,HttpResponse
from django.contrib.auth.mixins import LoginRequiredMixin,UserPassesTestMixin
from django.core.exceptions import PermissionDenied
from django.utils.translation import gettext as _
from .. import settings
from ..models import Page
from .base import View,FormView
from ..forms import PageForm,PageAdminForm
class PageView(View):
template_name = "tinywiki/page/view.html"
bs_template_name = "tinywiki/page/bs-view.html"
@classmethod
def get_template_name(cls) -> str:
if settings.USE_BOOTSTRAP:
return cls.bs_template_name
return cls.template_name
def get_context_data(self,page,**kwargs):
can_edit_page = False
can_delete_page = False
user = self.request.user
if (user.is_staff):
can_edit_page = True
can_delete_page = True
elif page.slug.startswith('tw-'):
if user.has_perm('page.tinywiki-edit-system'):
can_edit_page = True
if user.has_perm('page.tinywiki-delete-system'):
can_delete_page = True
else:
if (user.has_perm('page.tinywiki-edit-all')
or (user.pk == page.author.pk and user.has_perm('page.tinywiki-edit'))):
can_edit_page = True
if (user.has_perm('page.tinywiki-delete-all')
or (user.pk == page.author.pk and user.has_perm('page.tinywiki-delete'))):
can_delete_page = True
kwargs.update({'page':page,
'user_can_edit_wiki_page':can_edit_page,
'user_can_delete_wiki_page':can_delete_page,
'subtitle':page.title})
return super().get_context_data(**kwargs)
def get(self,request:HttpRequest,slug:str)->HttpResponse:
page = get_object_or_404(Page,slug=slug)
return render(request,
self.get_template_name(),
self.get_context_data(page=page))
class PageCreateView(LoginRequiredMixin,UserPassesTestMixin,FormView):
template_name = "tinywiki/page/create.html"
form_class = PageForm
def test_func(self) -> bool:
if self.request.user.is_authenticated:
if self.request.user.is_staff:
return True
return self.request.user.has_perm('tinywiki.tinywiki-create')
return False
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['create']=True
context.setdefault("title_extra","")
context.setdefault("slug_extra","")
context.setdefault("content_type_extra","")
context.setdefault("status_extra","")
context.setdefault("content_extra","")
return context
def form_invalid(self, form):
if 'slug' in form.errors:
slug_extra = "is-invalid"
else:
slug_extra = "is-valid"
if 'title' in form.errors:
title_extra = 'is-invalid'
else:
title_extra = 'is-valid'
if 'status_data' in form.errors:
status_extra = 'is-invalid'
else:
status_extra = 'is-valid'
if 'content_type_data' in form.errors:
content_type_extra = 'is-invalid'
else:
content_type_extra = 'is-valid'
if 'content' in form.errors:
content_extra = 'is-invalid'
else:
content_extra = 'is-valid'
return render(self.request,
self.get_template_name(),
self.get_context_data(
slug_extra=slug_extra,
title_extra=title_extra,
status_extra=status_extra,
content_type_extra=content_type_extra,
content_extra=content_extra,
))
def form_valid(self,form):
user = self.request.user
instance = form.save(commit=False)
if (instance.slug.startswith('tw-')
and not user.is_staff and
not user.has_perm('page.tinywiki-create-system')):
return render(self.request,
self.get_template_name(),
self.get_context_data(
slug_extra="is-invalid",
title_extra="is-valid",
status_extra="is-valid",
content_type_extra="is-valid",
content_extra="is-valid",
))
instance.author = user
instance.created_by = user
instance.last_edited_by = user
try:
form.save(commit=True)
if self.request.GET.get('save',"0") == "1":
return redirect(reverse("tinywiki:page-edit",kwargs={"slug":instance.slug}))
return redirect(reverse("tinywiki:page",kwargs={'slug':instance.slug}))
except:
return render(self.request,
self.get_template_name(),
self.get_context_data(
slug_extra="is-invalid",
title_extra="is-valid",
status_extra="is-valid",
content_type_extra="is-valid",
content_extra="is-valid",
))
class PageEditView(LoginRequiredMixin,UserPassesTestMixin,FormView):
template_name = "tinywiki/page/edit.html"
form_class = PageForm
def test_func(self) -> bool:
if self.request.user.is_authenticated:
if self.request.user.is_staff:
return True
return False
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['create']=False
context.setdefault("title_extra","")
context.setdefault("slug_extra","")
context.setdefault("content_type_extra","")
context.setdefault("status_extra","")
context.setdefault("content_extra","")
return context
def form_invalid(self, form):
if 'slug' in form.errors:
slug_extra = "is-invalid"
else:
slug_extra = "is-valid"
if 'title' in form.errors:
title_extra = 'is-invalid'
else:
title_extra = 'is-valid'
if 'status_data' in form.errors:
status_extra = 'is-invalid'
else:
status_extra = 'is-valid'
if 'content_type_data' in form.errors:
content_type_extra = 'is-invalid'
else:
content_type_extra = 'is-valid'
if 'content' in form.errors:
content_extra = 'is-invalid'
else:
content_extra = 'is-valid'
return render(self.request,
self.get_template_name(),
self.get_context_data(
slug_extra=slug_extra,
title_extra=title_extra,
status_extra=status_extra,
content_type_extra=content_type_extra,
content_extra=content_extra,
))
def get(self,request,slug:str):
instance = get_object_or_404(Page,slug=slug)
user = request.user
if (instance.slug.startswith('tw-')
and not user.is_staff
and not user.has_perm('page.tinywiki-edit-system')):
raise PermissionDenied(_("Only staff users and wiki-admins are allowed to edit TinyWiki system pages!"))
if user.pk != instance.author.pk:
if not user.is_staff and not user.has_perm("page.tinywiki-edit-all"):
raise PermissionDenied()
else:
if not user.has_perm('page.tinywiki-edit-all') or not user.has_perm('page.tinywiki-edit'):
raise PermissionDenied()
self.instance = instance
return super().get(request)
def post(self,request,slug:str):
instance = get_object_or_404(Page,slug=slug)
user = request.user
if (instance.slug.startswith('tw-') and not user.is_staff):
raise PermissionDenied(_("Only staff users are allowed to edit TinyWiki system pages!"))
if user.pk != instance.author.pk:
if not user.is_staff and not user.has_perm("page.tinywiki-edit-all"):
raise PermissionDenied()
else:
if not user.has_perm('page.tinywiki-edit-all') or not user.has_perm('page.tinywiki-edit'):
raise PermissionDenied()
self.instance = instance
return super().post(request)
def get_form(self):
return self.get_form_class()(instance=self.instance,**self.get_form_kwargs())
def form_valid(self,form):
user = self.request.user
instance = form.save(commit=False)
instance.created_by = user
instance.last_edited_by = user
try:
form.save(commit=True)
if self.request.GET.get('save',"0") == "1":
return redirect(reverse("tinywiki:page-edit",kwargs={"slug":instance.slug}))
return redirect(reverse("tinywiki:page",kwargs={'slug':instance.slug}))
except:
return render(self.request,
self.get_template_name(),
self.get_context_data(slug_invalid=True))
class PageDeleteView(View):
template_name = "tinywiki/page/delete"
def get(self,request,slug):
return render()