@ -2,24 +2,26 @@
from django . shortcuts import get_object_or_404 , render
from django . http import HttpResponse , HttpResponseRedirect , HttpResponseForbidden , JsonResponse
from django . urls import reverse
from django . urls import reverse , reverse_lazy
from django . core . exceptions import PermissionDenied , ObjectDoesNotExist
from django . views import generic
from django . utils . translation import ugettext as _
from django . http import Http404 , HttpResponseBadRequest , HttpResponseRedirect
from django . db . models import Q
from django . db . models import Q , Sum , Count
from django . views . decorators . csrf import ensure_csrf_cookie
from django . contrib . auth import authenticate , login , get_user_model , logout
from django . contrib . auth import views as auth_views
from django . contrib . auth . models import User
from django . contrib . auth . mixins import LoginRequiredMixin
from django . db import transaction
from dal import autocomplete
from . models import Problem , Cislo , Reseni , Nastaveni , Rocnik , Soustredeni , Organizator , Resitel , Novinky , Soustredeni_Ucastnici , Pohadka , Tema , Clanek , Osoba , Skola
import seminar . models as s
from . 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 . import utils
from . unicodecsv import UnicodeWriter
from . forms import PrihlaskaForm , LoginForm
from . forms import PrihlaskaForm , LoginForm , EditForm
from datetime import timedelta , date , datetime
from django . utils import timezone
@ -43,6 +45,45 @@ def verejna_temata(rocnik):
"""
return Problem . objects . filter ( typ = Problem . TYP_TEMA , cislo_zadani__rocnik = rocnik , cislo_zadani__verejne_db = True ) . order_by ( ' kod ' )
def temata_v_rocniku ( rocnik ) :
return Problem . objects . filter ( typ = Problem . TYP_TEMA , rocnik = rocnik )
def get_problemy_k_tematu ( tema ) :
return Problemy . objects . filter ( nadproblem = tema )
class VlozBodyView ( generic . ListView ) :
template_name = ' seminar/org/vloz_body.html '
def get_queryset ( self ) :
self . tema = get_object_or_404 ( Problem , id = self . kwargs [ ' tema ' ] )
print ( self . tema )
self . problemy = Problem . objects . filter ( nadproblem = self . tema )
print ( self . problemy )
self . reseni = Reseni . objects . filter ( problem__in = self . problemy )
print ( self . reseni )
return self . reseni
class ObalkovaniView ( generic . ListView ) :
template_name = ' seminar/org/obalkovani.html '
def get_queryset ( self ) :
rocnik = get_object_or_404 ( Rocnik , rocnik = self . kwargs [ ' rocnik ' ] )
cislo = get_object_or_404 ( Cislo , rocnik = rocnik , poradi = self . kwargs [ ' cislo ' ] )
self . cislo = cislo
self . hodnoceni = s . Hodnoceni . objects . filter ( cislo_body = cislo )
self . reseni = Reseni . objects . filter ( hodnoceni__in = self . hodnoceni ) . annotate ( Sum ( ' hodnoceni__body ' ) ) . annotate ( Count ( ' hodnoceni ' ) ) . order_by ( ' resitele__osoba ' )
return self . reseni
def get_context_data ( self , * * kwargs ) :
context = super ( ObalkovaniView , self ) . get_context_data ( * * kwargs )
print ( self . cislo )
context [ ' cislo ' ] = self . cislo
return context
def AktualniZadaniView ( request ) :
nastaveni = get_object_or_404 ( Nastaveni )
@ -73,6 +114,99 @@ def ZadaniTemataView(request):
}
)
# TODO Napsat tuto funkci znovu rekurzivně podle Jethrorad. Potom se podívat, jak lehce se dá modifikovat pro Rozcestník. Pokud lehce, rozšířit ji. Pokud složitě - použít tuhle
def vytahniZLesaSeznam ( tematko , koren , pouze_zajimave = False ) :
returnVal = [ ]
stack = [ ]
stack . append ( ( koren . first_child , 0 , False ) ) #Tuple of node, depth and relevance
while len ( stack ) > 0 :
wn , wd , wr = stack . pop ( )
if wn . succ != None :
stack . append ( ( wn . succ , wd , wr ) )
if isinstance ( wn , s . TemaVCisleNode ) :
print ( " TEMA " )
print ( wn . tema . id )
print ( tematko . id )
if wn . tema . id == tematko . id :
returnVal . append ( ( posledni_cislo , 0 ) )
print ( " PRIDANO " )
wr = True
wd = 1
if wn . srolovatelne :
tagOpen = s . Text ( na_web = " Otevírací srolovací tag " )
tagOpenNode = s . TextNode ( text = tagOpen )
tagClose = s . Text ( na_web = " Zavírací srolovací tag " )
tagCloseNode = s . TextNode ( text = tagClose )
stack . append ( ( tagCloseNode , wd , True ) )
if wn . first_child != None :
stack . append ( ( wn . first_child , wd + 1 , wr ) )
if isinstance ( wn , s . CisloNode ) :
posledni_cislo = wn
print ( wn )
if wr :
print ( " ZAJIMAVE " )
if pouze_zajimave :
if not wn . zajimave :
continue
returnVal . append ( ( wn , wd ) )
return returnVal
def TematkoView ( request , rocnik , tematko ) :
nastaveni = s . Nastaveni . objects . first ( )
rocnik_object = s . Rocnik . objects . filter ( rocnik = rocnik )
tematko_object = s . Tema . objects . filter ( rocnik = rocnik_object [ 0 ] , kod = tematko )
seznam = vytahniZLesaSeznam ( tematko_object [ 0 ] , nastaveni . aktualni_rocnik ( ) . rocniknode )
for node , depth in seznam :
if node . isinstance ( node , s . KonferaNode ) :
raise Exception ( " Not implemented yet " )
if node . isinstance ( node , s . PohadkaNode ) : # Mohu ignorovat, má pod sebou
pass
return render ( request , ' seminar/tematka/toaletak.html ' , { } )
def TemataRozcestnikView ( request ) :
print ( " ============================================= " )
nastaveni = s . Nastaveni . objects . first ( )
tematka_objects = s . Tema . objects . filter ( rocnik = nastaveni . aktualni_rocnik ( ) )
tematka = [ ] #List tematka obsahuje pro kazde tematko object a list vsech TemaVCisleNodu - implementované pomocí slovníku
for tematko_object in tematka_objects :
print ( " AKTUALNI TEMATKO " )
print ( tematko_object . id )
odkazy = vytahniZLesaSeznam ( tematko_object , nastaveni . aktualni_rocnik ( ) . rocniknode , pouze_zajimave = True ) #Odkazy jsou tuply (node, depth) v listu
print ( odkazy )
cisla = [ ] # List tuplů (nazev cisla, list odkazů)
vcisle = [ ]
cislo = None
for odkaz in odkazy :
if odkaz [ 1 ] == 0 :
if cislo != None :
cisla . append ( ( cislo , vcisle ) )
cislo = ( odkaz [ 0 ] . getOdkazStr ( ) , odkaz [ 0 ] . getOdkaz ( ) )
vcisle = [ ]
else :
print ( odkaz [ 0 ] . getOdkaz ( ) )
vcisle . append ( ( odkaz [ 0 ] . getOdkazStr ( ) , odkaz [ 0 ] . getOdkaz ( ) ) )
if cislo != None :
cisla . append ( ( cislo , vcisle ) )
print ( cisla )
tematka . append ( {
" kod " : tematko_object . kod ,
" nazev " : tematko_object . nazev ,
" abstrakt " : tematko_object . abstrakt ,
" obrazek " : tematko_object . obrazek ,
" cisla " : cisla
} )
return render ( request , ' seminar/tematka/rozcestnik.html ' , { " tematka " : tematka , " rocnik " : nastaveni . aktualni_rocnik ( ) . rocnik } )
#def ZadaniAktualniVysledkovkaView(request):
# nastaveni = get_object_or_404(Nastaveni)
@ -672,7 +806,7 @@ def obalkyView(request,resitele):
return response
def obalkovaniView ( request , rocnik , cislo ) :
def oldO balkovaniView ( request , rocnik , cislo ) :
rocnik = Rocnik . objects . get ( rocnik = rocnik )
cislo = Cislo . objects . get ( rocnik = rocnik , cislo = cislo )
@ -809,7 +943,7 @@ def StavDatabazeView(request):
@ensure_csrf_cookie
def LoginView ( request ) :
def TeXUpload LoginView( request ) :
""" Pro přihlášení při nahrávání z texu """
q = request . POST
# nastavení cookie csrftoken
@ -1016,8 +1150,6 @@ class ResitelView(LoginRequiredMixin,generic.DetailView):
return Resitel . objects . get ( osoba__user = self . request . user )
## Formulare
def resitelEditView ( request ) :
pass
def resetPasswordView ( request ) :
pass
@ -1054,6 +1186,59 @@ def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data):
logger . warn ( msg )
gdpr_logger . warn ( msg + " , form: {} " . format ( form_data ) )
from django . forms . models import model_to_dict
def resitelEditView ( request ) :
err_logger = logging . getLogger ( ' seminar.prihlaska.problem ' )
## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately
u = request . user
osoba_edit = Osoba . objects . get ( user = u )
resitel_edit = osoba_edit . resitel
user_edit = osoba_edit . user
## Vytvoření slovníku, kterým předvyplním formulář
prefill_1 = model_to_dict ( user_edit )
prefill_2 = model_to_dict ( resitel_edit )
prefill_3 = model_to_dict ( osoba_edit )
prefill_1 . update ( prefill_2 )
prefill_1 . update ( prefill_3 )
form = EditForm ( initial = prefill_1 )
## Změna údajů a jejich uložení
if request . method == ' POST ' :
form = EditForm ( request . POST )
if form . is_valid ( ) :
## Změny v osobě
fcd = form . cleaned_data
osoba_edit . jmeno = fcd [ ' jmeno ' ]
osoba_edit . prijmeni = fcd [ ' prijmeni ' ]
osoba_edit . pohlavi_muz = fcd [ ' pohlavi_muz ' ]
osoba_edit . email = fcd [ ' email ' ]
osoba_edit . telefon = fcd [ ' telefon ' ]
osoba_edit . ulice = fcd [ ' ulice ' ]
osoba_edit . mesto = fcd [ ' mesto ' ]
osoba_edit . psc = fcd [ ' psc ' ]
## Změny v osobě s podmínkami
if fcd . get ( ' spam ' , False ) :
osoba_edit . datum_souhlasu_zasilani = date . today ( )
if fcd . get ( ' stat ' , ' ' ) in ( ' CZ ' , ' SK ' ) :
osoba_edit . stat = fcd [ ' stat ' ]
else :
## Neznámá země
msg = " Unknown country {} " . format ( fcd [ ' stat_text ' ] )
## Změny v řešiteli
resitel_edit . skola = fcd [ ' skola ' ]
resitel_edit . rok_maturity = fcd [ ' rok_maturity ' ]
resitel_edit . zasilat = fcd [ ' zasilat ' ]
if fcd . get ( ' skola ' ) :
resitel_edit . skola = fcd [ ' skola ' ]
else :
# Unknown school - log it
msg = " Unknown school {} , {} " . format ( fcd [ ' skola_nazev ' ] , fcd [ ' skola_adresa ' ] )
resitel_edit . save ( )
osoba_edit . save ( )
return HttpResponseRedirect ( ' /thanks/ ' )
else :
## Stránka před odeslaním formuláře = předvyplněný formulář
return render ( request , ' seminar/edit.html ' , { ' form ' : form } )
def prihlaskaView ( request ) :
generic_logger = logging . getLogger ( ' seminar.prihlaska ' )
@ -1159,3 +1344,46 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
# Q(user__last_name__isstartswith=query))
#
# return qs
# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar'
class LoginView ( auth_views . LoginView ) :
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
template_name = ' seminar/login.html '
# Přesměrovací URL má být v kontextu:
def get_context_data ( self , * * kwargs ) :
ctx = super ( ) . get_context_data ( * * kwargs )
ctx [ ' next ' ] = reverse ( ' titulni_strana ' )
return ctx
class LogoutView ( auth_views . LogoutView ) :
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
template_name = ' seminar/logout.html '
# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité.
next_page = reverse_lazy ( ' titulni_strana ' )
# "Chci resetovat heslo"
class PasswordResetView ( auth_views . PasswordResetView ) :
#template_name = 'seminar/password_reset.html'
# TODO: vlastní email_template_name a subject_template_name a html_email_template_name
success_url = reverse_lazy ( ' reset_password_done ' )
from_email = ' login@mam.mff.cuni.cz '
# "Poslali jsme e-mail (pokud bylo kam))"
class PasswordResetDoneView ( auth_views . PasswordResetDoneView ) :
#template_name = 'seminar/password_reset_done.html'
pass
# "Vymysli si heslo"
class PasswordResetConfirmView ( auth_views . PasswordResetConfirmView ) :
#template_name = 'seminar/password_confirm_done.html'
success_url = reverse_lazy ( ' reset_password_complete ' )
# "Heslo se asi změnilo."
class PasswordResetCompleteView ( auth_views . PasswordResetCompleteView ) :
#template_name = 'seminar/password_complete_done.html'
pass
class PasswordChangeView ( auth_views . PasswordChangeView ) :
#template_name = 'seminar/password_change.html'
success_url = reverse_lazy ( ' titulni_strana ' )