diff --git a/deploy_v2/admin_org_prava.json b/deploy_v2/admin_org_prava.json index f1b6445d..2d07cf83 100644 --- a/deploy_v2/admin_org_prava.json +++ b/deploy_v2/admin_org_prava.json @@ -633,5 +633,20 @@ "codename": "view_fotkaurlvazba", "ct_app_label": "header_fotky", "ct_model": "fotkaurlvazba" + }, + { + "codename": "add_deadline", + "ct_app_label": "seminar", + "ct_model": "deadline" + }, + { + "codename": "change_deadline", + "ct_app_label": "seminar", + "ct_model": "deadline" + }, + { + "codename": "view_deadline", + "ct_app_label": "seminar", + "ct_model": "deadline" } ] diff --git a/odevzdavatko/forms.py b/odevzdavatko/forms.py index 14639b65..9e72fe73 100644 --- a/odevzdavatko/forms.py +++ b/odevzdavatko/forms.py @@ -2,6 +2,7 @@ from django import forms from dal import autocomplete from django.forms import formset_factory from django.forms.models import inlineformset_factory +from django.utils import timezone from seminar.models import Resitel import seminar.models as m @@ -87,7 +88,7 @@ ReseniSPrilohamiFormSet = inlineformset_factory(m.Reseni,m.PrilohaReseni, class JednoHodnoceniForm(forms.ModelForm): class Meta: model = m.Hodnoceni - fields = ('problem', 'body', 'cislo_body') + fields = ('problem', 'body', 'deadline_body') widgets = { 'problem': autocomplete.ModelSelect2( url='autocomplete_problem_odevzdatelny', # FIXME: Dovolit i starší? @@ -141,7 +142,6 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): from django.db.utils import OperationalError try: aktualni_rocnik = m.Nastaveni.get_solo().aktualni_rocnik - aktualni_cislo = m.Nastaveni.get_solo().aktualni_cislo except OperationalError: # django.db.utils.OperationalError: no such table: seminar_nastaveni # Nemáme databázi, takže to selhalo. Pro jistotu vrátíme aspoň dvě možnosti, ať to nepadá dál @@ -152,31 +152,18 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): # FIXME: Tohle je hnusný monkey patch, mělo by to být nějak zahrnuto výš. if rocnik is not None: aktualni_rocnik = rocnik - aktualni_cislo = m.Cislo.objects.filter(rocnik=rocnik).order_by('poradi').last() result = [] - for cislo in m.Cislo.objects.filter( - rocnik=aktualni_rocnik, - poradi__lte=aktualni_cislo.poradi, - ).reverse(): # Standardně se řadí od nejnovějšího čísla - # Předem je mi líto kohokoliv, kdo tyhle řádky bude číst... - if cislo.datum_vydani is not None and cislo.datum_vydani <= datetime.date.today(): - result.append(( - strftime(DATE_FORMAT, cislo.datum_vydani.timetuple()), - f"Vydání {cislo.poradi}. čísla")) - if cislo.datum_preddeadline is not None and cislo.datum_preddeadline <= datetime.date.today(): - result.append(( - strftime(DATE_FORMAT, cislo.datum_preddeadline.timetuple()), - f"Předdeadline {cislo.poradi}. čísla")) - if cislo.datum_deadline_soustredeni is not None and cislo.datum_deadline_soustredeni <= datetime.date.today(): - result.append(( - strftime(DATE_FORMAT, cislo.datum_deadline_soustredeni.timetuple()), - f"Sous. deadline {cislo.poradi}. čísla")) - if cislo.datum_deadline is not None and cislo.datum_deadline <= datetime.date.today(): - result.append(( - strftime(DATE_FORMAT, cislo.datum_deadline.timetuple()), - f"Finální deadline {cislo.poradi}. čísla")) + for deadline in m.Deadline.objects.filter( + deadline__lte=timezone.now(), + cislo__rocnik=aktualni_rocnik + ).order_by("deadline"): + + result.append(( + strftime(DATE_FORMAT, deadline.deadline.timetuple()), + str(deadline))) + result.append(( strftime(DATE_FORMAT, datetime.date.today().timetuple()), f"Dnes")) diff --git a/odevzdavatko/templates/odevzdavatko/detail.html b/odevzdavatko/templates/odevzdavatko/detail.html index 233d703d..10f86a14 100644 --- a/odevzdavatko/templates/odevzdavatko/detail.html +++ b/odevzdavatko/templates/odevzdavatko/detail.html @@ -49,6 +49,10 @@ $(document).ready(function(){ $('.smazat_hodnoceni').click(function(){ deleteForm("form",this); }); + // Copy deadline + if (form_idx !== "0") { + $('#id_form-' + form_idx + '-deadline_body')[0].value = $('#id_form-' + (form_idx - 1) + '-deadline_body')[0].value + } $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1); }); $('.smazat_hodnoceni').click(function(){ @@ -66,7 +70,7 @@ $(document).ready(function(){ {# https://docs.djangoproject.com/en/3.1/ref/models/instances/#django.db.models.Model.get_FOO_display #}

Forma: {{ object.get_forma_display }}

-

Doručeno {{ object.cas_doruceni }}, deadline: {{object.cas_doruceni | deadline_html }}

+

Doručeno {{ object.cas_doruceni }}, deadline: {{object.deadline_reseni | deadline_html }}

{# Soubory: #}

Přílohy:

@@ -97,13 +101,13 @@ $(document).ready(function(){ {{ form.management_form }} - + {% for subform in form %} - + @@ -118,7 +122,7 @@ $(document).ready(function(){ - +
ProblémBodyČíslo pro body
ProblémBodyDeadline pro body
{{ subform.problem }} {{ subform.body }}{{ subform.cislo_body }}{{ subform.deadline_body }} Smazat
{{ form.empty_form.problem }} {{ form.empty_form.body }}{{ form.empty_form.cislo_body }}{{ form.empty_form.deadline_body }} Smazat
diff --git a/odevzdavatko/templates/odevzdavatko/detail_resitele.html b/odevzdavatko/templates/odevzdavatko/detail_resitele.html index 4e5d7848..1c7622a7 100644 --- a/odevzdavatko/templates/odevzdavatko/detail_resitele.html +++ b/odevzdavatko/templates/odevzdavatko/detail_resitele.html @@ -12,7 +12,7 @@ {# https://docs.djangoproject.com/en/3.1/ref/models/instances/#django.db.models.Model.get_FOO_display #}

Forma: {{ object.get_forma_display }}

-

Doručeno {{ object.cas_doruceni }}, deadline: {{object.cas_doruceni | deadline_html }}

+

Doručeno {{ object.cas_doruceni }}, deadline: {{object.deadline_reseni | deadline_html }}

{# Soubory: #}

Přílohy:

@@ -37,12 +37,12 @@ {# Hodnocení: #}

Hodnocení:

-{# #} +{# #} {% for h in hodnoceni %} -{# #} +{# #} {% endfor %}
ProblémBodyČíslo pro body
ProblémBodyDeadline pro body
{{ h.problem }} {{ h.body }}{{ h.cislo_body }}{{ h.deadline_body }}
diff --git a/odevzdavatko/templates/odevzdavatko/prehled_reseni.html b/odevzdavatko/templates/odevzdavatko/prehled_reseni.html index 8c91a92a..f374b572 100644 --- a/odevzdavatko/templates/odevzdavatko/prehled_reseni.html +++ b/odevzdavatko/templates/odevzdavatko/prehled_reseni.html @@ -6,7 +6,7 @@

Označení deadlinů

@@ -29,7 +29,7 @@ {{ hodn.problem.nazev | zkrat_nazev_problemu:27 }} {{ hodn.problem.nazev | zkrat_nazev_problemu:10 }} {{ hodn.body|default_if_none:"---" }} - {{ hodn.reseni.cas_doruceni | deadline_html }} + {{ hodn.deadline_body | deadline_html }} {% endfor %} diff --git a/odevzdavatko/templates/odevzdavatko/seznam.html b/odevzdavatko/templates/odevzdavatko/seznam.html index bb2e4f38..b33f0ca0 100644 --- a/odevzdavatko/templates/odevzdavatko/seznam.html +++ b/odevzdavatko/templates/odevzdavatko/seznam.html @@ -4,7 +4,7 @@ {% block content %} {% for dl, mnozina_reseni in reseni_podle_deadlinu.items %} -

{{ dl.2 | deadline_html }}

+

{{ dl | deadline_html }}

{% endblock content %} diff --git a/seminar/templates/seminar/archiv/rocnik.html b/seminar/templates/seminar/archiv/rocnik.html index 757984cf..410b9361 100644 --- a/seminar/templates/seminar/archiv/rocnik.html +++ b/seminar/templates/seminar/archiv/rocnik.html @@ -112,7 +112,7 @@ {% endif %} - {% if vysledkovka %} + {% if vysledkovka.radky_vysledkovky %}

Výsledková listina

{% include "vysledkovky/vysledkovka_rocnik.html" %} {% endif %} @@ -120,10 +120,12 @@ {% 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)

+

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ů

- {% include "vysledkovky/vysledkovka_rocnik_neverejna.html" %} + {% include "vysledkovky/vysledkovka_rocnik.html" with vysledkovka=vysledkovka_neverejna %}
{% endif %} diff --git a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex index 217127de..a74d5e28 100644 --- a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex +++ b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex @@ -1,13 +1,13 @@ {% with lb="{" %} {% with rb="}" %} -{% with radky_vysledkovky=radky_vysledkovky_s_neverejnymi cisla=cisla_s_neverejnymi %} +{% with vysledkovka=vysledkovka_neverejna %} \setlength{\tabcolsep}{3pt} -\begin{longtable}{|r|l|c|r|{% for cislo in cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}\hline -& & & & \multicolumn{{ lb }}{{ cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in cisla %}\textbf{{ lb }}{{ cislo.poradi }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline +\begin{longtable}{|r|l|c|r|{% for cislo in vysledkovka.cisla_rocniku %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}\hline +& & & & \multicolumn{{ lb }}{{ vysledkovka.cisla_rocniku|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in vysledkovka.cisla_rocniku %}\textbf{{ lb }}{{ cislo.poradi }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline \endhead \hline \endfoot -{% for rv in radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.rocnik_resitele %}{{ rv.rocnik_resitele }}{% endif %} & {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_sezn %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ +{% for rv in vysledkovka.radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.rocnik_resitele %}{{ rv.rocnik_resitele }}{% endif %} & {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_seznam %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ {% endfor %}\end{longtable} {% endwith %} {% endwith %} diff --git a/seminar/templates/seminar/titulnistrana/titulnistrana.html b/seminar/templates/seminar/titulnistrana/titulnistrana.html index 39675a3e..f79bbbf1 100644 --- a/seminar/templates/seminar/titulnistrana/titulnistrana.html +++ b/seminar/templates/seminar/titulnistrana/titulnistrana.html @@ -19,17 +19,17 @@ function sousdeadline() {
Do - {% if typ_deadline == 'soustredeni' %} + {% if nejblizsi_deadline.typ == nejblizsi_deadline.TYP_SOUS or nejblizsi_deadline.typ == nejblizsi_deadline.TYP_PRVNI_A_SOUS %} deadlinu odeslání řešení pro účast na soustředění - {% elif typ_deadline == 'preddeadline' %} 1. deadlinu aktuálního čísla {% else %} deadlinu aktuálního čísla {% endif %}zbývá: - {{nejblizsi_deadline|timeuntil}} + {{nejblizsi_deadline.deadline|timeuntil}}

{% endif %} diff --git a/seminar/templates/seminar/zadani/AktualniVysledkovka.html b/seminar/templates/seminar/zadani/AktualniVysledkovka.html index c447d135..20e81ac7 100644 --- a/seminar/templates/seminar/zadani/AktualniVysledkovka.html +++ b/seminar/templates/seminar/zadani/AktualniVysledkovka.html @@ -8,7 +8,7 @@ {% endblock %} - {% if radky_vysledkovky %} + {% if vysledkovka.radky_vysledkovky %} {% include "vysledkovky/vysledkovka_rocnik.html" %} {% else %}

V tomto ročníku zatím žádné výsledky nejsou.

@@ -22,7 +22,7 @@ {% if user.je_org and vysledkovka_s_neverejnymi %}

Výsledky včetně neveřejných

- {% include "vysledkovky/vysledkovka_rocnik_neverejna.html" %} + {% include "vysledkovky/vysledkovka_rocnik.html" with vysledkovka=vysledkovka_neverejna %}
{% endif %} diff --git a/seminar/templates/seminar/zadani/AktualniZadani.html b/seminar/templates/seminar/zadani/AktualniZadani.html index 6dced7d9..81040dec 100644 --- a/seminar/templates/seminar/zadani/AktualniZadani.html +++ b/seminar/templates/seminar/zadani/AktualniZadani.html @@ -16,18 +16,20 @@
Termíny pro odeslání řešení {{ac.poradi}}. série:
- - {% if ac.datum_deadline_soustredeni %} - {{ac.datum_deadline_soustredeni}} pro účast na soustředění
- {% endif %} - {% if ac.datum_preddeadline %} - {{ac.datum_preddeadline}} pro otištění v dalším čísle
- {% endif %} + {% for deadline in ac.deadline_v_cisle.all %} + {% if deadline.typ == deadline.TYP_SOUS or deadline.typ == deadline.TYP_PRVNI_A_SOUS %} + {{deadline.deadline.date}} pro účast na soustředění
+ {% endif %} - {% if ac.datum_deadline %} - {{ac.datum_deadline}} definitivní deadline
- {% endif %} + {% if deadline.typ == deadline.TYP_PRVNI or deadline.typ == deadline.TYP_PRVNI_A_SOUS %} + {{deadline.deadline.date}} pro otištění v dalším čísle
+ {% endif %} + + {% if deadline.typ == deadline.TYP_CISLA %} + {{deadline.deadline.date}} definitivní deadline
+ {% endif %} + {% endfor %}

diff --git a/seminar/templatetags/deadliny.py b/seminar/templatetags/deadliny.py index 9cf0f7f4..95db664b 100644 --- a/seminar/templatetags/deadliny.py +++ b/seminar/templatetags/deadliny.py @@ -1,44 +1,32 @@ from django import template from django.utils.safestring import mark_safe -from seminar.utils import TypDeadline, deadline register = template.Library() - -@register.filter(name='deadline') -def deadline_text(datum): - if deadline(datum) is None: - return 'Neznámý deadline' - typ, cislo, dl = deadline(datum) - strings = { - TypDeadline.PredDeadline: f"1. deadline čísla {cislo} ({dl})", - TypDeadline.SousDeadline: f"Soustřeďkový deadline čísla {cislo} ({dl})", - TypDeadline.FinalDeadline: f"Finální deadline čísla {cislo} ({dl})", - } - return strings[typ] +import seminar.models as m @register.filter(name='deadline_kratseji') -def deadline_kratsi_text(datum): - if deadline(datum) is None: +def deadline_kratsi_text(deadline: m.Deadline): + if deadline is None: return 'NONE' - typ, cislo, dl = deadline(datum) strings = { - TypDeadline.PredDeadline: f"{cislo} ♲", - TypDeadline.SousDeadline: f"{cislo} Ⓢ", - TypDeadline.FinalDeadline: f"{cislo} ✓", + m.Deadline.TYP_PRVNI: f"{deadline.cislo} ⭯", + m.Deadline.TYP_SOUS: f"{deadline.cislo} Ⓢ", + m.Deadline.TYP_PRVNI_A_SOUS: f"{deadline.cislo} ⭯Ⓢ", + m.Deadline.TYP_CISLA: f"{deadline.cislo} ✓", } - return strings[typ] + return strings[deadline.typ] @register.filter(name='deadline_html') -def deadline_html(datum): - if deadline(datum) is None: +def deadline_html(deadline: m.Deadline): + if deadline is None: return 'Neznámý deadline' - typ, _, _ = deadline(datum) - text = deadline_kratsi_text(datum) + text = deadline_kratsi_text(deadline) classes = { - TypDeadline.PredDeadline: 'preddeadline', - TypDeadline.SousDeadline: 'sous_deadline', - TypDeadline.FinalDeadline: 'final_deadline', + m.Deadline.TYP_PRVNI: 'preddeadline', + m.Deadline.TYP_SOUS: 'sous_deadline', + m.Deadline.TYP_PRVNI_A_SOUS: 'sous_deadline', + m.Deadline.TYP_CISLA: 'final_deadline', } - return mark_safe(f'{text}') + return mark_safe(f'{text}') @register.filter(name='zkrat_nazev_problemu') def zkrat_nazev_problemu(nazev,width): diff --git a/seminar/test_deadlines.py b/seminar/test_deadlines.py deleted file mode 100644 index 0c0b713b..00000000 --- a/seminar/test_deadlines.py +++ /dev/null @@ -1,149 +0,0 @@ -from django.test import TestCase -from datetime import date - -import seminar.models as m -from seminar.utils import deadline, TypDeadline - -class DeadlineTestCase(TestCase): - def setUp(self): - # Chceme pár ročníků a v nich pár čísel - r1 = m.Rocnik.objects.create(rocnik=1, prvni_rok=2000, exportovat=False) - r2 = m.Rocnik.objects.create(rocnik=2, prvni_rok=2001, exportovat=False) - r3 = m.Rocnik.objects.create(rocnik=3, prvni_rok=2002, exportovat=False) - - # První číslo mívá soustřeďkový deadline… - c1_1 = m.Cislo.objects.create(rocnik=r1, poradi='1', - datum_vydani=date.fromisoformat('2000-05-22'), - datum_preddeadline=date.fromisoformat('2000-09-11'), - datum_deadline_soustredeni=date.fromisoformat('2000-09-11'), - datum_deadline=date.fromisoformat('2000-10-01'), - ) - c1_2 = m.Cislo.objects.create(rocnik=r1, poradi='2', - datum_vydani=date.fromisoformat('2000-10-19'), - datum_preddeadline=date.fromisoformat('2000-12-05'), - datum_deadline=date.fromisoformat('2001-01-02'), - ) - # Některá čísla nemají předdeadline… - c1_3 = m.Cislo.objects.create(rocnik=r1, poradi='3', - datum_vydani=date.fromisoformat('2001-01-28'), - datum_deadline=date.fromisoformat('2001-03-12'), - ) - # Poslední číslo nemá ani normální deadline… - c1_4 = m.Cislo.objects.create(rocnik=r1, poradi='4-5', - datum_vydani=date.fromisoformat('2001-04-24'), - ) - # První číslo dalšího ročníku se někdy vydá dřív, než poslední minulého… - c2_1 = m.Cislo.objects.create(rocnik=r2, poradi='1', - datum_vydani=date.fromisoformat('2001-04-19'), - datum_deadline_soustredeni=date.fromisoformat('2001-09-26'), - datum_deadline=date.fromisoformat('2001-10-07'), - ) - # Tohle číslo má finální deadline až po vydání prvního čísla dalšího ročníku - # To samé se skoro stalo na přelomu (reálných) ročníků 27 a 28. - c2_2 = m.Cislo.objects.create(rocnik=r2, poradi='2', - datum_vydani=date.fromisoformat('2002-03-14'), - datum_preddeadline=date.fromisoformat('2002-05-26'), - datum_deadline=date.fromisoformat('2002-06-30'), - ) - # Závěrečné číslo druhého ročníku až na podzim - c2_3 = m.Cislo.objects.create(rocnik=r2, poradi='3', - datum_vydani=date.fromisoformat('2002-09-05'), - ) - # Divný případ: sous deadline stejný jako finální - c3_1 = m.Cislo.objects.create(rocnik=r3, poradi='1', - datum_vydani=date.fromisoformat('2002-06-02'), - datum_preddeadline=date.fromisoformat('2002-08-31'), - datum_deadline=date.fromisoformat('2002-09-30'), - datum_deadline_soustredeni=date.fromisoformat('2002-09-30'), - ) - - # Celkový harmonogram: - # 2000-05-22 začátek 1. ročníku, číslo 1.1 - - # 2000-09-11 sous a 1. deadline 1.1 - # 2000-10-01 finální deadline 1.1 - # 2000-10-19 Vydání 1.2 - # 2000-12-05 předdeadline 1.2 - # 2001-01-02 finální deadline 1.2 - # 2001-01-28 vyd 1.3 - # 2001-03-12 deadline 1.3 - # 2001-04-19 Začátek 2. ročníku, číslo 2.1 - # 2001-04-24 Vydání 1.4-5 -- závěrečné číslo 1. roč. - - # 2001-09-26 Sous-deadline 2.1 - # 2001-10-07 Deadline 2.1 - # 2002-03-14 Pí den, vydání 2.2 - # 2002-05-26 Předdeadline 2.2 - # 2002-06-02 Třetí ročník, vydání 3.1 - # 2002-06-30 Deadline 2.2 - - # 2002-08-31 Předdeadline 3.1 - # 2002-09-04 Vydání 2.3, konec 2. roč. - # 2002-09-30 Sous a finální deadline 3.1 - - def test_deadline_spravne_vysledky(self): - """V každém intervalu mezi deadliny dostáváme ten správný deadline""" - # První ročník - self.assertEqual(deadline(date.fromisoformat('2000-05-30')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) - self.assertEqual(deadline(date.fromisoformat('2000-09-15')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-10-01'))) - - # Trochu divný případ, kdy někdo něco pošle před vydáním čísla. Ale článkům se to asi stát může… - self.assertEqual(deadline(date.fromisoformat('2000-10-10')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) - self.assertEqual(deadline(date.fromisoformat('2000-10-22')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) - self.assertEqual(deadline(date.fromisoformat('2000-12-15')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2001-01-02'))) - self.assertEqual(deadline(date.fromisoformat('2001-01-08')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) - self.assertEqual(deadline(date.fromisoformat('2001-01-30')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) - self.assertEqual(deadline(date.fromisoformat('2001-03-15')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - self.assertEqual(deadline(date.fromisoformat('2001-04-22')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - self.assertEqual(deadline(date.fromisoformat('2001-04-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - - # Druhý ročník - # Pro jistotu ještě prázdniny - self.assertEqual(deadline(date.fromisoformat('2001-07-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - self.assertEqual(deadline(date.fromisoformat('2001-09-27')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-10-07'))) - self.assertEqual(deadline(date.fromisoformat('2001-12-27')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) - self.assertEqual(deadline(date.fromisoformat('2002-03-15')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) - self.assertEqual(deadline(date.fromisoformat('2002-03-15')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) - - self.assertEqual(deadline(date.fromisoformat('2002-05-27')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) - # Tohle je trochu podezřelý případ, protože relevantní deadliny existují dvě… Ale ten pro minulý ročník je těsnější a realističtější - self.assertEqual(deadline(date.fromisoformat('2002-06-03')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) - self.assertEqual(deadline(date.fromisoformat('2002-07-01')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-08-31'))) - - # Třetí ročník - self.assertEqual(deadline(date.fromisoformat('2002-09-01')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) - self.assertEqual(deadline(date.fromisoformat('2002-09-05')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) - - def test_deadline_ve_zlomove_dny(self): - """Pro dny, kdy je deadline nebo vydání čísla, pořád dostáváme správné deadliny. - - Testuje hlavně přítomnost někde nějakých off-by-one""" - self.assertEqual(deadline(date.fromisoformat('2000-05-22')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) - - self.assertEqual(deadline(date.fromisoformat('2000-09-11')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) - self.assertEqual(deadline(date.fromisoformat('2000-10-01')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-10-01'))) - self.assertEqual(deadline(date.fromisoformat('2000-10-19')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) - self.assertEqual(deadline(date.fromisoformat('2000-12-05')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) - self.assertEqual(deadline(date.fromisoformat('2001-01-02')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2001-01-02'))) - self.assertEqual(deadline(date.fromisoformat('2001-01-28')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) - self.assertEqual(deadline(date.fromisoformat('2001-03-12')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) - self.assertEqual(deadline(date.fromisoformat('2001-04-19')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - self.assertEqual(deadline(date.fromisoformat('2001-04-24')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - - self.assertEqual(deadline(date.fromisoformat('2001-09-26')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) - self.assertEqual(deadline(date.fromisoformat('2001-10-07')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-10-07'))) - self.assertEqual(deadline(date.fromisoformat('2002-03-14')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) - self.assertEqual(deadline(date.fromisoformat('2002-05-26')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) - self.assertEqual(deadline(date.fromisoformat('2002-06-02')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) - self.assertEqual(deadline(date.fromisoformat('2002-06-30')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) - - self.assertEqual(deadline(date.fromisoformat('2002-08-31')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-08-31'))) - self.assertEqual(deadline(date.fromisoformat('2002-09-04')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) - self.assertEqual(deadline(date.fromisoformat('2002-09-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) - - def test_deadline_pro_datetime(self): - """Testuje, že i pro datetime dostáváme správné deadliny""" - self.skipTest('Chybí implementace testu') - - def test_moc_pozdni_deadline(self): - self.assertIsNone(deadline(date.max)) diff --git a/seminar/testutils.py b/seminar/testutils.py index efeea49f..fe73875f 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -297,7 +297,7 @@ def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_c res_vyber.remove(resitele[0]) # Vytvoření řešení. - if uloha.cislo_zadani.datum_deadline is not None: + if uloha.cislo_zadani.zlomovy_deadline_pro_papirove_cislo() is not None: # combine, abychom dostali plný čas a ne jen datum cas_doruceni = datetime.datetime.combine(uloha.cislo_zadani.datum_deadline, datetime.datetime.min.time()) - datetime.timedelta(days=random.randint(0, 40)) - datetime.timedelta(minutes=random.randint(0, 60*24)) # astimezone, protože jinak vyhazuje warning o nenastavené TZ diff --git a/seminar/urls.py b/seminar/urls.py index d825b9b8..c6ab5695 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -72,6 +72,16 @@ urlpatterns = [ org_required(views.resiteleRocnikuCsvExportView), name='seminar_rocnik_resitele_csv' ), + path( + 'rocnik//tituly.tex', + 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/utils.py b/seminar/utils.py index 176831cb..e7d52529 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -14,9 +14,6 @@ from django.contrib.auth.models import AnonymousUser from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from enum import Enum -from enum import auto - import logging import seminar.models as m @@ -179,11 +176,11 @@ def resi_v_rocniku(rocnik, cislo=None): if cislo is None: # filtrujeme pouze podle ročníku return m.Resitel.objects.filter(rok_maturity__gte=rocnik.druhy_rok(), - reseni__hodnoceni__cislo_body__rocnik=rocnik).distinct() + reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik).distinct() else: # filtrujeme podle ročníku i čísla return m.Resitel.objects.filter(rok_maturity__gte=rocnik.druhy_rok(), - reseni__hodnoceni__cislo_body__rocnik=rocnik, - reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi).distinct() + reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik, + reseni__hodnoceni__deadline_body__cislo__poradi__lte=cislo.poradi).distinct() def aktivniResitele(cislo, pouze_letosni=False): @@ -248,139 +245,6 @@ def viewMethodSwitch(get, post): return NewView.as_view() -def cisla_rocniku(rocnik, jen_verejne=True): - """ - Vrátí všechna čísla daného ročníku. - Parametry: - rocnik (Rocnik): ročník semináře - jen_verejne (bool): zda se mají vrátit jen veřejná, nebo všechna čísla - Vrátí: - seznam objektů typu Cislo - """ - if jen_verejne: - return rocnik.verejne_vysledkovky_cisla() - else: - return rocnik.cisla.all().order_by('poradi') - -def hlavni_problem(problem): - """ Pro daný problém vrátí jeho nejvyšší nadproblém.""" - while not(problem.nadproblem == None): - problem = problem.nadproblem - return problem - -def problemy_rocniku(rocnik, jen_verejne=True): - return m.Problem.objects.filter(hodnoceni__in = m.Hodnoceni.objects.filter(cislo_body__in = cisla_rocniku(rocnik, jen_verejne))).distinct().select_related('nadproblem').select_related('nadproblem__nadproblem') - -def problemy_cisla(cislo): - """ Vrátí seznam všech problémů s body v daném čísle. """ - return m.Problem.objects.filter(hodnoceni__in = m.Hodnoceni.objects.filter(cislo_body = cislo)).distinct().non_polymorphic().select_related('nadproblem').select_related('nadproblem__nadproblem') - - -def hlavni_problemy_f(problemy=None): - """ Vrátí seznam všech problémů, které již nemají nadproblém. """ - # hlavní problémy čísla - # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) - hlavni_problemy = set() - for p in problemy: - hlavni_problemy.add(hlavni_problem(p)) - - # zunikátnění - hlavni_problemy = list(hlavni_problemy) - hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... - - return hlavni_problemy - - -def podproblemy_v_cislu(cislo, problemy=None, hlavni_problemy=None): - """ Vrátí seznam všech problémů s body v daném čísle v poli 'indexovaném' tématy. """ - if problemy is None: - problemy = problemy_cisla(cislo) - if hlavni_problemy is None: - hlavni_problemy = hlavni_problemy_f(problemy) - - podproblemy = dict((hp.id, []) for hp in hlavni_problemy) - hlavni_problemy = set(hlavni_problemy) - podproblemy[-1] = [] - - for problem in problemy: - h_problem = hlavni_problem(problem) - if h_problem in hlavni_problemy: - podproblemy[h_problem.id].append(problem) - else: - podproblemy[-1].append(problem) - - for podproblem in podproblemy.keys(): - def int_or_zero(p): - try: - return int(p.kod) - except ValueError: - return 0 - - podproblemy[podproblem] = sorted(podproblemy[podproblem], key=int_or_zero) - - return podproblemy - -class TypDeadline(Enum): - PredDeadline = auto() - SousDeadline = auto() - FinalDeadline = auto() - -def deadline_v_rocniku(datum, rocnik): - """Funkce pro dohledání, ke kterému deadlinu daného ročníku se datum váže. - - Vrací trojici (TypDeadline, Cislo, datumDeadline: date). - - V případě nevalidního volání není aktuálně chování definováno(!) - """ - cisla = m.Cislo.objects.filter(rocnik=rocnik) - deadliny = [] - for c in cisla: - if c.datum_preddeadline is not None: - deadliny.append((TypDeadline.PredDeadline, c, c.datum_preddeadline)) - if c.datum_deadline_soustredeni is not None: - deadliny.append((TypDeadline.SousDeadline, c, c.datum_deadline_soustredeni)) - if c.datum_deadline is not None: - deadliny.append((TypDeadline.FinalDeadline, c, c.datum_deadline)) - deadliny = sorted(deadliny, key=lambda x: x[2]) # podle data - for dl in deadliny: - if datum <= dl[2]: - # První takový deadline je ten nejtěsnější - return dl - logger.error(f'Pro datum {datum} v ročníku {rocnik} neexistuje deadline.') - -def deadline(datum): - """Funkce pro dohledání, ke kterému deadlinu se datum váže. - - Vrací trojici (TypDeadline, Cislo, datumDeadline: date). Pokud se deadline nenajde, vrátí None - """ - - if isinstance(datum, datetime.datetime): - datum = datum.date() - rok = datum.year - # Dva ročníky podezřelé z obsahování dat - try: - pozdejsi_rocnik = m.Rocnik.objects.get(prvni_rok=rok) - except m.Rocnik.DoesNotExist: - pozdejsi_rocnik = None - - try: - drivejsi_rocnik = m.Rocnik.objects.get(prvni_rok=rok-1) - except m.Rocnik.DoesNotExist: - drivejsi_rocnik = None - - if drivejsi_rocnik is not None: - # Předpokládáme, že neexistuje číslo, které má deadline ale nemá finální deadline. - # Seznam čísel je potřeba ručně setřídit chronologicky, protože Model říká, že se řadí od nejnovějšího - posledni_deadline_drivejsiho_rocniku = m.Cislo.objects.filter(rocnik=drivejsi_rocnik, datum_deadline__isnull=False).order_by('poradi').last().datum_deadline - - logger.debug(f'Nalezené ročníky: {drivejsi_rocnik}, {pozdejsi_rocnik}') - if drivejsi_rocnik is not None and datum <= posledni_deadline_drivejsiho_rocniku: - logger.debug(f'Hledám v dřívějším ročníku: {drivejsi_rocnik}') - return deadline_v_rocniku(datum, drivejsi_rocnik) - else: - logger.debug(f'Hledám v pozdějším ročníku: {pozdejsi_rocnik}') - return deadline_v_rocniku(datum, pozdejsi_rocnik) - def sync_skoly(base_url): """Stáhne všechny školy z mamwebu na adrese a uloží je do databáze""" diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 49327aa3..7cf79d9f 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -11,14 +11,16 @@ from django.core.exceptions import PermissionDenied import seminar.models as s import seminar.models as m -from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Organizator, Resitel, Novinky, Tema, Clanek # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci +from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, \ + Organizator, Resitel, Novinky, Tema, Clanek, \ + Deadline # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from seminar import utils from treenode import treelib import treenode.templatetags as tnltt import treenode.serializers as vr -from vysledkovky.utils import body_resitelu -from vysledkovky.views import vysledkovka_rocniku, vysledkovka_cisla +from vysledkovky.utils import body_resitelu, VysledkovkaCisla, \ + VysledkovkaRocniku, VysledkovkaDoTeXu from datetime import date, datetime from django.utils import timezone @@ -206,26 +208,17 @@ def ZadaniAktualniVysledkovkaView(request): nastaveni = get_object_or_404(Nastaveni) # Aktualni verejna vysledkovka rocnik = nastaveni.aktualni_rocnik - context = vysledkovka_rocniku( - rocnik=rocnik, - request=request, - sneverejnou=True - ) + context = {'vysledkovka': VysledkovkaRocniku(rocnik, True)} # kdyz neni verejna vysledkovka, tak zobraz starou - if len(context['cisla']) == 0: + if len(context['vysledkovka'].cisla_rocniku) == 0: try: minuly_rocnik = Rocnik.objects.get( - prvni_rok=(rocnik.prvni_rok-1)) + rocnik=(rocnik.rocnik-1)) rocnik = minuly_rocnik # Přepíšeme prázdnou výsledkovku výsledkovkou z minulého ročníku - context = vysledkovka_rocniku( - rocnik=rocnik, - context=context, - request=request, - sneverejnou=True - ) + context['vysledkovka'] = VysledkovkaRocniku(rocnik, True) except ObjectDoesNotExist: pass @@ -268,23 +261,8 @@ class TitulniStranaView(generic.ListView): context = super(TitulniStranaView, self).get_context_data(**kwargs) nastaveni = get_object_or_404(Nastaveni) - deadline_soustredeni = (nastaveni.aktualni_cislo.datum_deadline_soustredeni, "soustredeni") - preddeadline = (nastaveni.aktualni_cislo.datum_preddeadline, "preddeadline") - deadline = (nastaveni.aktualni_cislo.datum_deadline, "deadline") - - try: - nejblizsi_deadline = sorted(filter(lambda dl: dl[0] is not None and dl[0] >= date.today(), [deadline_soustredeni, preddeadline, deadline]))[0] - if nejblizsi_deadline[0] == deadline_soustredeni[0]: - nejblizsi_deadline = deadline_soustredeni - except IndexError: - nejblizsi_deadline = (None, None) # neni zadna aktualni deadline - - if nejblizsi_deadline[0] is not None: - context['nejblizsi_deadline'] = datetime.combine(nejblizsi_deadline[0], datetime.max.time()) - else: - context['nejblizsi_deadline'] = None - - context['typ_deadline'] = nejblizsi_deadline[1] + deadline = m.Deadline.objects.filter(deadline__gte=timezone.now()).order_by("deadline").first() + context['nejblizsi_deadline'] = deadline # Aktuální témata nazvy_a_odkazy_na_aktualni_temata = [] @@ -377,17 +355,10 @@ class RocnikView(generic.DetailView): return get_object_or_404(queryset,rocnik=self.kwargs.get('rocnik')) def get_context_data(self, **kwargs): - start = time.time() context = super(RocnikView, self).get_context_data(**kwargs) - context = vysledkovka_rocniku( - rocnik=context["rocnik"], - context=context, - request=self.request, - sneverejnou=True - ) - end = time.time() - print("Kontext:", end-start) - + context["vysledkovka"] = VysledkovkaRocniku(context["rocnik"], True) + context["neprazdna_vysledkovka"] = len(context['vysledkovka'].cisla_rocniku) != 0 + context["vysledkovka_neverejna"] = VysledkovkaRocniku(context["rocnik"], False) return context def resiteleRocnikuCsvExportView(request, rocnik): @@ -452,8 +423,23 @@ 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() - # vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky - return vysledkovka_cisla(cislo, context) + + deadliny = Deadline.objects.filter(cislo=cislo).reverse() + deadliny_s_vysledkovkami = [] + + nadpisy = { + m.Deadline.TYP_CISLA: "Výsledkovka", + m.Deadline.TYP_PRVNI: "Výsledkovka do prvního deadlinu", + m.Deadline.TYP_PRVNI_A_SOUS: "Výsledkovka do prvního deadlinu a deadlinu pro účast na soustředění", + m.Deadline.TYP_SOUS: "Výsledkovka do deadlinu pro účast na soustředění", + } + + for deadline in deadliny: + if self.request.user.je_org | deadline.verejna_vysledkovka: + deadliny_s_vysledkovkami.append((deadline, nadpisy[deadline.typ], VysledkovkaCisla(cislo, not self.request.user.je_org, deadline))) + + context['deadliny_s_vysledkovkami'] = deadliny_s_vysledkovkami + return context class ArchivTemataView(generic.ListView): @@ -476,17 +462,41 @@ class OdmenyView(generic.TemplateView): fromcislo = Cislo.objects.get(rocnik=self.kwargs.get('frocnik'), poradi=self.kwargs.get('fcislo')) tocislo = Cislo.objects.get(rocnik=self.kwargs.get('trocnik'), poradi=self.kwargs.get('tcislo')) resitele = aktivniResitele(tocislo) - frombody = body_resitelu(resitele, fromcislo) - tobody = body_resitelu(resitele, tocislo) - outlist = [] - for (aid, tbody) in tobody.items(): - fbody = frombody.get(aid,0) - resitel = Resitel.objects.get(pk=aid) - ftitul = resitel.get_titul(fbody) - ttitul = resitel.get_titul(tbody) - if ftitul != ttitul: - outlist.append({'jmeno': resitel.osoba.plne_jmeno(), 'ftitul': ftitul, 'ttitul': ttitul}) - context['zmeny'] = outlist + + def get_diff(from_deadline: Deadline, to_deadline: Deadline): + frombody = body_resitelu(resitele=resitele, jen_verejne=False, do=from_deadline) + tobody = body_resitelu(resitele=resitele, jen_verejne=False, do=to_deadline) + outlist = [] + for (aid, tbody) in tobody.items(): + fbody = frombody.get(aid,0) + resitel = Resitel.objects.get(pk=aid) + ftitul = resitel.get_titul(fbody) + ttitul = resitel.get_titul(tbody) + if ftitul != ttitul: + outlist.append({'jmeno': resitel.osoba.plne_jmeno(), 'ftitul': ftitul, 'ttitul': ttitul}) + return outlist + + def posledni_deadline_oprava(cislo: Cislo) -> Deadline: + posledni_deadline = cislo.posledni_deadline + if posledni_deadline is None: + return Deadline.objects.filter(Q(cislo__poradi__lt=cislo.poradi, cislo__rocnik=cislo.rocnik) | Q(cislo__rocnik__rocnik__lt=cislo.rocnik.rocnik)).order_by("deadline").last() + return posledni_deadline + + context["from_cislo"] = fromcislo + context["to_cislo"] = tocislo + context["zmeny_prvni_prvni"] = get_diff( + fromcislo.zlomovy_deadline_pro_papirove_cislo(), + tocislo.zlomovy_deadline_pro_papirove_cislo() + ) + context["zmeny_prvni_posledni"] = get_diff( + fromcislo.zlomovy_deadline_pro_papirove_cislo(), + posledni_deadline_oprava(tocislo) + ) + context["zmeny_posledni_prvni"] = get_diff( + posledni_deadline_oprava(fromcislo), + tocislo.zlomovy_deadline_pro_papirove_cislo() + ) + return context @@ -504,6 +514,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 @@ -556,17 +620,23 @@ def oldObalkovaniView(request, rocnik, cislo): ### Tituly +def TitulyViewRocnik(request, rocnik): + return TitulyView(request, rocnik, None) + def TitulyView(request, rocnik, cislo): """ View pro stažení makra titulů v TeXu.""" rocnik_obj = Rocnik.objects.get(rocnik = rocnik) resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok) - cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo) asciijmena = [] jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), # pokud ano, vrátí se jako true - slovnik_s_body = body_resitelu(resitele, cislo_obj) + if cislo is not None: + cislo_obj = Cislo.objects.get(rocnik=rocnik_obj, poradi=cislo) + slovnik_s_body = body_resitelu(do=cislo_obj.zlomovy_deadline_pro_papirove_cislo(), jen_verejne=False) + else: + slovnik_s_body = body_resitelu(do=Deadline.objects.filter(cislo__rocnik=rocnik_obj).last(), jen_verejne=False) for resitel in resitele: resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id]) diff --git a/vysledkovky/templates/vysledkovky/vysledkovka_cisla.html b/vysledkovky/templates/vysledkovky/vysledkovka_cisla.html index 6243c32b..e24b3d12 100644 --- a/vysledkovky/templates/vysledkovky/vysledkovka_cisla.html +++ b/vysledkovky/templates/vysledkovky/vysledkovka_cisla.html @@ -3,21 +3,21 @@ # Jméno - {% for p in problemy %} - {# #}{{ p.kod_v_rocniku }}{# #} + {% for p in vysledkovka.temata_a_spol%} + {# #}{{ p.kod_v_rocniku }}{# #} {# TODELETE #} - {% for podproblemy in podproblemy_iter.next %} - {# #}{{ podproblemy.kod_v_rocniku }}{# #} + {% for podproblemy in vysledkovka.podproblemy_iter.next %} + {# #}{{ podproblemy.kod_v_rocniku }}{# #} {% endfor %} {# TODELETE #} {% endfor %} - {% if ostatni %}Ostatní {% endif %} + {% if vysledkovka.je_nejake_ostatni %}Ostatní {% endif %} {# TODELETE #} - {% for podproblemy in podproblemy_iter.next %} - {# #}{{ podproblemy.kod_v_rocniku }}{# #} + {% for podproblemy in vysledkovka.podproblemy_iter.next %} + {# #}{{ podproblemy.kod_v_rocniku }}{# #} {% endfor %} {# TODELETE #} @@ -25,7 +25,7 @@ Za číslo Za ročník Odjakživa - {% for rv in radky_vysledkovky %} + {% for rv in vysledkovka.radky_vysledkovky %} {% autoescape off %}{{ rv.poradi }}{% endautoescape %} @@ -33,14 +33,12 @@ {{ rv.titul }}MM {% endif %} {{ rv.resitel.osoba.plne_jmeno }} - {% for b in rv.body_problemy_sezn %} + {% for b in rv.body_za_temata_seznam %} {{ b }} - {# TODELETE #} {% for body_podproblemu in rv.body_podproblemy_iter.next %} - {{ body_podproblemu }} + {{ body_podproblemu }} {% endfor %} - {# TODELETE #} {% endfor %} {{ rv.body_cislo }} @@ -55,29 +53,29 @@ {# TODELETE #}