# coding:utf-8 from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.views import generic from django.utils.translation import ugettext as _ from django.http import Http404 from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from datetime import timedelta, date, datetime from itertools import groupby 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, }, ) 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'), } ) ### Titulni strana class TitulniStranaView(generic.ListView): model = Novinky template_name='seminar/titulnistrana.html' queryset = Novinky.objects.filter(zverejneno=True).order_by('-datum')[:5] def get_context_data(self, **kwargs): context = super(TitulniStranaView, self).get_context_data(**kwargs) nastaveni = get_object_or_404(Nastaveni) cas_deadline = nastaveni.aktualni_cislo.datum_deadline try: rozdil_casu = datetime.combine(cas_deadline, datetime.max.time()) \ - datetime.now() context['cas_do_konce_dni'] = rozdil_casu.days context['cas_do_konce_hodin'] = rozdil_casu.seconds / 3600 context['cas_do_konce_minut'] = (rozdil_casu.seconds / 60) % 60 context['cas_do_konce_sekund'] = rozdil_casu.seconds % 60 context['dead'] = datetime.combine(cas_deadline, datetime.max.time()) context['ted'] = datetime.now() except: context['dead'] = None return context class StareNovinkyView(generic.ListView): model = Novinky template_name = 'seminar/stare_novinky.html' queryset = Novinky.objects.filter(zverejneno=True).order_by('-datum') ### Co je M&M ## Organizatori class CojemamOrganizatoriView(generic.ListView): model = Organizator template_name='seminar/cojemam/organizatori.html' queryset = Organizator.objects.exclude(organizuje_do_roku__isnull=False, organizuje_do_roku__lt=date.today().year).order_by('user__first_name') def get_context_data(self, **kwargs): context = super(CojemamOrganizatoriView, self).get_context_data(**kwargs) context['aktivni'] = True return context class CojemamOrganizatoriStariView(generic.ListView): model = Organizator template_name='seminar/cojemam/organizatori.html' queryset = Organizator.objects.filter(organizuje_do_roku__isnull=False, organizuje_do_roku__lt=date.today().year).order_by('-organizuje_do_roku') ### Archiv class CislaView(generic.ListView): model = Rocnik template_name='seminar/archiv/cisla.html' def sloupec_s_poradim(vysledky): # počet řešitelů ve výsledkovce nad aktuálním lepsich_resitelu = 0 poradi_l = [] # projdeme skupiny řešitelů se stejným počtem bodů for skupina in (list(x) for _, x in groupby(vysledky, lambda x: x.body)): # připravíme si obsahy buněk ve sloupci pořadí pro skupinu if len(skupina) == 1: poradi_l += ["{}.".format(lepsich_resitelu + 1)] # je-li účastníků se stejným počtem bodů víc, pořadí (rozsah X.-Y.) je jen u prvního else: poradi_l += ["{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) lepsich_resitelu += len(skupina) return poradi_l class RocnikView(generic.DetailView): model = Rocnik template_name = 'seminar/archiv/rocnik.html' # Vlastni ziskavani objektu z databaze podle (Rocnik.rocnik) 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(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 return context class ProblemView(generic.DetailView): model = Problem def _je_clanek(self, problem): return problem.typ in [Problem.TYP_ORG_CLANEK, Problem.TYP_RES_CLANEK] def get_template_names(self, **kwargs): context = super(ProblemView, self).get_context_data(**kwargs) return ['seminar/archiv/problem_' + ('clanek.html' if self._je_clanek(context['problem']) else 'uloha_tema.html')] def get_context_data(self, **kwargs): context = super(ProblemView, self).get_context_data(**kwargs) if context['problem'].typ == Problem.TYP_RES_CLANEK: context['reseni'] = Reseni.objects.filter(problem=context['problem']).select_related('resitel').order_by('resitel__prijmeni') return context class RadekVysledkovky(object): pass class CisloView(generic.DetailView): model = Cislo template_name = 'seminar/archiv/cislo.html' # Vlastni ziskavani objektu z databaze podle (Rocnik.rocnik) def get_object(self, queryset=None): if queryset is None: queryset = self.get_queryset() rocnik_arg = self.kwargs.get('rocnik') cislo_arg = self.kwargs.get('cislo') queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_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(CisloView, self).get_context_data(**kwargs) vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = context['cislo']).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno') reseni = Reseni.objects.filter(cislo_body = context['cislo']).select_related("resitel") # typy úloh, které se mají zobrazovat u čísla, tj. těch, které byly v čísle skutečně zadány typy_skutecne_zadanych = [Problem.TYP_ULOHA, Problem.TYP_SERIAL, Problem.TYP_ORG_CLANEK] v_cisle_zadane = Problem.objects.filter(cislo_zadani=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('kod') 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)) #setridi problemy podle typu a poradi zadani problem_index = {} for i in range(len(problemy)): problem_index[problemy[i].id] = i #umoznuje zjistit index podle id problemu vysledky_resitele = {} 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.body_celkem_rocnik = v.body v.body_celkem_odjakziva = VysledkyKCisluOdjakziva.objects.get(resitel=v.resitel, cislo=context['cislo']).body # je tady '', aby se nezobrazovala 0, pokud se řešitel o řešení úlohy ani nepokusil v.body_ulohy = [''] * len(problemy) v.titul = v.resitel.get_titul(v.body_celkem_odjakziva) body_cislo_q = VysledkyZaCislo.objects.filter(resitel=v.resitel, cislo=context['cislo']) v.body_cislo = body_cislo_q[0].body if body_cislo_q else 0 vysledkovka.append(v) # připravíme si odkaz na řádek, abychom do něj mohli doplnit body za jednotlivé úlohy vysledky_resitele[v.resitel.id] = v # za každé řešení doplníme k příslušnému řešiteli a úloze body for r in reseni: vysledky_resitele[r.resitel.id].body_ulohy[problem_index[r.problem.id]] = r.body context['vysledkovka'] = vysledkovka context['problemy'] = problemy context['v_cisle_zadane'] = v_cisle_zadane context['resene_problemy'] = resene_problemy return context class ArchivTemataView(generic.ListView): model = Problem template_name = 'seminar/archiv/temata.html' queryset = Problem.objects.filter(typ=Problem.TYP_TEMA, stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') ### Generovani vysledkovky class CisloVysledkovkaView(CisloView): model = Cislo template_name = 'seminar/archiv/cislo_vysledkovka.tex' #content_type = 'application/x-tex; charset=UTF8' #umozni rovnou stahnout TeXovsky dokument content_type = 'text/plain; charset=UTF8' #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani class RocnikVysledkovkaView(RocnikView): model = Rocnik template_name = 'seminar/archiv/rocnik_vysledkovka.tex' #content_type = 'application/x-tex; charset=UTF8' #umozni rovnou stahnout TeXovsky dokument content_type = 'text/plain; charset=UTF8' #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani ### Soustredeni class SoustredeniListView(generic.ListView): model = Soustredeni template_name = 'seminar/soustredeni/seznam_soustredeni.html' class SoustredeniView(generic.DetailView): model = Soustredeni template_name = 'seminar/archiv/soustredeni.html' ### Články class ClankyResitelView(generic.ListView): model = Problem template_name = 'seminar/clanky/resitelske_clanky.html' queryset = Problem.objects.filter(typ=Problem.TYP_RES_CLANEK, stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') class ClankyOrganizatorView(generic.ListView): model = Problem template_name = 'seminar/clanky/organizatorske_clanky.html' queryset = Problem.objects.filter(typ=Problem.TYP_ORG_CLANEK, stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') ### Status def StavDatabazeView(request): # nastaveni = Nastaveni.objects.get() problemy = utils.seznam_problemu() muzi = Resitel.objects.filter(pohlavi_muz=True) zeny = Resitel.objects.filter(pohlavi_muz=False) return render(request, 'seminar/stav_databaze.html', { # 'nastaveni': nastaveni, 'problemy': problemy, 'resitele': Resitel.objects.all(), 'muzi': muzi, 'zeny': zeny, 'jmena_muzu': utils.histogram([r.jmeno for r in muzi]), 'jmena_zen': utils.histogram([r.jmeno for r in zeny]), })