diff --git a/seminar/models/tvorba.py b/seminar/models/tvorba.py index f3cbc4dc..00d1adfd 100644 --- a/seminar/models/tvorba.py +++ b/seminar/models/tvorba.py @@ -220,7 +220,7 @@ class Cislo(SeminarModelBase): def relativni_v_rocniku(self, rel_index): "Číslo o `index` dále v ročníku. None pokud neexistuje." - cs = self.rocnik.cisla.order_by('cislo').all() + cs = self.rocnik.cisla.order_by('poradi').all() i = list(cs).index(self) + rel_index if (i < 0) or (i >= len(cs)): return None diff --git a/seminar/templates/seminar/archiv/rocnik.html b/seminar/templates/seminar/archiv/rocnik.html index cbe162d2..410b9361 100644 --- a/seminar/templates/seminar/archiv/rocnik.html +++ b/seminar/templates/seminar/archiv/rocnik.html @@ -120,7 +120,8 @@ {% if user.je_org %}

Výsledkovka ročníku (LaTeX, včetně neveřejných)

- Tituly (TeX, do konce ročníku = pro poslední číslo) +

Tituly (TeX, do konce ročníku = pro poslední číslo)

+

Výsledkovka posledního čísla

{# FIXME: Sice to sem asi nepatří sémanticky, ale bylo to nejjednodušší… #}

CSV export řešitelů

Výsledková listina včetně neveřejných bodů

diff --git a/seminar/urls.py b/seminar/urls.py index ecbb86e6..c6ab5695 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -77,6 +77,11 @@ urlpatterns = [ org_required(views.TitulyViewRocnik), name='seminar_rocnik_titul' ), + path( + 'rocnik//posledni_vysledkovka.tex', + org_required(views.PosledniCisloVysledkovkaView.as_view()), + name='seminar_rocnik_posledni_vysledkovka' + ), path( 'cislo/./vysledkovka.tex', org_required(views.CisloVysledkovkaView.as_view()), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 8ce4b93c..965e6c82 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -20,7 +20,7 @@ from treenode import treelib import treenode.templatetags as tnltt import treenode.serializers as vr from vysledkovky.utils import body_resitelu, VysledkovkaCisla, \ - VysledkovkaRocniku + VysledkovkaRocniku, VysledkovkaDoTeXu from datetime import date, datetime from django.utils import timezone @@ -438,7 +438,6 @@ class CisloView(generic.DetailView): cislo = context['cislo'] context['prevcislo'] = Cislo.objects.filter((Q(rocnik__lt=self.object.rocnik) | Q(poradi__lt=self.object.poradi))&Q(rocnik__lte=self.object.rocnik)).first() - context['vysledkovka'] = VysledkovkaCisla(cislo, not self.request.user.je_org) deadliny = Deadline.objects.filter(cislo=cislo).reverse() deadliny_s_vysledkovkami = [] @@ -506,6 +505,60 @@ class CisloVysledkovkaView(CisloView): content_type = 'text/plain; charset=UTF8' #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani + def get_context_data(self, **kwargs): + context = super(CisloVysledkovkaView, self).get_context_data() + cislo = context['cislo'] + + cislopred = cislo.predchozi() + if cislopred is not None: + context['vysledkovka'] = VysledkovkaDoTeXu( + cislo, + od_vyjma=cislopred.zlomovy_deadline_pro_papirove_cislo(), + do_vcetne=cislo.zlomovy_deadline_pro_papirove_cislo(), + ) + else: + context['vysledkovka'] = VysledkovkaCisla( + cislo, + jen_verejne=False, + do_deadlinu=cislo.zlomovy_deadline_pro_papirove_cislo(), + ) + return context + + +# Podle předchozího +class PosledniCisloVysledkovkaView(generic.DetailView): + """View vytvořené pro zobrazení výsledkovky posledního čísla v TeXu.""" + + model = Rocnik + template_name = 'seminar/archiv/cislo_vysledkovka.tex' + content_type = 'text/plain; charset=UTF8' + + def get_object(self, queryset=None): + if queryset is None: + queryset = self.get_queryset() + rocnik_arg = self.kwargs.get('rocnik') + queryset = queryset.filter(rocnik=rocnik_arg) + + try: + obj = queryset.get() + except queryset.model.DoesNotExist: + raise Http404(_("No %(verbose_name)s found matching the query") % + {'verbose_name': queryset.model._meta.verbose_name}) + return obj + + def get_context_data(self, **kwargs): + context = super(PosledniCisloVysledkovkaView, self).get_context_data() + rocnik = context['rocnik'] + cislo = rocnik.cisla.order_by("poradi").last() + cislopred = cislo.predchozi() + context['vysledkovka'] = VysledkovkaDoTeXu( + cislo, + od_vyjma=cislopred.zlomovy_deadline_pro_papirove_cislo(), + do_vcetne=cislo.deadline_v_cisle.order_by("deadline").last(), + ) + return context + + class RocnikVysledkovkaView(RocnikView): """ View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu.""" model = Rocnik diff --git a/vysledkovky/utils.py b/vysledkovky/utils.py index e6be09da..450fbb69 100644 --- a/vysledkovky/utils.py +++ b/vysledkovky/utils.py @@ -456,3 +456,32 @@ class VysledkovkaCisla(Vysledkovka): def ne_clanek_ne_konfera(problem): inst = problem.get_real_instance() return not (isinstance(inst, m.Clanek) or isinstance(inst, m.Konfera)) + + +class VysledkovkaDoTeXu(VysledkovkaCisla): + def __init__( + self, + nejake_cislo: m.Cislo, + od_vyjma: m.Deadline, + do_vcetne: m.Deadline + ): + super().__init__(nejake_cislo, False, do_vcetne) + self.od_deadlinu = od_vyjma + + @cached_property + def problemy(self) -> list[m.Problem]: + return m.Problem.objects.filter(hodnoceni__in=m.Hodnoceni.objects.filter( + deadline_body__deadline__gt=self.od_deadlinu.deadline, + deadline_body__deadline__lte=self.do_deadlinu.deadline, + )).distinct().non_polymorphic().select_related('nadproblem').select_related('nadproblem__nadproblem') + + @property + def hodnoceni_do_cisla(self): + hodnoceni = m.Hodnoceni.objects.prefetch_related( + 'problem', 'reseni', 'reseni__resitele') + if self.jen_verejne: + hodnoceni = hodnoceni.filter(deadline_body__verejna_vysledkovka=True) + return hodnoceni.filter( + deadline_body__deadline__gt=self.od_deadlinu.deadline, + deadline_body__deadline__lte=self.do_deadlinu.deadline + ) \ No newline at end of file