Generování certifikátů úspěšných řešitelů

This commit is contained in:
Jonas Havelka 2025-09-29 16:36:08 +02:00
parent 9a50805a69
commit a1c62bdf09
7 changed files with 132 additions and 1 deletions

Binary file not shown.

Binary file not shown.

View file

@ -122,6 +122,7 @@
<p><a href="tituly.tex" download>Tituly (TeX, včetně neveřejných, všechny, nevhodné do mamtexu)</a></p>
{# FIXME: Sice to sem asi nepatří sémanticky, ale bylo to nejjednodušší… #}
<p><a href='{% url 'tvorba_rocnik_resitele_csv' rocnik=rocnik.rocnik %}' download>CSV export řešitelů</a></p>
<p><a href='certifikaty.tar.gz' download>Certifikáty úspěšných řešitelů (doplňte místa [a data] narození a zkompilujte ./certifikaty)</a></p>
<h2>Výsledková listina včetně neveřejných bodů</h2>
{% include "vysledkovky/vysledkovka_rocnik.html" with vysledkovka=vysledkovka_neverejna %}
</div>

View file

@ -0,0 +1,11 @@
{% autoescape off %}{% load static %}{% load tex %}{% with lb='{' %}
\def\ucastnik{{resitel|sloz}}
\def\narozeni{{lb}} {% firstof ofresitel.osoba.datum_narozeni "\\TODO{datum narození ve tvaru 1. 1. 2001}" %}}
\def\mistonar{\TODO{místo narození}}
\def\body{{lb}}{{body}} bod{% if cele %}ů{% else %}u{% endif %}}
\newif\ifresitelka
{% if osloveni_zenske %}\resitelkatrue{% else %}\resitelkafalse{% endif %}
\input{certifikat.tex}
{% endwith %}{% endautoescape %}

View file

@ -0,0 +1,65 @@
{% autoescape off %}{% load static %}{% load tex %}{% with lb='{' %}
\def\rocnik{{rocnik.rocnik|sloz}}
\def\rok{{lb}}{{rocnik.prvni_rok}}/{{rocnik.prvni_rok|add:"1"}}}
\def\levypodpis{Mgr. Vladan Majerech, Dr.\\vedoucí KS M\&M}
\def\pravypodpis{doc. RNDr. Mirko Rokyta, CSc.\\děkan MFF UK}
\documentclass[landscape, 12pt]{article}
\usepackage{geometry}\geometry{a4paper,left=2cm,right=2cm,top=2cm,bottom=2cm}
\setlength\parskip{2em}
\pagestyle{empty}
\usepackage{graphicx}
\usepackage[czech]{babel}
\begin{document}
\centering
\Large
{\Huge
\includegraphics[width=0.45\textwidth]{mff-uk-logo.pdf}\\[1em]
uděluje osvědčení úspěšného řešitele\\
Korespondenčního semináře M\&M
\par}
{\normalsize jméno účastn\ifresitelka ice\else íka\fi:} {\Huge \ucastnik}\\
{\normalsize datum narození:} \narozeni{\normalsize, místo narození:} \mistonar
Účastn\ifresitelka ice\else ík\fi\ v \rocnik. ročníku semináře (školní rok \rok) získal\ifresitelka a\fi\ \body,\\
čímž se stal\ifresitelka a\fi\ úspěšným řešitelem korespondenčního semináře.
\begin{minipage}[t]{0.25\textwidth}
{
\centering
\hrule
\vspace{4pt}
\normalsize\levypodpis
\par
}
\end{minipage}
\begin{minipage}[b]{0.3\textwidth}
\centering
\includegraphics[width=0.8\textwidth]{logomm-new.pdf}
\par
\end{minipage}
\begin{minipage}[t]{0.25\textwidth}
{
\centering
\hrule
\vspace{4pt}
\normalsize\pravypodpis
\par
}
\end{minipage}
\vspace{1em}
%{\vbox to 0pt{\hbox to \textwidth{\hfill\includegraphics[height=2.5em]{jcmf.pdf}}\vskip 0pt minus 1fill}\setlength\parskip{0pt}\noindent}
{\normalsize
Korespondenční seminář M\&M organizují převážně studenti Matematicko-fyzikální fakulty Univerzity Karlovy.\\
% Organizaci semináře a vydávání časopisu podporuje Jednota českých matematiků a fyziků.
\par}
\end{document}
{% endwith %}{% endautoescape %}

View file

@ -36,6 +36,11 @@ urlpatterns = [
org_required(views.resiteleRocnikuCsvExportView),
name='tvorba_rocnik_resitele_csv'
),
path(
'rocnik/<int:rocnik>/certifikaty.tar.gz',
org_required(views.certifikatyExportView),
name='tvorba_rocnik_certifikaty'
),
path(
'rocnik/<int:rocnik>/tituly.tex',
org_required(views.TitulyViewRocnik),

View file

@ -13,8 +13,9 @@ from django.http import Http404
from django.db.models import Q, Sum, Count
from django.views.generic.base import RedirectView
from django.core.exceptions import PermissionDenied
from django.contrib.staticfiles.finders import find
from personalni.models import Resitel
from personalni.models import Resitel, Osoba
from soustredeni.models import Konfera
from tvorba.models import Problem, Cislo, Rocnik, Tema, Clanek, Deadline, Uloha
from treenode.models import TemaVCisleNode, PohadkaNode
@ -34,6 +35,10 @@ from django.conf import settings
import unicodedata
import logging
import time
import http
import tempfile
import shutil
import subprocess
import personalni.views
@ -281,6 +286,50 @@ def resiteleRocnikuCsvExportView(request, rocnik):
)
)
def certifikatyExportView(request, rocnik):
rocnik = get_object_or_404(Rocnik, rocnik=rocnik)
id_a_body_resitelu: dict[int, int] = body_resitelu(
rocnik,
jen_verejne = False,
)
resitele_a_body = [(Resitel.objects.get(id=id), body) for id, body in id_a_body_resitelu.items() if body > 100]
with tempfile.TemporaryDirectory() as tempdir:
shutil.copy(find("tvorba/logomm-new.pdf"), tempdir)
shutil.copy(find("tvorba/mff-uk-logo.pdf"), tempdir)
tex = render(request, "tvorba/archiv/rocnik_certifikat_part.tex", {
"rocnik": rocnik,
}).content
with open(tempdir+"/certifikat.tex", "w") as texfile:
texfile.write(tex.decode())
ostatni_soubory = ["logomm-new.pdf", "mff-uk-logo.pdf", "certifikat.tex"]
certifikaty = []
for r, b in resitele_a_body:
tex = render(request, "tvorba/archiv/rocnik_certifikat.tex", {
"resitel": r,
"body": b,
"cele": b % 1 == 0,
"osloveni_zenske": r.osoba.osloveni == Osoba.OSLOVENI_ZENSKE,
}).content
soubor = f"{r}.tex"
with open(f"{tempdir}/{soubor}", "w") as texfile:
texfile.write(tex.decode())
certifikaty.append(soubor)
with open(tempdir+"/certifikaty", "w") as skript:
for certifikat in certifikaty:
print(f"pdflatex '{certifikat}'", file=skript)
os.chmod(f"{tempdir}/certifikaty", 0o777)
subprocess.call(["tar", "-czf", "certifikaty.tar.gz", *certifikaty, *ostatni_soubory, "certifikaty"], cwd=tempdir)
with open(tempdir+"/certifikaty.tar.gz", "rb") as pdffile:
response = HttpResponse(pdffile.read(), content_type='application/gzip')
return response
# FIXME: Pozor, výš je ještě jeden ProblemView!
#class ProblemView(generic.DetailView):