|
@ -645,6 +645,12 @@ class RadekVysledkovkyRocniku(object): |
|
|
self.body_cisla_sezn = body_cisla_sezn |
|
|
self.body_cisla_sezn = body_cisla_sezn |
|
|
self.titul = resitel.get_titul(body_odjakziva) |
|
|
self.titul = resitel.get_titul(body_odjakziva) |
|
|
|
|
|
|
|
|
|
|
|
def setrid_resitele_a_body(slov_resitel_body): |
|
|
|
|
|
setrizeni_resitele_id = [dvojice[0] for dvojice in slov_resitel_body] |
|
|
|
|
|
setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] |
|
|
|
|
|
setrizene_body = [dvojice[1] for dvojice in slov_resitel_body] |
|
|
|
|
|
return setrizeni_resitele_id, setrizeni_resitele, setrizene_body |
|
|
|
|
|
|
|
|
def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
""" Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve |
|
|
""" Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve |
|
|
formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" |
|
|
formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" |
|
@ -665,9 +671,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(rocnik, aktivni_resitele) |
|
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(rocnik, aktivni_resitele) |
|
|
|
|
|
|
|
|
# setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší |
|
|
# setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší |
|
|
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] |
|
|
setrizeni_resitele_id, setrizeni_resitele, setrizene_body = setrid_resitele_a_body(resitel_rocnikbody_sezn) |
|
|
setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] |
|
|
|
|
|
setrizene_body = [dvojice[1] for dvojice in resitel_rocnikbody_sezn] |
|
|
|
|
|
poradi = sloupec_s_poradim(setrizene_body) |
|
|
poradi = sloupec_s_poradim(setrizene_body) |
|
|
|
|
|
|
|
|
# získáme body odjakživa |
|
|
# získáme body odjakživa |
|
@ -958,12 +962,13 @@ def resi_v_rocniku(rocnik, cislo=None): |
|
|
return letosni_resitele.distinct() |
|
|
return letosni_resitele.distinct() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def aktivniResitele(rocnik, cislo): |
|
|
def aktivniResitele(rocnik, cislo, pouze_realni=False): |
|
|
""" Vrací QuerySet aktivních řešitelů, což jsou ti, co ještě neodmaturovali |
|
|
""" Vrací QuerySet aktivních řešitelů, což jsou ti, co ještě neodmaturovali |
|
|
a letos něco poslali (anebo loni něco poslali, pokud jde o první tři čísla). |
|
|
a letos něco poslali (anebo loni něco poslali, pokud jde o první tři čísla). |
|
|
Parametry: |
|
|
Parametry: |
|
|
rocnik (typu int) číslo ročníku, o který se jedná |
|
|
rocnik (typu int) číslo ročníku, o který se jedná |
|
|
cislo (typu int) pořadí čísla, o které se jedná |
|
|
cislo (typu int) pořadí čísla, o které se jedná |
|
|
|
|
|
pouze_realni jen řešitelé, kteří tento rok něco poslali |
|
|
|
|
|
|
|
|
""" |
|
|
""" |
|
|
letos = Rocnik.objects.get(rocnik = rocnik) |
|
|
letos = Rocnik.objects.get(rocnik = rocnik) |
|
@ -980,6 +985,10 @@ def aktivniResitele(rocnik, cislo): |
|
|
# pravděpodobně se jedná o číslo 7-8 |
|
|
# pravděpodobně se jedná o číslo 7-8 |
|
|
zacatek_rocniku = False |
|
|
zacatek_rocniku = False |
|
|
|
|
|
|
|
|
|
|
|
# nehledě na číslo chceme jen řešitele, kteří letos něco odevzdali |
|
|
|
|
|
if pouze_realni: |
|
|
|
|
|
zacatek_rocniku = False |
|
|
|
|
|
|
|
|
if not zacatek_rocniku: |
|
|
if not zacatek_rocniku: |
|
|
return resi_v_rocniku(letos) |
|
|
return resi_v_rocniku(letos) |
|
|
else: |
|
|
else: |
|
@ -1123,8 +1132,8 @@ class ClankyResitelView(generic.ListView): |
|
|
def StavDatabazeView(request): |
|
|
def StavDatabazeView(request): |
|
|
# nastaveni = Nastaveni.objects.get() |
|
|
# nastaveni = Nastaveni.objects.get() |
|
|
problemy = utils.seznam_problemu() |
|
|
problemy = utils.seznam_problemu() |
|
|
muzi = Resitel.objects.filter(pohlavi_muz=True) |
|
|
muzi = Resitel.objects.filter(osoba__pohlavi_muz=True) |
|
|
zeny = Resitel.objects.filter(pohlavi_muz=False) |
|
|
zeny = Resitel.objects.filter(osoba__pohlavi_muz=False) |
|
|
return render(request, 'seminar/stav_databaze.html', |
|
|
return render(request, 'seminar/stav_databaze.html', |
|
|
{ |
|
|
{ |
|
|
# 'nastaveni': nastaveni, |
|
|
# 'nastaveni': nastaveni, |
|
@ -1133,210 +1142,10 @@ def StavDatabazeView(request): |
|
|
'resitele': Resitel.objects.all(), |
|
|
'resitele': Resitel.objects.all(), |
|
|
'muzi': muzi, |
|
|
'muzi': muzi, |
|
|
'zeny': zeny, |
|
|
'zeny': zeny, |
|
|
'jmena_muzu': utils.histogram([r.jmeno for r in muzi]), |
|
|
'jmena_muzu': utils.histogram([r.osoba.jmeno for r in muzi]), |
|
|
'jmena_zen': utils.histogram([r.jmeno for r in zeny]), |
|
|
'jmena_zen': utils.histogram([r.osoba.jmeno for r in zeny]), |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ensure_csrf_cookie |
|
|
|
|
|
def TeXUploadLoginView(request): |
|
|
|
|
|
"""Pro přihlášení při nahrávání z texu""" |
|
|
|
|
|
q = request.POST |
|
|
|
|
|
# nastavení cookie csrftoken |
|
|
|
|
|
if not q: |
|
|
|
|
|
return JsonResponse({"ok": 1}) |
|
|
|
|
|
|
|
|
|
|
|
if "username" in q: |
|
|
|
|
|
username = q["username"] |
|
|
|
|
|
password = q["password"] |
|
|
|
|
|
user = authenticate(username=username, password=password) |
|
|
|
|
|
if user is not None and user.is_staff: |
|
|
|
|
|
login(request, user) |
|
|
|
|
|
return JsonResponse({"ok": 1}) |
|
|
|
|
|
else: |
|
|
|
|
|
return JsonResponse({"error": "Neplatné uživatelské jméno nebo heslo"}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ensure_csrf_cookie |
|
|
|
|
|
def texUploadView(request): |
|
|
|
|
|
|
|
|
|
|
|
def uloz_soubory(files, rocnik, cislo): |
|
|
|
|
|
for filename, f in files: |
|
|
|
|
|
path = os.path.join( |
|
|
|
|
|
settings.MEDIA_ROOT, |
|
|
|
|
|
settings.CISLO_IMG_DIR, |
|
|
|
|
|
rocnik, |
|
|
|
|
|
cislo, |
|
|
|
|
|
filename |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
adresar = os.path.dirname(path) |
|
|
|
|
|
if not os.path.exists(adresar): |
|
|
|
|
|
os.makedirs(adresar) |
|
|
|
|
|
|
|
|
|
|
|
with open(path, "wb+") as fout: |
|
|
|
|
|
for chunk in f.chunks(): |
|
|
|
|
|
fout.write(chunk) |
|
|
|
|
|
|
|
|
|
|
|
q = request.POST |
|
|
|
|
|
# nastavení cookie csrftoken |
|
|
|
|
|
if not q: |
|
|
|
|
|
return JsonResponse({"ok": 1}) |
|
|
|
|
|
|
|
|
|
|
|
# Odchytíme všechny výjimky a traceback pošleme v odpovědi |
|
|
|
|
|
try: |
|
|
|
|
|
meta = json.loads(q["meta"]) |
|
|
|
|
|
html = q["html"] |
|
|
|
|
|
|
|
|
|
|
|
if meta["typ"] in ["uloha", "serial", "reseni", "tema"]: |
|
|
|
|
|
|
|
|
|
|
|
# Uložíme soubory |
|
|
|
|
|
if meta["typ"] != "reseni": |
|
|
|
|
|
c = meta["cislo"] |
|
|
|
|
|
else: |
|
|
|
|
|
# Řešení má nastavené číslo svojí úlohy, ale obrázky jsou |
|
|
|
|
|
# ukládány do čísla, kde řešení vyšlo |
|
|
|
|
|
c = meta["cislo_reseni"] |
|
|
|
|
|
|
|
|
|
|
|
# Zjistíme typ ukládaného problému |
|
|
|
|
|
typy = { |
|
|
|
|
|
"uloha": Problem.TYP_ULOHA, |
|
|
|
|
|
"serial": Problem.TYP_SERIAL, |
|
|
|
|
|
"reseni": Problem.TYP_ULOHA, |
|
|
|
|
|
"tema": Problem.TYP_TEMA, |
|
|
|
|
|
} |
|
|
|
|
|
problem_typ = typy[meta["typ"]] |
|
|
|
|
|
|
|
|
|
|
|
# Pokud už problém existuje, vytáhneme jej z db a upravíme. |
|
|
|
|
|
# Pokud neexistuje, vytvoříme jej jedině pokud je to vynucené. |
|
|
|
|
|
|
|
|
|
|
|
# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku -> |
|
|
|
|
|
# číslo/ročník se musí založit ručně v adminu. |
|
|
|
|
|
rocnik = Rocnik.objects.get(rocnik=meta["rocnik"]) |
|
|
|
|
|
cislo = Cislo.objects.get(rocnik=rocnik, cislo=meta["cislo"]) |
|
|
|
|
|
|
|
|
|
|
|
existujici = Problem.objects.filter( |
|
|
|
|
|
typ=problem_typ, |
|
|
|
|
|
stav=Problem.STAV_ZADANY, |
|
|
|
|
|
cislo_zadani=cislo, |
|
|
|
|
|
kod=meta["kod"] |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
problem = None |
|
|
|
|
|
if existujici: |
|
|
|
|
|
problem = existujici[0] |
|
|
|
|
|
elif "vytvor" in q: |
|
|
|
|
|
# vytvoříme nový |
|
|
|
|
|
problem = Problem( |
|
|
|
|
|
typ=problem_typ, |
|
|
|
|
|
stav=Problem.STAV_ZADANY, |
|
|
|
|
|
kod=meta["kod"], |
|
|
|
|
|
cislo_zadani=cislo |
|
|
|
|
|
) |
|
|
|
|
|
else: |
|
|
|
|
|
return JsonResponse({ |
|
|
|
|
|
"error": "Problém neexistuje: {} {}.{} kód {}".format( |
|
|
|
|
|
meta["typ"], meta["rocnik"], meta["cislo"], meta["kod"] |
|
|
|
|
|
) |
|
|
|
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
uloz_soubory(request.FILES.items(), meta["rocnik"], c) |
|
|
|
|
|
|
|
|
|
|
|
if meta["typ"] == "reseni": |
|
|
|
|
|
problem.text_reseni = html |
|
|
|
|
|
|
|
|
|
|
|
# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku -> |
|
|
|
|
|
# číslo/ročník se musí založit ručně v adminu |
|
|
|
|
|
problem.cislo_reseni = Cislo.objects.get( |
|
|
|
|
|
rocnik=rocnik, |
|
|
|
|
|
cislo=meta["cislo_reseni"] |
|
|
|
|
|
) |
|
|
|
|
|
# při nahrávání řešení už původní zadání atd. neměníme |
|
|
|
|
|
else: |
|
|
|
|
|
problem.text_zadani = html |
|
|
|
|
|
problem.nazev = meta["nazev"] |
|
|
|
|
|
if meta["typ"] != "tema": |
|
|
|
|
|
problem.body = meta["body"] |
|
|
|
|
|
|
|
|
|
|
|
problem.save() |
|
|
|
|
|
cislo.faze = cislo.FAZE_NAHRANO |
|
|
|
|
|
cislo.save() |
|
|
|
|
|
|
|
|
|
|
|
# Vrátíme id dané úlohy, aby se k ní dala případně připojit pohádka |
|
|
|
|
|
return JsonResponse({"db_id": problem.id}) |
|
|
|
|
|
|
|
|
|
|
|
elif meta["typ"] == "pohadka": |
|
|
|
|
|
uloha = Problem.objects.get(typ=Problem.TYP_ULOHA, pk=meta["uloha"]) |
|
|
|
|
|
|
|
|
|
|
|
# Pokud už příslušná pohádka existuje, jen ji upravíme |
|
|
|
|
|
existujici = Pohadka.objects.filter(uloha=uloha, pred=meta["pred"]) |
|
|
|
|
|
pohadka = None |
|
|
|
|
|
if existujici: |
|
|
|
|
|
pohadka = existujici[0] |
|
|
|
|
|
else: |
|
|
|
|
|
pohadka = Pohadka(uloha=uloha, pred=meta["pred"]) |
|
|
|
|
|
pohadka.text = q["html"] |
|
|
|
|
|
pohadka.save() |
|
|
|
|
|
|
|
|
|
|
|
return JsonResponse({"db_id": pohadka.id}) |
|
|
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
# Pošleme zpátky traceback, ať uživatel ví, v čem je problém |
|
|
|
|
|
tb = "".join(traceback.format_exception(type(e), e, sys.exc_info()[2])) |
|
|
|
|
|
return JsonResponse({"error": tb}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def texDownloadView(request, rocnik, cislo): |
|
|
|
|
|
"""View posílající JSON se zadanými a řešenými problémy pro založení čísla |
|
|
|
|
|
""" |
|
|
|
|
|
cislo = Cislo.objects.get(rocnik__rocnik=rocnik, cislo=cislo) |
|
|
|
|
|
if cislo.faze == cislo.FAZE_NAHRANO: |
|
|
|
|
|
# obsah byl nahrán z TeXu na web, už je příliš složitý |
|
|
|
|
|
return JsonResponse( |
|
|
|
|
|
{"error": "Obsah čísla už byl nahrán z TeXu na web."} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
zadane = Problem.objects.filter( |
|
|
|
|
|
cislo_zadani=cislo, |
|
|
|
|
|
stav=Problem.STAV_ZADANY |
|
|
|
|
|
) |
|
|
|
|
|
resene = Problem.objects.filter( |
|
|
|
|
|
cislo_reseni=cislo, |
|
|
|
|
|
stav=Problem.STAV_ZADANY, |
|
|
|
|
|
typ=Problem.TYP_ULOHA |
|
|
|
|
|
) |
|
|
|
|
|
pred_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=True) |
|
|
|
|
|
po_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=False) |
|
|
|
|
|
|
|
|
|
|
|
response = { |
|
|
|
|
|
"zadane": [ |
|
|
|
|
|
{ |
|
|
|
|
|
"nazev": p.nazev, |
|
|
|
|
|
"typ": p.typ, |
|
|
|
|
|
"kod": p.kod, |
|
|
|
|
|
"body": p.body, |
|
|
|
|
|
"zadani": p.text_zadani, |
|
|
|
|
|
"pred_pohadky": [x.text for x in pred_pohadky.filter(uloha=p)], |
|
|
|
|
|
"po_pohadky": [x.text for x in po_pohadky.filter(uloha=p)], |
|
|
|
|
|
} for p in zadane |
|
|
|
|
|
], |
|
|
|
|
|
"resene": [ |
|
|
|
|
|
{ |
|
|
|
|
|
"nazev": p.nazev, |
|
|
|
|
|
"typ": p.typ, |
|
|
|
|
|
"kod": p.kod, |
|
|
|
|
|
"body": p.body, |
|
|
|
|
|
"zadani": p.text_zadani, |
|
|
|
|
|
"reseni": p.text_reseni, |
|
|
|
|
|
"cislo_zadani": p.cislo_zadani.poradi, |
|
|
|
|
|
} for p in resene |
|
|
|
|
|
], |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cislo.faze = Cislo.FAZE_TEX |
|
|
|
|
|
cislo.save() |
|
|
|
|
|
return JsonResponse(response) |
|
|
|
|
|
|
|
|
|
|
|
class ResitelView(LoginRequiredMixin,generic.DetailView): |
|
|
class ResitelView(LoginRequiredMixin,generic.DetailView): |
|
|
model = Resitel |
|
|
model = Resitel |
|
|