Rozdělení varous.views, aby odpovídali 5f7ec853
This commit is contained in:
parent
47894ce335
commit
be8c9810e4
3 changed files with 87 additions and 78 deletions
|
@ -5,7 +5,7 @@ from django.contrib.staticfiles.finders import find
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
|
|
||||||
import various.views
|
import various.views.generic
|
||||||
from seminar.views import obalkyView
|
from seminar.views import obalkyView
|
||||||
|
|
||||||
from .models import Soustredeni, Soustredeni_Ucastnici
|
from .models import Soustredeni, Soustredeni_Ucastnici
|
||||||
|
@ -38,7 +38,10 @@ class KonkretniSoustredeniMixin:
|
||||||
self.soustredeni = get_object_or_404(Soustredeni, id=soustredeni_id)
|
self.soustredeni = get_object_or_404(Soustredeni, id=soustredeni_id)
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniUcastniciBaseView(KonkretniSoustredeniMixin, various.views.NeprazdnyListView):
|
class SoustredeniUcastniciBaseView(
|
||||||
|
KonkretniSoustredeniMixin,
|
||||||
|
various.views.generic.NeprazdnyListView,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Slouží jako ListView účastníků soustředění
|
Slouží jako ListView účastníků soustředění
|
||||||
+ háže inteligentní chybu při soustředění bez účastníků
|
+ háže inteligentní chybu při soustředění bez účastníků
|
||||||
|
@ -82,7 +85,10 @@ class SoustredeniUcastniciExportView(SoustredeniUcastniciBaseView):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniStvrzenkyView(various.views.TeXResponseMixin, SoustredeniUcastniciBaseView):
|
class SoustredeniStvrzenkyView(
|
||||||
|
various.views.generic.TeXResponseMixin,
|
||||||
|
SoustredeniUcastniciBaseView,
|
||||||
|
):
|
||||||
template_name = 'soustredeni/stvrzenky.tex'
|
template_name = 'soustredeni/stvrzenky.tex'
|
||||||
dalsi_potrebne_soubory = [find('images/logomm.pdf')]
|
dalsi_potrebne_soubory = [find('images/logomm.pdf')]
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
import http
|
from django.http import HttpResponseForbidden
|
||||||
import tempfile
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from django.http import HttpResponseForbidden, HttpResponse
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views import generic
|
|
||||||
from django.template.loader import render_to_string
|
|
||||||
|
|
||||||
|
|
||||||
def csrf_error(request, reason=""):
|
def csrf_error(request, reason=""):
|
||||||
|
@ -18,68 +9,3 @@ def csrf_error(request, reason=""):
|
||||||
{"url": request.META.get("HTTP_REFERER", None), "reason": reason},
|
{"url": request.META.get("HTTP_REFERER", None), "reason": reason},
|
||||||
status=HttpResponseForbidden.status_code,
|
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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
77
various/views/generic.py
Normal file
77
various/views/generic.py
Normal file
|
@ -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 a new issue