diff --git a/Makefile b/Makefile index 12b49069..afe1221d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean_env init_env clean_virtualenv install_packages clean install run all schema_seminar.pdf schema_all.pdf PYTHON=python2.7 -VE_VER=12.0.7 +VE_VER=13.1.2 LOCAL_PYTHON=bin/python all: install @@ -17,7 +17,7 @@ make_env: ${LOCAL_PYTHON} # phony, but fast repeated execution install_packages: make_env - bin/pip install -r requirements.txt + bin/pip install -r requirements.txt --upgrade # phony clean_env: @@ -35,12 +35,13 @@ ${LOCAL_PYTHON}: virtualenv virtualenv: curl -O https://pypi.python.org/packages/source/v/virtualenv/virtualenv-${VE_VER}.tar.gz tar xvfz virtualenv-${VE_VER}.tar.gz - mv virtualenv-${VE_VER} virtualenv + mv -T virtualenv-${VE_VER} virtualenv rm virtualenv-${VE_VER}.tar.gz # phony clean_virtualenv: rm -rf virtualenv/ + rm -rf virtualenv-*.tar.gz run: ./manage.py runserver_plus @@ -60,21 +61,24 @@ schema_all.pdf: # Deploy to current *mamweb-test* directory deploy_test: - @if [[ `pwd` != "/akce/MaM/WWW/mamweb-test" ]]; then echo "Only possible in /akce/MaM/WWW/mamweb-test"; exit 1; fi + @if [ ${USER} != "www-mam" ]; then echo "Only possible by user www-mam"; exit 1; fi + @if [ `pwd` != "/akce/MaM/WWW/mamweb-test" ]; then echo "Only possible in /akce/MaM/WWW/mamweb-test"; exit 1; fi @echo "Installing version from origin/master ..." git pull origin master git clean -f make install ./manage.py migrate ./manage.py collectstatic --noinput - (chown -Rf :mam . || true ) - (chmod -Rf g+w . || true ) + (chown -R :mam . || true ) + (chmod -R g+rX,go-w . || true ) + @echo Notifying apache about the change ... touch mamweb/wsgi.py @echo Done. # Deploy to current *mamweb-prod* directory deploy_prod: - @if [[ `pwd` != "/akce/MaM/WWW/mamweb-prod" ]]; then echo "Only possible in /akce/MaM/WWW/mamweb-prod"; exit 1; fi + @if [ ${USER} != "www-mam" ]; then echo "Only possible by user www-mam"; exit 1; fi + @if [ `pwd` != "/akce/MaM/WWW/mamweb-prod" ]; then echo "Only possible in /akce/MaM/WWW/mamweb-prod"; exit 1; fi @echo "Backing up production DB ..." ( cd .. && ./backup_prod_db.sh ) @echo "Installing version from origin/stable ..." @@ -83,8 +87,9 @@ deploy_prod: make install ./manage.py migrate ./manage.py collectstatic --noinput - (chown -Rf :mam . || true ) - (chmod -Rf g+w . || true ) + (chown -R :mam . || true ) + (chmod -R g+rX,go-w . || true ) + @echo Notifying apache about the change ... touch mamweb/wsgi.py @echo Done. diff --git a/mamweb/context_processors.py b/mamweb/context_processors.py new file mode 100644 index 00000000..ec6481df --- /dev/null +++ b/mamweb/context_processors.py @@ -0,0 +1,12 @@ + +from datetime import datetime, date + +def vzhled(request): + ''' Podle casu prida do templatu, zdali je nebo neni noc ''' + hodin = datetime.now().hour + if (hodin <= 6) or (hodin >= 20): + noc = True + else: + noc = False + return {'noc' : noc} + diff --git a/mamweb/middleware.py b/mamweb/middleware.py new file mode 100644 index 00000000..5e5dc33e --- /dev/null +++ b/mamweb/middleware.py @@ -0,0 +1,84 @@ +from datetime import datetime, date + +from django.conf import settings +from django.http import HttpResponse, HttpResponseRedirect + + + +class LoggedInHintCookieMiddleware(object): + """Middleware to securely help with 'logged-in' detection for dual HTTP/HTTPS sites. + + On insecure requests: Checks for a (non-secure) cookie settings.LOGGED_IN_HINT_COOKIE_NAME + and if present, redirects to HTTPS (same adress). + Note this usually breaks non-GET (POST) requests. + + On secure requests: Updates cookie settings.LOGGED_IN_HINT_COOKIE_NAME to reflect + whether an user is logged in in the current session (cookie set to 'True' or cleared). + The cookie is set to expire at the same time as the sessionid cookie. + + By default, LOGGED_IN_HINT_COOKIE_NAME = 'logged_in_hint'. + """ + + def __init__(self): + if hasattr(settings, 'LOGGED_IN_HINT_COOKIE_NAME'): + self.cookie_name = settings.LOGGED_IN_HINT_COOKIE_NAME + else: self.cookie_name = 'logged_in_hint' + self.cookie_value = 'True' + + def cookie_correct(self, request): + return self.cookie_name in request.COOKIES and request.COOKIES[self.cookie_name] == self.cookie_value + + def process_request(self, request): + if not request.is_secure(): + if self.cookie_correct(request): + # redirect insecure (assuming http) requests with hint cookie to https + url = HttpRequest.build_absolute_uri() + assert url[:5] == 'http:' + return HttpResponseRedirect('https:' + url[5:]) + return None + + def process_response(self, request, response): + if request.is_secure(): + # assuming full session info (as the conn. is secure) + if request.user.is_authenticated(): + if not self.cookie_correct(request): + expiry = None if request.session.get_expire_at_browser_close() else request.session.get_expiry_date() + response.set_cookie(self.cookie_name, value=self.cookie_value, expires=expiry, secure=False) + else: + if self.cookie_name in request.COOKIES: + response.delete_cookie(self.cookie_name) + return response + + +class vzhled: + + def process_request(self, request): + return None + + def process_view(self, request, view_func, view_args, view_kwargs): + #print "====== process_request ======" + #print view_func + #print view_args + #print view_kwargs + #print "=============================" + return None + + def process_template_response(self, request, response): + hodin = datetime.now().hour + if (hodin <= 6) or (hodin >= 14): # TODO 20 + response.context_data['noc'] = True + else: + response.context_data['noc'] = False + return response + + def process_response(self, request, response): + #hodin = datetime.now().hour + #if (hodin <= 6) or (hodin >= 14): # TODO 20 + #response.context_data['noc'] = True + #else: + #response.context_data['noc'] = False + return response + + + ##def process_exception(request, exception): + #pass diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index a46085cf..71f16b9f 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -60,6 +60,7 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', + 'mamweb.middleware.LoggedInHintCookieMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', @@ -78,6 +79,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.tz', 'sekizai.context_processors.sekizai', 'django.core.context_processors.static', + 'mamweb.context_processors.vzhled', ) INSTALLED_APPS = ( diff --git a/mamweb/settings_prod.py b/mamweb/settings_prod.py index 8535389d..eaf18db2 100644 --- a/mamweb/settings_prod.py +++ b/mamweb/settings_prod.py @@ -47,12 +47,18 @@ import os SERVER_EMAIL = 'mamweb-prod-errors@mam.mff.cuni.cz' ADMINS = [ - ('Tomas Gavenciak', 'gavento@ucw.cz'), ('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'), ('Matěj Kocián', 'matej.kocian@gmail.com'), ] +# SECURITY: only send sensitive cookies via HTTPS + +SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SECURE = True + + + # LOGGING = { # 'version': 1, # 'disable_existing_loggers': True, diff --git a/mamweb/settings_test.py b/mamweb/settings_test.py index f18a419f..a628be47 100644 --- a/mamweb/settings_test.py +++ b/mamweb/settings_test.py @@ -25,11 +25,11 @@ INSTALLED_APPS += ( SECRET_KEY = ')^u=i65*zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzv9l+zo)n' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = False -TEMPLATE_DEBUG = True +TEMPLATE_DEBUG = False -ALLOWED_HOSTS = ['*.mam.mff.cuni.cz'] +ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni.cz'] # Database # https://docs.djangoproject.com/en/1.7/ref/settings/#databases @@ -45,6 +45,18 @@ DATABASES = { }, } +import os + +SERVER_EMAIL = 'mamweb-test-errors@mam.mff.cuni.cz' +ADMINS = [ + ('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'), +] + + +# SECURITY: only send sensitive cookies via HTTPS + +SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SECURE = True diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index 73adcb29..2d0a283f 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -58,16 +58,24 @@ h2 { #header { position: relative; font-size: 250%; - background: url("../images/header-bg-uvod.png") no-repeat center top; + background: url("../images/header-bg-uvod.jpg") no-repeat center top; height: 255px; top: -1px; } -#header.cojemam { background-image: url("../images/header-bg-uvod.png"); } -#header.soustredeni { background-image: url("../images/header-bg-soustredeni.png"); } -#header.zadani { background-image: url("../images/header-bg-zadani.png"); } -#header.clanky { background-image: url("../images/header-bg-clanek.png"); } -#header.archiv { background-image: url("../images/header-bg-archiv.png"); } + +#header.cojemam { background-image: url("../images/header-bg-uvod.jpg"); } +#header.soustredeni { background-image: url("../images/header-bg-soustredeni.jpg"); } +#header.zadani { background-image: url("../images/header-bg-zadani.jpg"); } +#header.clanky { background-image: url("../images/header-bg-clanek.jpg"); } +#header.archiv { background-image: url("../images/header-bg-archiv.jpg"); } + +#header.NOC {background-image: url("../images/header-bg-uvod-NOC.jpg"); } +#header.NOCcojemam { background-image: url("../images/header-bg-uvod-NOC.jpg"); } +#header.NOCsoustredeni { background-image: url("../images/header-bg-soustredeni-NOC.jpg"); } +#header.NOCzadani { background-image: url("../images/header-bg-zadani-NOC.jpg"); } +#header.NOCclanky { background-image: url("../images/header-bg-clanek-NOC.jpg"); } +#header.NOCarchiv { background-image: url("../images/header-bg-archiv-NOC.jpg"); } #header img.logo { position: absolute; diff --git a/mamweb/static/images/header-bg-archiv-NOC.jpg b/mamweb/static/images/header-bg-archiv-NOC.jpg new file mode 100644 index 00000000..d3732d92 Binary files /dev/null and b/mamweb/static/images/header-bg-archiv-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-archiv.jpg b/mamweb/static/images/header-bg-archiv.jpg new file mode 100644 index 00000000..6f00a321 Binary files /dev/null and b/mamweb/static/images/header-bg-archiv.jpg differ diff --git a/mamweb/static/images/header-bg-archiv.png b/mamweb/static/images/header-bg-archiv.png deleted file mode 100644 index 32870431..00000000 Binary files a/mamweb/static/images/header-bg-archiv.png and /dev/null differ diff --git a/mamweb/static/images/header-bg-clanek-NOC.jpg b/mamweb/static/images/header-bg-clanek-NOC.jpg new file mode 100644 index 00000000..6c21cf02 Binary files /dev/null and b/mamweb/static/images/header-bg-clanek-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-clanek.jpg b/mamweb/static/images/header-bg-clanek.jpg new file mode 100644 index 00000000..29077929 Binary files /dev/null and b/mamweb/static/images/header-bg-clanek.jpg differ diff --git a/mamweb/static/images/header-bg-clanek.png b/mamweb/static/images/header-bg-clanek.png deleted file mode 100644 index 95576fe6..00000000 Binary files a/mamweb/static/images/header-bg-clanek.png and /dev/null differ diff --git a/mamweb/static/images/header-bg-odevzdat-NOC.jpg b/mamweb/static/images/header-bg-odevzdat-NOC.jpg new file mode 100644 index 00000000..3697993b Binary files /dev/null and b/mamweb/static/images/header-bg-odevzdat-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-soustredeni-NOC.jpg b/mamweb/static/images/header-bg-soustredeni-NOC.jpg new file mode 100644 index 00000000..f950069c Binary files /dev/null and b/mamweb/static/images/header-bg-soustredeni-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-soustredeni.jpg b/mamweb/static/images/header-bg-soustredeni.jpg new file mode 100644 index 00000000..a4f4121f Binary files /dev/null and b/mamweb/static/images/header-bg-soustredeni.jpg differ diff --git a/mamweb/static/images/header-bg-soustredeni.png b/mamweb/static/images/header-bg-soustredeni.png deleted file mode 100644 index 00df5e42..00000000 Binary files a/mamweb/static/images/header-bg-soustredeni.png and /dev/null differ diff --git a/mamweb/static/images/header-bg-uvod-NOC.jpg b/mamweb/static/images/header-bg-uvod-NOC.jpg new file mode 100644 index 00000000..6963bf83 Binary files /dev/null and b/mamweb/static/images/header-bg-uvod-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-uvod.jpg b/mamweb/static/images/header-bg-uvod.jpg new file mode 100644 index 00000000..0236ce5e Binary files /dev/null and b/mamweb/static/images/header-bg-uvod.jpg differ diff --git a/mamweb/static/images/header-bg-uvod.png b/mamweb/static/images/header-bg-uvod.png deleted file mode 100644 index 532d9941..00000000 Binary files a/mamweb/static/images/header-bg-uvod.png and /dev/null differ diff --git a/mamweb/static/images/header-bg-zadani-NOC.jpg b/mamweb/static/images/header-bg-zadani-NOC.jpg new file mode 100644 index 00000000..fa2c27b3 Binary files /dev/null and b/mamweb/static/images/header-bg-zadani-NOC.jpg differ diff --git a/mamweb/static/images/header-bg-zadani.jpg b/mamweb/static/images/header-bg-zadani.jpg new file mode 100644 index 00000000..e06a3d02 Binary files /dev/null and b/mamweb/static/images/header-bg-zadani.jpg differ diff --git a/mamweb/static/images/header-bg-zadani.png b/mamweb/static/images/header-bg-zadani.png deleted file mode 100644 index 291c46bb..00000000 Binary files a/mamweb/static/images/header-bg-zadani.png and /dev/null differ diff --git a/mamweb/static/images/header-bg.jpg b/mamweb/static/images/header-bg.jpg new file mode 100644 index 00000000..b6e22870 Binary files /dev/null and b/mamweb/static/images/header-bg.jpg differ diff --git a/mamweb/static/images/header-bg.png b/mamweb/static/images/header-bg.png deleted file mode 100644 index eeb35d6b..00000000 Binary files a/mamweb/static/images/header-bg.png and /dev/null differ diff --git a/mamweb/templates/400.html b/mamweb/templates/400.html new file mode 100644 index 00000000..6c1c7b93 --- /dev/null +++ b/mamweb/templates/400.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% load staticfiles %} + +{% block content %} +

+ {% block nadpis1a %}{% block nadpis1b %} + O-jo-jo-jo-joj + {% endblock %}{% endblock %} +

+ +

+ Chybička se vloudila. + Zkuste přejít na titulní stránku + nebo se podívat na aktuální zadání. +

+ +{% endblock %} + diff --git a/mamweb/templates/403.html b/mamweb/templates/403.html new file mode 100644 index 00000000..873f599e --- /dev/null +++ b/mamweb/templates/403.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% load staticfiles %} + +{% block content %} +

+ {% block nadpis1a %}{% block nadpis1b %} + Vrrrrrrrrr + {% endblock %}{% endblock %} +

+ +

+ Tady pravděpodobně nemáte co dělat. + Zkuste přejít na titulní stránku + nebo se podívat na aktuální zadání. +

+ +{% endblock %} + diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index 6073ac99..a97d5168 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -48,7 +48,7 @@
- diff --git a/seminar/templates/seminar/cojemam/organizatori.html b/seminar/templates/seminar/cojemam/organizatori.html index 12f3a506..0111cd20 100644 --- a/seminar/templates/seminar/cojemam/organizatori.html +++ b/seminar/templates/seminar/cojemam/organizatori.html @@ -53,7 +53,7 @@ Aktivní v letech {{org.organizuje_od_roku | default:"?" }}–{{org.organizuje_do_roku | default:"?" }} {% endif %} {% if org.studuje %} -
  • Studuje: {{org.studuje}} +
  • {{org.studuje}} {% endif %} {% if org.user.email %}
  • Pošta: diff --git a/seminar/templates/seminar/vysledkovka_rocnik.html b/seminar/templates/seminar/vysledkovka_rocnik.html new file mode 100644 index 00000000..f1dc1d79 --- /dev/null +++ b/seminar/templates/seminar/vysledkovka_rocnik.html @@ -0,0 +1,29 @@ + + + + +{% endfor %} +
    # + Jméno + R. + Odjakživa + {% for c in vysledkovka.cisla %} + + {{c.rocnik.rocnik}}.{{ c.cislo }} + {% endfor %} + Celkem + +{% for rv in vysledkovka.radky %} +
    {% autoescape off %}{{ rv.poradi }}{% endautoescape %} + + {% if rv.titul %} + {{ rv.titul }}MM + {% endif %} + {{ rv.resitel.plne_jmeno }} + {{ rv.resitel.rocnik }} + {{ rv.body_odjakziva }} + {% for b in rv.body_cisla %} + {{ b }} + {% endfor %} + {{ rv.body_rocnik }} +
    diff --git a/seminar/templates/seminar/zadani/AktualniVysledkovka.html b/seminar/templates/seminar/zadani/AktualniVysledkovka.html new file mode 100644 index 00000000..9996b567 --- /dev/null +++ b/seminar/templates/seminar/zadani/AktualniVysledkovka.html @@ -0,0 +1,35 @@ +{% extends "seminar/zadani/base.html" %} + +{% block submenu %} + {% with "vysledkova-listina" as selected %} + {% include 'seminar/zadani/submenu.html' %} + {% endwith %} +{% endblock submenu %} + + +{% block content %} +{% with nastaveni.aktualni_rocnik as rocnik %} + +

    + {% block nadpis1a %}{% block nadpis1b %} + Výsledky + {% endblock %}{% endblock %} +

    + + {% if vysledkovka %} + {% include "seminar/vysledkovka_rocnik.html" %} + {% else %} + V tomto ročníku zatím žádné výsledky nejsou + {% endif %} + + {% if user.is_staff and vysledkovka_s_neverejnymi %} +
    +

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

    + {% with vysledkovka_s_neverejnymi as vysledkovka %} + {% include "seminar/vysledkovka_rocnik.html" %} + {% endwith %} +
    + {% endif %} + +{% endwith %} +{% endblock content %} diff --git a/seminar/templates/seminar/zadani/AktualniZadani.html b/seminar/templates/seminar/zadani/AktualniZadani.html index ffca40bf..ff6c3cd3 100644 --- a/seminar/templates/seminar/zadani/AktualniZadani.html +++ b/seminar/templates/seminar/zadani/AktualniZadani.html @@ -18,8 +18,6 @@ {% if ac.zadane_problemy.all %}
    Termín odeslání {{ac.cislo}}. série: {{ac.datum_deadline}} -
    - Termín odeslání 1. série pro účast na soustředění: 21. září 2015
    {% endif %} {#TODO a co speciální deadline pro účast na soustředění? #} diff --git a/seminar/urls.py b/seminar/urls.py index 1af3d42a..be4947c6 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -19,6 +19,7 @@ urlpatterns = patterns('', url(r'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'), url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'), + url(r'^zadani/vysledkova-listina/$', views.ZadaniAktualniVysledkovkaView, name='seminar_vysledky'), url(r'^$', views.TitulniStranaView.as_view(), name='titulni_strana'), url(r'^stare-novinky/$', views.StareNovinkyView.as_view(), name='stare_novinky'), diff --git a/seminar/views.py b/seminar/views.py index 955668e4..eb3e0616 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -15,17 +15,22 @@ from datetime import timedelta, date, datetime from itertools import groupby +def verejna_temata(rocnik): + """Vrací queryset zveřejněných témat v daném ročníku. + """ + return Problem.objects.filter(typ=Problem.TYP_TEMA, cislo_zadani__rocnik=rocnik, cislo_zadani__verejne_db=True).order_by('kod') + + def AktualniZadaniView(request): nastaveni = get_object_or_404(Nastaveni) problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany') ulohy = problemy.filter(typ = 'uloha').order_by('kod') serialy = problemy.filter(typ = 'serial').order_by('kod') - temata = problemy.filter(typ = 'tema').order_by('kod') jednorazove_problemy = [ulohy, serialy] return render(request, 'seminar/zadani/AktualniZadani.html', {'nastaveni': nastaveni, 'jednorazove_problemy': jednorazove_problemy, - 'temata': temata, + 'temata': verejna_temata(nastaveni.aktualni_rocnik), }, ) @@ -33,10 +38,23 @@ def ZadaniTemataView(request): nastaveni = get_object_or_404(Nastaveni) return render(request, 'seminar/zadani/Temata.html', { - 'temata': Problem.objects.filter(typ=Problem.TYP_TEMA, stav=Problem.STAV_ZADANY, cislo_zadani__rocnik=nastaveni.aktualni_rocnik).order_by('kod'), + 'temata': verejna_temata(nastaveni.aktualni_rocnik) + } + ) + +def ZadaniAktualniVysledkovkaView(request): + nastaveni = get_object_or_404(Nastaveni) + vysledkovka = vysledkovka_rocniku(nastaveni.aktualni_rocnik) + vysledkovka_s_neverejnymi = vysledkovka_rocniku(nastaveni.aktualni_rocnik, jen_verejne=False) + return render(request, 'seminar/zadani/AktualniVysledkovka.html', + { + 'nastaveni': nastaveni, + 'vysledkovka': vysledkovka, + 'vysledkovka_s_neverejnymi': vysledkovka_s_neverejnymi, } ) + ### Titulni strana class TitulniStranaView(generic.ListView): @@ -110,6 +128,63 @@ def sloupec_s_poradim(vysledky): return poradi_l +def vysledkovka_rocniku(rocnik, jen_verejne=True): + """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve + formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" + """ + + #vyberu vsechny vysledky z rocniku + cisla_v_rocniku = VysledkyKCisluZaRocnik.objects.filter(cislo__rocnik=rocnik).order_by('cislo') + if jen_verejne: + cisla_v_rocniku = cisla_v_rocniku.filter(cislo__verejna_vysledkovka=True) + + #pokud žádné nejsou, výsledkovka se nezobrazí + if not cisla_v_rocniku: + return None + + #vybere vsechny vysledky z posledniho (verejneho) cisla a setridi sestupne dle bodu + vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].cislo).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) + + class Vysledkovka: + def __init__(self): + self.radky = [] + self.cisla = [] + + vysledkovka = Vysledkovka() + vysledkovka.cisla = (rocnik.verejne_vysledkovky_cisla() if jen_verejne else rocnik.cisla.all().order_by('cislo')) + + # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině + for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky): + v.poradi = poradi + v.resitel.rocnik = v.resitel.rocnik(rocnik) + + verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].cislo) + if jen_verejne: + verejne_vysl_odjakziva = verejne_vysl_odjakziva.filter(cislo__verejna_vysledkovka=True) + + v.body_odjakziva = verejne_vysl_odjakziva.filter(resitel = v.resitel)[0].body + v.titul = v.resitel.get_titul(v.body_odjakziva) + v.body_rocnik = v.body + v.body_cisla = [] + + #pokud pro dany rok a cislo nema resitel vysledky, ma defaultne 0 + for cis in vysledkovka.cisla: + if not jen_verejne or cis.verejna_vysledkovka: + #seznam vysledku se spravnym rocnikem a cislem pro resitele + #zobrazim jen je-li vysledkovka verejna + body_za_cislo = VysledkyZaCislo.objects.filter(cislo__rocnik=rocnik).filter(cislo = cis).filter(resitel = v.resitel) + if body_za_cislo: + #neprazdne vysledky by mely obsahovat prave jeden vysledek + v.body_cisla.append(body_za_cislo[0].body) + else: + #resitel nema za cislo body + v.body_cisla.append(0) + + vysledkovka.radky.append(v) + + return vysledkovka + + class RocnikView(generic.DetailView): model = Rocnik template_name = 'seminar/archiv/rocnik.html' @@ -131,46 +206,9 @@ class RocnikView(generic.DetailView): def get_context_data(self, **kwargs): context = super(RocnikView, self).get_context_data(**kwargs) - cisla_v_rocniku = VysledkyKCisluZaRocnik.objects.filter(cislo__verejna_vysledkovka = True).filter(cislo__rocnik = context['rocnik']).order_by('cislo') - #vyberu vsechny verejne vysledky z rocniku - #pokud žádné nejsou, výsledkovka se nezobrazí - if cisla_v_rocniku: - vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].cislo).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) - #vybere vsechny vysledky z posledniho verejneho cisla a setridi sestupne dle bodu - vysledkovka = [] - - # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině - for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky): - v.poradi = poradi - v.resitel.rocnik = v.resitel.rocnik(context['rocnik']) - - verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__verejna_vysledkovka = True).filter(cislo__rocnik = context['rocnik']).filter(cislo = cisla_v_rocniku[0].cislo) - - v.body_odjakziva = verejne_vysl_odjakziva.filter(resitel = v.resitel)[0].body - v.titul = v.resitel.get_titul(v.body_odjakziva) - v.body_rocnik = v.body - v.body_cisla = [] - - #pokud pro dany rok a cislo nema resitel vysledky, ma defaultne 0 - for cis in context['rocnik'].verejna_cisla(): - if cis.verejna_vysledkovka: - body_za_cislo = VysledkyZaCislo.objects.filter(cislo__rocnik = context['rocnik']).filter(cislo = cis).filter(resitel = v.resitel) - #seznam vysledku se spravnym rocnikem a cislem pro resitele - #zobrazim jen je-li vysledkovka verejna - if body_za_cislo: - v.body_cisla.append(body_za_cislo[0].body) - #neprazdne vysledky by mely obsahovat prave jeden vysledek - else: - v.body_cisla.append(0) - #resitel nema za cislo body - - vysledkovka.append(v) - - - context['vysledkovka'] = vysledkovka - - temata_v_rocniku = Problem.objects.filter(typ=Problem.TYP_TEMA, cislo_zadani__rocnik=context['rocnik']).order_by('kod') - context['temata_v_rocniku'] = temata_v_rocniku + context['vysledkovka'] = vysledkovka_rocniku(context["rocnik"]) + context['vysledkovka_s_neverejnymi'] = vysledkovka_rocniku(context["rocnik"], jen_verejne=False) + context['temata_v_rocniku'] = verejna_temata(context["rocnik"]) return context @@ -227,7 +265,7 @@ class CisloView(generic.DetailView): resene_problemy = Problem.objects.filter(cislo_reseni=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('cislo_zadani__cislo', 'kod') - problemy = sorted(list(set([r.problem for r in reseni])), key=lambda x:(0 if x.typ==Problem.TYP_ULOHA else 1, x.kod_v_rocniku)) + problemy = sorted(set(r.problem for r in reseni), key=lambda x:(0 if x.typ==Problem.TYP_ULOHA else 1, x.kod_v_rocniku())) #setridi problemy podle typu a poradi zadani problem_index = {} for i in range(len(problemy)):