Jonas Havelka
4 months ago
3 changed files with 87 additions and 78 deletions
@ -0,0 +1,77 @@ |
|||||
|
""" |
||||
|
Stejně jako je `django.views.generic` jsou zde generické Views |
||||
|
a pár mixinů, které upravují chování Views. |
||||
|
""" |
||||
|
|
||||
|
import http |
||||
|
import shutil |
||||
|
import subprocess |
||||
|
import tempfile |
||||
|
|
||||
|
from pathlib import Path |
||||
|
|
||||
|
from django.http import HttpResponse |
||||
|
from django.shortcuts import render |
||||
|
from django.template.loader import render_to_string |
||||
|
from django.views import generic |
||||
|
|
||||
|
|
||||
|
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 |
Loading…
Reference in new issue