You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.7 KiB

import http
import tempfile
import shutil
import subprocess
from pathlib import Path
from django.http import HttpResponseForbidden, HttpResponse
from django.shortcuts import render
from django.views import generic
from django.template.loader import render_to_string
def csrf_error(request, reason=""):
""" Jednoduchý „template view“ (třída to být nemůže) pro CSRF chyby """
return render(
request, 'various/403_csrf.html',
{"url": request.META.get("HTTP_REFERER", None), "reason": reason},
status=HttpResponseForbidden.status_code,
)
class NeprazdnyListView(generic.ListView):
"""
Použití jako generic.ListView, jen při prázdném listu vyhodí M&M stránku
s titlem `self.if_prazdny_title` a textem `self.if_prazdny_text`
a způsob renderování (např. CSV) lze změnit přepsáním metody render.
"""
allow_empty = False
if_prazdny_title = "V seznamu nic není"
if_prazdny_text = "V seznamu nic není. Zkus to napravit v adminu, nebo se zeptej webařů."
# Skoro copy-paste generic.list.ListView.get,
# protože nemůžu chytat 404, neboť může nastat i v get_context_data
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
if self.get_paginate_by(self.object_list) is not None and hasattr(
self.object_list, "exists"
):
is_empty = not self.object_list.exists()
else:
is_empty = not self.object_list
if is_empty:
return render(request, 'universal.html', {
'title': self.if_prazdny_title,
'text': self.if_prazdny_text,
},
status=http.HTTPStatus.NOT_FOUND,
)
return self.render(request, *args, **kwargs)
# Tohle jsem vyčlenil, aby šlo generovat i něco jiného než template
def render(self, request, *args, **kwargs):
context = self.get_context_data()
return self.render_to_response(context)
class TeXResponseMixin:
"""
Mixin pro TemplateView, aby výsledek projel TeXem a vrátil rovnou PDF.
Obrázky a jiné soubory lze přidat nastavením `dalsi_potrebne_soubory`
(např. na `[django.contrib.staticfiles.finders.find('bla')]`,
nebo jiný seznam absolutních cest).
"""
dalsi_potrebne_soubory = []
tex = "pdflatex"
def render_to_response(self, context, **response_kwargs):
zdrojak = render_to_string(self.get_template_names(), context)
with tempfile.TemporaryDirectory() as tempdirfn:
tempdir = Path(tempdirfn)
with open(tempdir / "main.tex", "w") as texfile:
texfile.write(zdrojak)
for file in self.dalsi_potrebne_soubory:
shutil.copy(file, tempdir)
subprocess.call([self.tex, "main.tex"], cwd=tempdir, stdout=subprocess.DEVNULL)
with open(tempdir / "main.pdf", "rb") as pdffile:
response = HttpResponse(pdffile.read(), content_type='application/pdf', **response_kwargs)
return response