Files
kasu/src/content/views.py
Xeniac f3d44b743b recalculating only the new hanchans shoud do the trick now.
the racalc cronjob reports erronous partly recalculations now.
A lot of code cleanups
2017-11-01 09:53:52 +01:00

310 lines
9.9 KiB
Python

import os
import django_comments as comments
from csp.decorators import csp_update
from django.conf import settings
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import HttpResponse, Http404
from django.utils.translation import ugettext as _
from django.views import generic
from . import models, forms
class WYSIWYGEditorMixin(PermissionRequiredMixin):
"""
A view to update the Content-Security-Policy for the WYSIWYG editor.
Since it is only used in edit forms, it extends the PermissionRequiredMixin.
"""
@csp_update(SCRIPT_SRC="'unsafe-eval'")
def dispatch(self, request, *args, **kwargs):
"""Add "unsafe-eval" to the Content-Secuirty-Policy HTTP Headers for the
WYSIWYG Editor.
:param request: the HTTP Request Object
:param args: args for the super dispatch
:param kwargs: kwargs for the super dispatch
:return: django HTTPResponse object
"""
return super(WYSIWYGEditorMixin, self).dispatch(
request, *args, **kwargs)
class ArticleArchiveMixin(object):
"""Mixin to add common context data to Views of the news archive."""
category = None
def get_category(self, queryset):
"""
Filter the queryset by category if one has been specified in the URL
:param queryset: an model.Article.objects Queryset
:return: an model.Article.objects Queryset filterd by category
"""
category_slug = self.kwargs.get('category')
if not category_slug:
self.category = None
return queryset
try:
self.category = models.Category.objects.get(slug=category_slug)
except models.Category.DoesNotExist:
raise Http404(_("This Category does not exist."))
return queryset.filter(category=self.category)
def get_context_data(self, **kwargs):
"""
Adds the categories and the active category to the template context.
:return: an django.template.context
"""
context = super(ArticleArchiveMixin, self).get_context_data(**kwargs)
context['categories'] = models.Category.objects.all()
context['active_category'] = self.category
return context
class ArticleArchiveIndex(ArticleArchiveMixin, generic.ArchiveIndexView):
"""
Displays the latest news and the filters to browse the archives.
"""
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
paginate_by = 5
context_object_name = 'article_list'
allow_empty = True
def get_queryset(self):
"""
Filter the Queryset by category.
:return: models.Article.objects queryset
"""
return self.get_category(
super(ArticleArchiveIndex, self).get_queryset()
)
class ArticleYearArchive(ArticleArchiveMixin, generic.YearArchiveView):
"""
Displays the Articles filterd by a specific year
"""
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
paginate_by = 5
year_format = '%Y'
make_object_list = True
allow_empty = True
def get_queryset(self):
"""
Filter the Queryset by category.
:return: models.Article.objects queryset
"""
return self.get_category(
super(ArticleYearArchive, self).get_queryset()
)
class ArticleMonthArchive(ArticleArchiveMixin, generic.MonthArchiveView):
"""
Displays the Articles filterd by a specific month
"""
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
month_format = '%m'
paginate_by = 5
make_object_list = True
allow_empty = True
def get_queryset(self):
"""
Filter the Queryset by category.
:return: models.Article.objects queryset
"""
return self.get_category(
super(ArticleMonthArchive, self).get_queryset()
)
class ArticleDetail(generic.DetailView):
"""
Render the news Article, but only if it got published.
"""
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
class ArticleForm(WYSIWYGEditorMixin, generic.UpdateView):
"""
View to add or edit an Article
"""
model = models.Article
form_class = forms.ArticleForm
permission_required = 'content.change_article'
def get_context_data(self, **kwargs):
"""Set the title variable to create/or edit article."""
context = super(ArticleForm, self).get_context_data(**kwargs)
context['title'] = _("Edit Article") if self.kwargs.get('pk') else \
_("Create Article")
return context
def get_object(self, queryset=None):
"""Get the Article or create a new one if no id has been provided.
:param queryset: Get the single item from this filtered queryset.
:return:
"""
queryset = queryset or self.get_queryset()
if self.kwargs.get('pk'):
return queryset.get(pk=self.kwargs['pk'])
return models.Article(author=self.request.user)
class PageAddForm(WYSIWYGEditorMixin, generic.CreateView):
""" Renders an Form to create a new page for users with conforming
permissions."""
form_class = forms.PageForm
template_name = 'content/page_form.html'
permission_required = 'content.add_page'
def get_initial(self):
"""Try to get the path of the parent page as initial data."""
path = os.path.splitext(self.kwargs['path'])[0]
if path.startswith('/'):
path = path[1:]
if path.endswith('/'):
path = path[:-1]
parent = models.Page.objects.get(path=path)
return {'parent': parent}
class PageEditForm(WYSIWYGEditorMixin, generic.UpdateView):
"""Renders an Form to edit a page for users with conforming permissions."""
form_class = forms.PageForm
model = models.Page
permission_required = 'content.change_page'
def get_object(self, queryset=None):
""" Get the path from the URL and fetch the corresponding page.
First get the path wihout fileextentsion leading or trailing slashes,
then search in the database if such a page exists.
:param queryset: Get the single item from this filtered queryset.
:return:
"""
path = os.path.splitext(self.kwargs['path'])[0]
queryset = queryset or self.get_queryset()
if path.startswith('/'):
path = path[1:]
if path.endswith('/'):
path = path[:-1]
return queryset.get(path=path)
class PageHtml(generic.DetailView):
"""Display static HTML content from the database."""
model = models.Page
def get_object(self, queryset=None):
"""Get the page content from the db that equals the given URL.
:param queryset: Get the single item from this filtered queryset.
:return:
"""
queryset = queryset or self.get_queryset()
try:
return queryset.get(path=self.kwargs['path'],
content_type=models.HTML_PAGE)
except models.Page.DoesNotExist:
raise Http404(
_("No Page found matching the Path %s") % self.request.path
)
def get_template_names(self):
"""Each static page can define its own template, so return the template
name that has been stored in the dataset.
:return: filename of the template to render.
"""
return self.object.template
class PagePdf(generic.DeleteView):
"""Deliver an static PDF File under this given URL."""
model = models.Page
def get_object(self, queryset=None):
"""Get the PDF page from the db that equals the given URL.
:param queryset: Get the single item from this filtered queryset.
:return: models.Page object or raise a 404 if not found.
"""
queryset = queryset or self.get_queryset()
try:
return queryset.get(path=self.kwargs['path'],
content_type=models.PDF_PAGE)
except models.Page.DoesNotExist:
raise Http404(
_("No PDF Document found matching the Path %s") %
self.request.path
)
def render_to_response(self, context, **response_kwargs):
"""Stream the PDF File to the client and set the right content headers.
:param context: useless only for compatility
:param response_kwargs: will be added to the HttpResponse kwargs.
:return: an HTTPResponse with PDF Content or an Http404 exception
"""
try:
with open(self.object.pdf_file.path, 'rb') as pdf_file:
response = HttpResponse(
content=pdf_file.read(),
content_type='application/pdf',
**response_kwargs
)
return response
except:
raise Http404('File not Found %s.pdf' % self.kwargs['path'])
class StartPage(generic.TemplateView):
"""The Frontpage, a page with the latest infos and some static content."""
template_name = 'index.html'
def get_context_data(self):
""" Adds recent ariticles and recent comments to the context.
:return: array() with the context data
"""
page = models.Page.objects.get(slug='index')
recent_comment_list = comments.get_model().objects.filter(
site__pk=settings.SITE_ID,
is_public=True,
is_removed=False,
)
recent_comment_list = recent_comment_list.order_by('-submit_date')[:10]
context = {
'title': page.title,
'content': page.content,
'recent_article_list': models.Article.objects.published()[:3],
'recent_comment_list': recent_comment_list,
}
return context
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)