Browse Source

Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations

export_seznamu_prednasek
Kateřina Č 4 years ago
parent
commit
f960853239
  1. 34
      data/sitetree.json
  2. 2
      mamweb/settings_common.py
  3. 42
      mamweb/templates/base.html
  4. 22
      seminar/forms.py
  5. 61
      seminar/migrations/0001_squashed_0067_auto_20190814_0805.py
  6. 13
      seminar/migrations/0051_resitel_to_osoba.py
  7. 62
      seminar/migrations/0052_user_to_organizator.py
  8. 19
      seminar/models.py
  9. 5
      seminar/templates/seminar/odevzdavatko/detail.html
  10. 38
      seminar/templates/seminar/odevzdavatko/resitel_prehled.html
  11. 6
      seminar/templates/seminar/odevzdavatko/seznam.html
  12. 2
      seminar/templates/seminar/profil/edit.html
  13. 1
      seminar/templates/seminar/profil/resitel.html
  14. 35
      seminar/templatetags/deadliny.py
  15. 1
      seminar/urls.py
  16. 14
      seminar/utils.py
  17. 37
      seminar/views/odevzdavatko.py
  18. 21
      seminar/views/views_all.py
  19. 0
      various/__init__.py
  20. 3
      various/admin.py
  21. 5
      various/apps.py
  22. 14
      various/context_processors.py
  23. 0
      various/migrations/__init__.py
  24. 3
      various/models.py
  25. 3
      various/tests.py
  26. 3
      various/views.py

34
data/sitetree.json

@ -695,13 +695,13 @@
"alias": null,
"description": "",
"hidden": false,
"hint": "",
"hint": "To, co ŘEŠITELÉ poslali",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 21,
"sort_order": 37,
"title": "Odevzdaná řešení",
"sort_order": 38,
"title": "Došlá řešení",
"tree": 1,
"url": "odevzdavatko_tabulka",
"urlaspattern": true
@ -724,7 +724,7 @@
"inmenu": true,
"insitetree": true,
"parent": 21,
"sort_order": 38,
"sort_order": 42,
"title": "Odhlásit se",
"tree": 1,
"url": "logout",
@ -806,5 +806,31 @@
},
"model": "sitetree.treeitem",
"pk": 41
},
{
"fields": {
"access_guest": false,
"access_loggedin": false,
"access_perm_type": 1,
"access_permissions": [
2
],
"access_restricted": true,
"alias": null,
"description": "",
"hidden": false,
"hint": "To, co jsem JÁ odevzdal",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 21,
"sort_order": 37,
"title": "Odevzdaná řešení",
"tree": 1,
"url": "seminar_resitel_odevzdana_reseni",
"urlaspattern": true
},
"model": "sitetree.treeitem",
"pk": 42
}
]

2
mamweb/settings_common.py

@ -78,6 +78,7 @@ TEMPLATES = [
'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai',
'header_fotky.context_processors.vzhled',
'various.context_processors.april',
)
},
},
@ -132,6 +133,7 @@ INSTALLED_APPS = (
'korektury',
'prednasky',
'header_fotky',
'various',
# Admin upravy:

42
mamweb/templates/base.html

@ -131,6 +131,48 @@
$("a[rel^='gallery-image']").prettyPhoto(prettyparams);
});
</script>
{% if april == 2021 %}
<script type="text/javascript" charset="utf-8">
function rotace(vektor, uhel_deg) {
var uhel = uhel_deg *(Math.PI / 180);
var x = vektor[0];
var y = vektor[1];
return [x*Math.cos(uhel) - y*Math.sin(uhel), x*Math.sin(uhel) + y*Math.cos(uhel)];
}
function rotace_a_posun(obj, uhel) {
var ow = obj.width();
var oh = obj.height();
var rohy = [[0,0], [0,oh], [ow, 0], [ow, oh]];
var minx = 0;
var miny = 0;
for (var roh of rohy) {
var otoceny = rotace(roh, uhel);
if (otoceny[0] < minx) {
minx = otoceny[0];
}
if (otoceny[1] < miny) {
miny = otoceny[1];
}
}
miny *= -1;
minx *= -1;
var transf_str = "translateX("+minx+"px) translateY("+miny+"px) rotate("+uhel+"deg)";
obj.css('transform-origin', 'top left');
obj.css('transform', transf_str);
}
function randomUhel() {
return Math.floor(360*Math.random());
}
$('.container').css('margin', 0);
rotace_a_posun($('.container'), randomUhel());
</script>
{% endif %}
{% render_block "js" %}
</body>
</html>

22
seminar/forms.py

@ -142,6 +142,28 @@ class PrihlaskaForm(forms.Form):
elif data.get('skola_adresa')=='':
self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy'))
# Editační formulář bez řešitele.
class ProfileEditFormPoMaturite(forms.Form):
username = forms.CharField(label='Přihlašovací jméno',
max_length=256,
required=True)
jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)
pohlavi_muz = forms.ChoiceField(label='Pohlaví',
choices = ((True,'muž'),(False,'žena')), required=True)
email = forms.EmailField(label='E-mail',max_length=256, required=True)
telefon = forms.CharField(widget=TelInput(),label='Telefon',max_length=256, required=False)
datum_narozeni = forms.DateField(widget=DateInput(),label='Datum narození', required=False)
ulice = forms.CharField(label='Ulice', max_length=256, required=False)
mesto = forms.CharField(label='Město', max_length=256, required=False)
psc = forms.CharField(label='PSČ', max_length=32, required=False)
stat = forms.ChoiceField(label='Stát',
choices = (('CZ', 'Česká Republika'),
('SK', 'Slovenská Republika'),
('other', 'Jiné')),
required=False)
stat_text = forms.CharField(label='Stát', max_length=256, required=False)
class ProfileEditForm(forms.Form):
username = forms.CharField(label='Přihlašovací jméno',

61
seminar/migrations/0001_squashed_0067_auto_20190814_0805.py

@ -107,22 +107,50 @@ def spoj_k_organizatorum_osoby(apps, scema_editor):
for org in Organizator.objects.all():
# Spárování organizátora s osobou
# Myšlenka: Když najdeme řešitele pro daného uživatele, tak se vezme Osoba příslušná uživateli,
# Pokud nenajdeme uživatele, tak ještě zkusíme dohledat Osobu podle e-mailu
user = org.user
resitele = Resitel.objects.filter(user=user)
if resitele.count() != 0:
osoba = resitele.first().osoba
else:
if user is None:
logger.error(f'Org {org} nemá uživatele!')
# Je to podezřelé, ale prostě vyrobíme novou osobu.
osoba = Osoba(user=user)
# Přesun informací z usera do osoby
# pro řešitele již v minule migraci
osoba.jmeno = user.first_name
osoba.prijmeni = user.last_name
osoba.email = user.email
user.jmeno = "Použij osobu!"
user.prijmeni = "Použij osobu!"
user.email = "Použij osobu!"
user.save()
# Téhle osobě nejdou nastavit detaily, protože žádné nemáme.
else:
logger.info(f'Org {org.user.email}(ID: {org.id}) má uživatele {user}')
# 💢💢💢 Python nemá goto, ale prý má výjimky… 💢💢💢
class EndException(Exception): pass
try:
# Hledáme podle uživatele
resitele = Resitel.objects.filter(user=user)
if resitele.count() != 0 and user is not None:
osoba = resitele.first().osoba
logger.info(f'Našel jsem řešitele {resitele.first().email} podle uživatele, používám jeho Osobu')
raise EndException
# Hledáme podle e-mailu
osoby = Osoba.objects.filter(email__iexact=user.email)
if osoby.count() != 0 and user.email != '':
osoba = osoby.first()
if osoba.user is None:
osoba.user = user
logger.info(f'Našel jsem Osobu {osoby.first().email} podle e-mailu')
raise EndException
# Fallback
logger.warning(f'Org neměl řešitele, zakládám novou Osobu.')
osoba = Osoba(user=user)
# Přesun informací z usera do osoby
# pro osoby z řešitelů (jediné dosud existující osoby) již v minule migraci
osoba.jmeno = user.first_name
osoba.prijmeni = user.last_name
osoba.email = user.email
user.jmeno = "Použij osobu!"
user.prijmeni = "Použij osobu!"
user.email = "Použij osobu!"
user.save()
except EndException: pass
# Přesun informací z organizátora do jeho osoby
osoba.prezdivka = org.prezdivka if org.prezdivka is not None else ''
@ -142,7 +170,10 @@ def fix_problem(apps, schema_editor):
else:
pr.autor = None
if pr.opravovatel is not None:
pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first())
if Organizator.objects.filter(osoba__user=pr.opravovatel).first() is not None:
pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first())
else:
logger.error(f'WTF, nespárovaný opravovatel {pr.opravovatel} problému {pr}')
pr.save()
def fix_pohadka(apps, schema_editor):

13
seminar/migrations/0051_resitel_to_osoba.py

@ -28,26 +28,23 @@ def resitel_to_osoba(apps,schema_editor):
if u.first_name:
if not o.jmeno:
o.jmeno = u.first_name
u.first_name = 'Použij osobu!'
u.first_name += ' (Uživatel!)'
elif o.jmeno == u.first_name:
u.first_name = 'Použij osobu!'
u.first_name += ' (Uživatel!)'
else:
raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name))
if u.last_name:
if not o.prijmeni:
o.prijmeni = u.last_name
u.last_name = 'Použij osobu!'
u.last_name += ' (Uživatel!)'
elif o.prijmeni == u.last_name:
u.last_name = 'Použij osobu!'
u.last_name += ' (Uživatel!)'
else:
raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name))
if u.email:
if not o.email:
o.email = u.email
u.email = 'Použij osobu!'
elif o.email == u.email:
u.email = 'Použij osobu!'
else:
elif o.email != u.email:
raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email))
u.save()

62
seminar/migrations/0052_user_to_organizator.py

@ -4,6 +4,10 @@ from __future__ import unicode_literals
from django.db import migrations
import logging
logger = logging.getLogger(__name__)
def spoj_k_organizatorum_osoby(apps, scema_editor):
Organizator = apps.get_model('seminar', 'Organizator')
Resitel = apps.get_model('seminar', 'Resitel')
@ -11,22 +15,49 @@ def spoj_k_organizatorum_osoby(apps, scema_editor):
for org in Organizator.objects.all():
# Spárování organizátora s osobou
# Myšlenka: Když najdeme řešitele pro daného uživatele, tak se vezme Osoba příslušná uživateli,
# Pokud nenajdeme uživatele, tak ještě zkusíme dohledat Osobu podle e-mailu
user = org.user
resitele = Resitel.objects.filter(user=user)
if resitele.count() != 0:
osoba = resitele.first().osoba
else:
if user is None:
logger.error(f'Org {org} nemá uživatele!')
# Je to podezřelé, ale prostě vyrobíme novou osobu.
osoba = Osoba(user=user)
# Téhle osobě nejdou nastavit detaily, protože žádné nemáme.
else:
logger.info(f'Org {org.user.email}(ID: {org.id}) má uživatele {user}')
# 💢💢💢 Python nemá goto, ale prý má výjimky… 💢💢💢
class EndException(Exception): pass
try:
# Hledáme podle uživatele
resitele = Resitel.objects.filter(user=user)
if resitele.count() != 0 and user is not None:
osoba = resitele.first().osoba
logger.info(f'Našel jsem řešitele {resitele.first().email} podle uživatele, používám jeho Osobu')
raise EndException
# Hledáme podle e-mailu
osoby = Osoba.objects.filter(email__iexact=user.email)
if osoby.count() != 0 and user.email != '':
osoba = osoby.first()
if osoba.user is None:
osoba.user = user
logger.info(f'Našel jsem Osobu {osoby.first().email} podle e-mailu')
raise EndException
# Fallback
logger.warning(f'Org neměl řešitele, zakládám novou Osobu.')
osoba = Osoba(user=user)
# Přesun informací z usera do osoby
# pro osoby z řešitelů (jediné dosud existující osoby) již v minule migraci
osoba.jmeno = user.first_name
osoba.prijmeni = user.last_name
osoba.email = user.email
user.jmeno += " (Uživatel!)"
user.prijmeni += " (Uživatel!)"
user.save()
# Přesun informací z usera do osoby
# pro řešitele již v minule migraci
osoba.jmeno = user.first_name
osoba.prijmeni = user.last_name
osoba.email = user.email
user.jmeno = "Použij osobu!"
user.prijmeni = "Použij osobu!"
user.email = "Použij osobu!"
user.save()
except EndException: pass
# Přesun informací z organizátora do jeho osoby
osoba.prezdivka = org.prezdivka if org.prezdivka is not None else ''
@ -46,7 +77,10 @@ def fix_problem(apps, schema_editor):
else:
pr.autor = None
if pr.opravovatel is not None:
pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first())
if Organizator.objects.filter(osoba__user=pr.opravovatel).first() is not None:
pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first())
else:
logger.error(f'WTF, nespárovaný opravovatel {pr.opravovatel} problému {pr}')
pr.save()
def fix_pohadka(apps, schema_editor):

19
seminar/models.py

@ -602,13 +602,18 @@ class Cislo(SeminarModelBase):
png_filename = pathlib.Path(tempfile.mkdtemp(), 'nahled.png')
subprocess.run([
"convert",
"-density", "300x300",
"-geometry", "{}x{}".format(VYSKA, sirka),
"-background", "white",
"-flatten",
"{}[0]".format(self.pdf.path), # titulní strana
png_filename
"gs",
"-sstdout=%stderr",
"-dSAFER",
"-dNOPAUSE",
"-dBATCH",
"-dNOPROMPT",
"-sDEVICE=pngalpha",
"-r{}x{}".format(VYSKA, sirka),
"-dFirstPage=1d",
"-dLastPage=1d",
"-sOutputFile=" + str(png_filename),
"-f%s" % self.pdf.path
],
check=True,
capture_output=True

5
seminar/templates/seminar/odevzdavatko/detail.html

@ -1,5 +1,6 @@
{% extends "base.html" %}
{% load static %}
{% load deadliny %}
{% block content %}
@ -62,7 +63,9 @@ $(document).ready(function(){
<p>Řešitelé: {{ object.resitele.all | join:", " }}</p>
{# https://docs.djangoproject.com/en/3.1/ref/models/instances/#django.db.models.Model.get_FOO_display #}
<p>Forma: {{ object.get_forma_display }}, doručeno {{ object.cas_doruceni }}</p>
<p>Forma: {{ object.get_forma_display }}</p>
<p>Doručeno {{ object.cas_doruceni }}, deadline: {{object.cas_doruceni | deadline_html }}</p>
{# Soubory: #}
<h3>Přílohy:</h3>

38
seminar/templates/seminar/odevzdavatko/resitel_prehled.html

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% load static %}
{% load deadliny %}
{% block custom_css %}
<style type=text/css>
.dosla_reseni tr th {
text-align: center;
}
.dosla_reseni tr th, .dosla_reseni tr td {
border: 1px solid black;
padding: 1px 10px 1px 10px;
border-collapse: collapse;
}
</style>
{% endblock custom_css %}
{% block content %}
{% for rocnik, hodnoceni in podle_rocniku %}
<h1>Ročník {{ rocnik }}</h1>
<table class="dosla_reseni">
<tr>
<th>Doručeno</th>
<th>Problém</th>
<th>Body</th>
<th>Deadline</th>
</tr>
{% for hodn in hodnoceni %}
<tr>
<td>{{ hodn.reseni.cas_doruceni }}</td>
<td>{{ hodn.problem }}</td>
<td>{{ hodn.body|default_if_none:"---" }}</td>
<td>{{ hodn.reseni.cas_doruceni | deadline_html }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% endblock %}

6
seminar/templates/seminar/odevzdavatko/seznam.html

@ -1,11 +1,15 @@
{% extends "base.html" %}
{% load deadliny %}
{% block content %}
{% for dl, mnozina_reseni in reseni_podle_deadlinu.items %}
<h1>{{ dl.2 | deadline_html }}</h1>
<ul>
{% for obj in object_list %}
{% for obj in mnozina_reseni %}
<li><a href="{% url 'odevzdavatko_detail_reseni' pk=obj.id %}">{{ obj }}</a> ({{ obj.get_forma_display }} {{ obj.cas_doruceni }})
{% endfor %}
</ul>
{% endfor %}
{% endblock %}

2
seminar/templates/seminar/profil/edit.html

@ -61,6 +61,7 @@
{% include "seminar/profil/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
</table>
{% if not po_maturite %} {# Vysloužilým účastníkům skrýt editaci školy apod. #}
<hr>
<h4>
@ -95,6 +96,7 @@
</table>
<hr>
{% endif %}
<input type="submit" value="Změnit">
</form>

1
seminar/templates/seminar/profil/resitel.html

@ -11,6 +11,7 @@
<a href="{% url 'logout' %}">Odhlásit se</a><br>
<a href="{% url 'seminar_resitel_edit' %}">Upravit údaje</a><br>
<a href="{% url 'seminar_resitel_odevzdana_reseni' %}">Odevzdaná řešení</a><br>
{% endblock %}

35
seminar/templatetags/deadliny.py

@ -0,0 +1,35 @@
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):
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]
@register.filter(name='deadline_kratseji')
def deadline_kratsi_text(datum):
typ, cislo, dl = deadline(datum)
strings = {
TypDeadline.PredDeadline: f"1. deadline {cislo}",
TypDeadline.SousDeadline: f"Soustřeďkový deadline {cislo}",
TypDeadline.FinalDeadline: f"Finální deadline {cislo}",
}
return strings[typ]
@register.filter(name='deadline_html')
def deadline_html(datum):
typ, _, _ = deadline(datum)
text = deadline_kratsi_text(datum)
classes = {
TypDeadline.PredDeadline: 'preddeadline',
TypDeadline.SousDeadline: 'sous_deadline',
TypDeadline.FinalDeadline: 'final_deadline',
}
return mark_safe(f'<span class="{classes[typ]}">{text}</span>')

1
seminar/urls.py

@ -135,6 +135,7 @@ urlpatterns = [
path('prihlasit/', views.LoginView.as_view(), name='login'),
path('odhlasit/', views.LogoutView.as_view(), name='logout'),
path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'),
path('resitel/odevzdana_reseni/', resitel_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'),
path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'),
path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'),
path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),

14
seminar/utils.py

@ -309,7 +309,7 @@ def deadline_v_rocniku(datum, rocnik):
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:
if datum <= dl[2]:
# První takový deadline je ten nejtěsnější
return dl
@ -319,20 +319,22 @@ def deadline(datum):
Vrací trojici (TypDeadline, Cislo, datumDeadline: date).
"""
if isinstance(datum, datetime.datetime):
datum = datum.date()
rok = datum.year
# Dva ročníky podezřelé z obsahování dat
pozdejsi_rocnik = m.Rocnik.filter(prvni_rok=rok)
drivejsi_rocnik = m.Rocnik.filter(druhy_rok=rok)
if any(
pozdejsi_rocnik = m.Rocnik.objects.filter(prvni_rok=rok)
drivejsi_rocnik = m.Rocnik.objects.filter(prvni_rok=rok-1)
if any([
pozdejsi_rocnik.count() > 1,
drivejsi_rocnik.count() > 1,
):
]):
raise ValueError(f"Více ročníků začíná/končí stejným rokem: {rok}")
pozdejsi_rocnik = pozdejsi_rocnik.first() if pozdejsi_rocnik.count() > 0 else None
drivejsi_rocnik = drivejsi_rocnik.first() if drivejsi_rocnik.count() > 0 else None
# Předpokládáme, že neexistuje číslo, které má deadline ale nemá finální deadline.
posledni_deadline_drivejsiho_rocniku = m.Cislo.objects.get(rocnik=drivejsi_rocnik, datum_deadline__isnull=False).datum_deadline
posledni_deadline_drivejsiho_rocniku = m.Cislo.objects.filter(rocnik=drivejsi_rocnik, datum_deadline__isnull=False).last().datum_deadline
if datum <= posledni_deadline_drivejsiho_rocniku:
return deadline_v_rocniku(datum, drivejsi_rocnik)

37
seminar/views/odevzdavatko.py

@ -8,12 +8,13 @@ from django.db import transaction
from dataclasses import dataclass
import datetime
from itertools import groupby
import logging
import seminar.models as m
import seminar.forms as f
from seminar.forms import OdevzdavatkoTabulkaFiltrForm as FiltrForm
from seminar.utils import aktivniResitele, resi_v_rocniku
from seminar.utils import aktivniResitele, resi_v_rocniku, deadline
logger = logging.getLogger(__name__)
@ -24,6 +25,8 @@ logger = logging.getLogger(__name__)
# - ReseniProblemuView
# - Detail konkrétního řešení -- všechny soubory, datum, ...
# - DetailReseniView
# - Pro řešitele: přehled jejich odevzdaných řešení
# - PrehledOdevzdanychReseni
#
# Taky se může hodit:
# - Tabulka všech řešitelů x všech problémů?
@ -169,7 +172,14 @@ class ReseniProblemuView(MultipleObjectTemplateResponseMixin, MultipleObjectMixi
return redirect(reverse("odevzdavatko_detail_reseni", kwargs={"pk": jedine_reseni.id}))
context = self.get_context_data()
return self.render_to_response(context)
# Kontext automaticky?
def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
# XXX: Předat groupby do template nejde: https://stackoverflow.com/questions/6906593/itertools-groupby-in-a-django-template
# Django má {% regroup %}, ale ten potřebuje, aby klíč byl atribut položky: https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#regroup
# Takže rozbalíme groupby do slovníku klíč → seznam sami (dictionary comphrehension)
ctx['reseni_podle_deadlinu'] = {k: list(v) for k,v in groupby(ctx['object_list'], lambda r: deadline(r.cas_doruceni))}
return ctx
## XXX: https://docs.djangoproject.com/en/3.1/topics/class-based-views/mixins/#avoid-anything-more-complex
class DetailReseniView(DetailView):
@ -230,6 +240,29 @@ def hodnoceniReseniView(request, pk, *args, **kwargs):
return redirect(success_url)
class PrehledOdevzdanychReseni(ListView):
model = m.Hodnoceni
template_name = 'seminar/odevzdavatko/resitel_prehled.html'
def get_queryset(self):
if not self.request.user.is_authenticated:
raise RuntimeError("Uživatel měl být přihlášený!")
resitel = m.Resitel.objects.get(osoba__user=self.request.user)
qs = super().get_queryset()
qs = qs.filter(reseni__resitele__in=[resitel])
return qs
def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
# Ročník určujeme podle čísla, do jehož deadlinu došlo řešení.
# Chceme to mít seřazené, takže místo comphrerehsion ručně postavíme pole polí. Django templates neumí použít OrderedDict :-/
podle_rocniku = []
for rocnik, hodnoceni in groupby(ctx['object_list'], lambda ho: deadline(ho.reseni.cas_doruceni)[1].rocnik):
podle_rocniku.append((rocnik, list(hodnoceni)))
ctx['podle_rocniku'] = reversed(podle_rocniku) # Od nejnovějšího ročníku
# TODO: Umožnit stažení / zobrazení řešení
return ctx
# Přehled všech řešení kvůli debugování
class SeznamReseniView(ListView):

21
seminar/views/views_all.py

@ -26,7 +26,7 @@ import seminar.models as m
from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
from seminar import utils, treelib
from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm
from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm, ProfileEditFormPoMaturite
import seminar.forms as f
import seminar.templatetags.treenodes as tnltt
import seminar.views.views_rest as vr
@ -1095,15 +1095,23 @@ def resitelEditView(request):
user_edit = osoba_edit.user
## Vytvoření slovníku, kterým předvyplním formulář
prefill_1=model_to_dict(user_edit)
if resitel_edit:
if resitel_edit and resitel_edit.rok_maturity >= date.today().year:
prefill_2=model_to_dict(resitel_edit)
prefill_1.update(prefill_2)
prefill_3=model_to_dict(osoba_edit)
prefill_1.update(prefill_3)
form = ProfileEditForm(initial=prefill_1)
if 'datum_narozeni' in prefill_1:
prefill_1['datum_narozeni'] = str(prefill_1['datum_narozeni'])
if resitel_edit and resitel_edit.rok_maturity < date.today().year:
form = ProfileEditFormPoMaturite(initial=prefill_1)
else:
form = ProfileEditForm(initial=prefill_1)
## Změna údajů a jejich uložení
if request.method == 'POST':
form = ProfileEditForm(request.POST)
if resitel_edit and resitel_edit.rok_maturity < date.today().year:
form = ProfileEditFormPoMaturite(request.POST)
else:
form = ProfileEditForm(request.POST)
if form.is_valid():
## Změny v osobě
fcd = form.cleaned_data
@ -1115,6 +1123,7 @@ def resitelEditView(request):
osoba_edit.ulice = fcd['ulice']
osoba_edit.mesto = fcd['mesto']
osoba_edit.psc = fcd['psc']
osoba_edit.datum_narozeni = fcd['datum_narozeni']
## Změny v osobě s podmínkami
if fcd.get('spam',False):
osoba_edit.datum_souhlasu_zasilani = date.today()
@ -1124,7 +1133,7 @@ def resitelEditView(request):
## Neznámá země
msg = "Unknown country {}".format(fcd['stat_text'])
if resitel_edit:
if resitel_edit and resitel_edit.rok_maturity >= date.today().year:
## Změny v řešiteli
resitel_edit.skola = fcd['skola']
resitel_edit.rok_maturity = fcd['rok_maturity']
@ -1140,7 +1149,7 @@ def resitelEditView(request):
return formularOKView(request)
else:
## Stránka před odeslaním formuláře = předvyplněný formulář
return render(request, 'seminar/profil/edit.html', {'form': form})
return render(request, 'seminar/profil/edit.html', {'form': form, 'po_maturite': resitel_edit and resitel_edit.rok_maturity < date.today().year})
def prihlaskaView(request):
generic_logger = logging.getLogger('seminar.prihlaska')

0
various/__init__.py

3
various/admin.py

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
various/apps.py

@ -0,0 +1,5 @@
from django.apps import AppConfig
class VariousConfig(AppConfig):
name = 'various'

14
various/context_processors.py

@ -0,0 +1,14 @@
def april(req):
if 'X-April' in req.headers:
try:
year = int(req.headers['X-April'])
return {'april': year}
except:
pass # Fall-back to regular behaviour
import datetime
today = datetime.date.today()
if today.day == 1 and today.month == 4:
return {'april': today.year}
return {}

0
various/migrations/__init__.py

3
various/models.py

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
various/tests.py

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
various/views.py

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
Loading…
Cancel
Save