Merge remote-tracking branch 'origin/data_migrations' into treenode_editor
This commit is contained in:
commit
e4818d28ea
4 changed files with 102 additions and 303 deletions
|
@ -8,98 +8,96 @@ from django.utils.encoding import force_text
|
||||||
from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni
|
from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni
|
||||||
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||||
from .ovvpfile import OvvpFile
|
from .ovvpfile import OvvpFile
|
||||||
|
from seminar import views
|
||||||
|
|
||||||
class ExportIndexView(generic.View):
|
class ExportIndexView(generic.View):
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
ls = []
|
||||||
|
for r in Rocnik.objects.filter(exportovat = True):
|
||||||
|
url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok})
|
||||||
|
ls.append(url.split('/')[-1])
|
||||||
|
for s in Soustredeni.objects.filter(exportovat = True):
|
||||||
|
url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()})
|
||||||
|
ls.append(url.split('/')[-1])
|
||||||
|
|
||||||
ls = []
|
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8')
|
||||||
for r in Rocnik.objects.filter(exportovat = True):
|
|
||||||
url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok})
|
|
||||||
ls.append(url.split('/')[-1])
|
|
||||||
for s in Soustredeni.objects.filter(exportovat = True):
|
|
||||||
url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()})
|
|
||||||
ls.append(url.split('/')[-1])
|
|
||||||
|
|
||||||
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def default_ovvpfile(event, rocnik):
|
def default_ovvpfile(event, rocnik):
|
||||||
of = OvvpFile()
|
of = OvvpFile()
|
||||||
of.headers['version'] = '1'
|
of.headers['version'] = '1'
|
||||||
of.headers['event'] = event
|
of.headers['event'] = event
|
||||||
of.headers['year'] = force_text(rocnik.prvni_rok)
|
of.headers['year'] = force_text(rocnik.prvni_rok)
|
||||||
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
of.headers['id-scope'] = 'mam'
|
of.headers['id-scope'] = 'mam'
|
||||||
of.headers['id-generation'] = '1'
|
of.headers['id-generation'] = '1'
|
||||||
return of
|
return of
|
||||||
|
|
||||||
|
|
||||||
class ExportSousView(generic.View):
|
class ExportSousView(generic.View):
|
||||||
|
|
||||||
def get(self, request, datum_zacatku=None):
|
def get(self, request, datum_zacatku=None):
|
||||||
try:
|
try:
|
||||||
dz = django.utils.dateparse.parse_date(datum_zacatku)
|
dz = django.utils.dateparse.parse_date(datum_zacatku)
|
||||||
except:
|
except:
|
||||||
dz = None
|
dz = None
|
||||||
if dz is None:
|
if dz is None:
|
||||||
raise django.http.Http404()
|
raise django.http.Http404()
|
||||||
|
|
||||||
s = get_object_or_404(Soustredeni, datum_zacatku=dz, exportovat=True)
|
s = get_object_or_404(Soustredeni, datum_zacatku=dz, exportovat=True)
|
||||||
|
|
||||||
akce = {Soustredeni.TYP_JARNI: 'MaM.sous.jaro',
|
akce = {Soustredeni.TYP_JARNI: 'MaM.sous.jaro',
|
||||||
Soustredeni.TYP_PODZIMNI: 'MaM.sous.podzim',
|
Soustredeni.TYP_PODZIMNI: 'MaM.sous.podzim',
|
||||||
Soustredeni.TYP_VIKEND: 'MaM.vikend',
|
Soustredeni.TYP_VIKEND: 'MaM.vikend',
|
||||||
}[s.typ]
|
}[s.typ]
|
||||||
|
|
||||||
of = default_ovvpfile(akce, s.rocnik)
|
|
||||||
of.headers['x-event-begin'] = s.datum_zacatku.isoformat()
|
|
||||||
of.headers['x-event-end'] = s.datum_konce.isoformat()
|
|
||||||
of.headers['x-event-location'] = s.misto
|
|
||||||
of.headers['comment'] = u'MaM-Web export ucastniku soustredeni v {x-event-location} od {x-event-begin} do {x-event-end}'.format(**of.headers)
|
|
||||||
of.columns = ['id', 'name', 'surname', 'gender', 'email', 'end-year', 'school', 'school-name']
|
|
||||||
|
|
||||||
for u in s.ucastnici.all():
|
|
||||||
of.rows.append(u.export_row())
|
|
||||||
|
|
||||||
return of.to_HttpResponse()
|
|
||||||
|
|
||||||
|
|
||||||
|
of = default_ovvpfile(akce, s.rocnik)
|
||||||
|
of.headers['x-event-begin'] = s.datum_zacatku.isoformat()
|
||||||
|
of.headers['x-event-end'] = s.datum_konce.isoformat()
|
||||||
|
of.headers['x-event-location'] = s.misto
|
||||||
|
of.headers['comment'] = u'MaM-Web export ucastniku soustredeni v {x-event-location} od {x-event-begin} do {x-event-end}'.format(**of.headers)
|
||||||
|
of.columns = ['id', 'name', 'surname', 'gender', 'email', 'end-year', 'school', 'school-name']
|
||||||
|
|
||||||
|
for u in s.ucastnici.all():
|
||||||
|
of.rows.append(u.export_row())
|
||||||
|
|
||||||
|
return of.to_HttpResponse()
|
||||||
|
|
||||||
|
# POZOR! Předělání na nový model neotestováno v reálu (ale zase jen drobné změny)
|
||||||
class ExportRocnikView(generic.View):
|
class ExportRocnikView(generic.View):
|
||||||
|
|
||||||
def get(self, request, prvni_rok=None):
|
def get(self, request, prvni_rok=None):
|
||||||
try:
|
try:
|
||||||
pr = int(prvni_rok)
|
pr = int(prvni_rok)
|
||||||
except:
|
except:
|
||||||
pr = None
|
pr = None
|
||||||
if pr is None:
|
if pr is None:
|
||||||
raise django.http.Http404()
|
raise django.http.Http404()
|
||||||
|
|
||||||
rocnik = get_object_or_404(Rocnik, prvni_rok=pr, exportovat=True)
|
rocnik = get_object_or_404(Rocnik, prvni_rok=pr, exportovat=True)
|
||||||
cislo = rocnik.posledni_zverejnena_vysledkovka_cislo()
|
cislo = rocnik.posledni_zverejnena_vysledkovka_cislo()
|
||||||
vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = cislo).select_related("resitel").order_by('-body').all()
|
resitele = views.aktivniResitele(cislo.rocnik.rocnik, cislo.poradi, True)
|
||||||
|
slovnik_body = views.secti_body_za_rocnik(cislo, resitele)
|
||||||
|
_, setrizeni_resitele, setrizene_body = views.setrid_resitele_a_body(slovnik_body)
|
||||||
|
|
||||||
of = default_ovvpfile('MaM.rocnik', rocnik)
|
of = default_ovvpfile('MaM.rocnik', rocnik)
|
||||||
of.headers['comment'] = u'MaM-Web export aktivnich resitelu rocniku {rocnik} do cisla {cislo}'.format(
|
of.headers['comment'] = u'MaM-Web export aktivnich resitelu rocniku {rocnik} do cisla {cislo}'.format(rocnik=rocnik, cislo=cislo)
|
||||||
rocnik=rocnik, cislo=cislo)
|
of.columns = ['id', 'name', 'surname', 'gender', 'born', 'email', 'end-year',
|
||||||
of.columns = ['id', 'name', 'surname', 'gender', 'born', 'email', 'end-year',
|
'street', 'town', 'postcode', 'country', 'spam-flag', 'spam-date',
|
||||||
'street', 'town', 'postcode', 'country', 'spam-flag', 'spam-date',
|
'school', 'school-name', 'points', 'rank',]
|
||||||
'school', 'school-name', 'points', 'rank',]
|
|
||||||
|
# počítání pořadí řešitelů
|
||||||
posledni_body = 100000
|
posledni_body = 100000
|
||||||
posledni_poradi = 0
|
posledni_poradi = 0
|
||||||
for vi in range(len(vysledky)):
|
for i in range(len(setrizeni_resitele)):
|
||||||
|
rd = setrizeni_resitele[i].export_row()
|
||||||
v = vysledky[vi]
|
|
||||||
rd = v.resitel.export_row()
|
|
||||||
|
|
||||||
if posledni_body > v.body:
|
|
||||||
posledni_body = v.body
|
|
||||||
posledni_poradi = vi + 1
|
|
||||||
rd['rank'] = posledni_poradi
|
|
||||||
rd['points'] = v.body
|
|
||||||
|
|
||||||
of.rows.append(rd)
|
|
||||||
|
|
||||||
return of.to_HttpResponse()
|
|
||||||
|
|
||||||
|
if posledni_body > body[i]:
|
||||||
|
posledni_body = body[i]
|
||||||
|
posledni_poradi = i + 1
|
||||||
|
rd['rank'] = posledni_poradi
|
||||||
|
rd['points'] = body[i]
|
||||||
|
|
||||||
|
of.rows.append(rd)
|
||||||
|
|
||||||
|
return of.to_HttpResponse()
|
||||||
|
|
|
@ -94,17 +94,9 @@ urlpatterns = [
|
||||||
staff_member_required(views.StavDatabazeView), name='stav_databaze'),
|
staff_member_required(views.StavDatabazeView), name='stav_databaze'),
|
||||||
path('cislo/<int:rocnik>.<int:cislo>/obalkovani',
|
path('cislo/<int:rocnik>.<int:cislo>/obalkovani',
|
||||||
staff_member_required(views.ObalkovaniView.as_view()), name='seminar_cislo_resitel_obalkovani'),
|
staff_member_required(views.ObalkovaniView.as_view()), name='seminar_cislo_resitel_obalkovani'),
|
||||||
path('cislo/<int:rocnik>.<int:cislo>/tex-download.json',
|
|
||||||
staff_member_required(views.texDownloadView), name='seminar_tex_download'),
|
|
||||||
path('soustredeni/<int:soustredeni>/obalky.pdf',
|
path('soustredeni/<int:soustredeni>/obalky.pdf',
|
||||||
staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'),
|
staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'),
|
||||||
|
|
||||||
path('tex-upload/login/', views.TeXUploadLoginView, name='seminar_login'),
|
|
||||||
path(
|
|
||||||
'tex-upload/',
|
|
||||||
staff_member_required(views.texUploadView),
|
|
||||||
name='seminar_tex_upload'
|
|
||||||
),
|
|
||||||
path('org/vloz_body/<int:tema>/',
|
path('org/vloz_body/<int:tema>/',
|
||||||
staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'),
|
staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'),
|
||||||
path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
|
path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
|
||||||
|
|
|
@ -49,40 +49,40 @@ def seznam_problemu():
|
||||||
|
|
||||||
# Pomocna fce k formatovani problemovych hlasek
|
# Pomocna fce k formatovani problemovych hlasek
|
||||||
def prb(cls, msg, objs=None):
|
def prb(cls, msg, objs=None):
|
||||||
s = u'<b>%s:</b> %s' % (cls.__name__, msg)
|
s = '<b>%s:</b> %s' % (cls.__name__, msg)
|
||||||
if objs:
|
if objs:
|
||||||
s += u' ['
|
s += ' ['
|
||||||
for o in objs:
|
for o in objs:
|
||||||
try:
|
try:
|
||||||
url = o.admin_url()
|
url = o.admin_url()
|
||||||
except:
|
except:
|
||||||
url = None
|
url = None
|
||||||
if url:
|
if url:
|
||||||
s += u'<a href="%s">%s</a>, ' % (url, o.pk, )
|
s += '<a href="%s">%s</a>, ' % (url, o.pk, )
|
||||||
else:
|
else:
|
||||||
s += u'%s, ' % (o.pk, )
|
s += '%s, ' % (o.pk, )
|
||||||
s = s[:-2] + u']'
|
s = s[:-2] + ']'
|
||||||
problemy.append(s)
|
problemy.append(s)
|
||||||
|
|
||||||
# Duplicita jmen
|
# Duplicita jmen
|
||||||
jmena = {}
|
jmena = {}
|
||||||
for r in m.Resitel.objects.all():
|
for r in m.Resitel.objects.all():
|
||||||
j = r.plne_jmeno()
|
j = r.osoba.plne_jmeno()
|
||||||
if j not in jmena:
|
if j not in jmena:
|
||||||
jmena[j] = []
|
jmena[j] = []
|
||||||
jmena[j].append(r)
|
jmena[j].append(r)
|
||||||
for j in jmena:
|
for j in jmena:
|
||||||
if len(jmena[j]) > 1:
|
if len(jmena[j]) > 1:
|
||||||
prb(m.Resitel, u'Duplicitní jméno "%s"' % (j, ), jmena[j])
|
prb(m.Resitel, 'Duplicitní jméno "%s"' % (j, ), jmena[j])
|
||||||
|
|
||||||
# Data maturity a narození
|
# Data maturity a narození
|
||||||
for r in m.Resitel.objects.all():
|
for r in m.Resitel.objects.all():
|
||||||
if not r.rok_maturity:
|
if not r.rok_maturity:
|
||||||
prb(m.Resitel, u'Neznámý rok maturity', [r])
|
prb(m.Resitel, 'Neznámý rok maturity', [r])
|
||||||
if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
|
if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
|
||||||
prb(m.Resitel, u'Podezřelé datum maturity', [r])
|
prb(m.Resitel, 'Podezřelé datum maturity', [r])
|
||||||
if r.datum_narozeni and (r.datum_narozeni.year < 1970 or r.datum_narozeni.year > datetime.date.today().year - 12):
|
if r.osoba.datum_narozeni and (r.osoba.datum_narozeni.year < 1970 or r.osoba.datum_narozeni.year > datetime.date.today().year - 12):
|
||||||
prb(m.Resitel, u'Podezřelé datum narození', [r])
|
prb(m.Resitel, 'Podezřelé datum narození', [r])
|
||||||
# if not r.email:
|
# if not r.email:
|
||||||
# prb(Resitel, u'Neznámý email', [r])
|
# prb(Resitel, u'Neznámý email', [r])
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -979,6 +984,10 @@ def aktivniResitele(rocnik, cislo):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# 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)
|
||||||
|
@ -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,211 +1142,11 @@ 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
|
||||||
template_name = 'seminar/resitel.html'
|
template_name = 'seminar/resitel.html'
|
||||||
|
|
Loading…
Reference in a new issue