2025-01-24 20:22:38 +01:00
import csv
2025-01-21 21:43:43 +01:00
import http
2025-01-24 19:40:54 +01:00
import logging
2025-01-21 21:43:43 +01:00
2025-01-29 01:05:08 +01:00
from django . http import HttpResponse , HttpRequest
2017-10-06 00:37:08 +02:00
from django . shortcuts import render , get_object_or_404
2016-10-04 23:53:56 +02:00
from django . views import generic
2016-04-18 01:14:08 +02:00
from django . shortcuts import HttpResponseRedirect
2017-10-06 00:37:08 +02:00
from django . core . exceptions import ObjectDoesNotExist
2025-01-24 19:40:54 +01:00
from django . db import transaction
2016-04-18 01:14:08 +02:00
2025-01-21 21:14:19 +01:00
from various . views . pomocne import formularOKView
2025-01-24 19:40:54 +01:00
from . forms import HlasovaniPrednaskaFormSet , HlasovaniZnalostiFormSet
2025-01-21 21:14:19 +01:00
2025-01-21 21:43:43 +01:00
from various . models import Nastaveni
2025-01-24 19:40:54 +01:00
from prednasky . models import Prednaska , Hlasovani , Znalost , HlasovaniOZnalostech , Seznam
2024-10-30 15:03:17 +01:00
from soustredeni . models import Soustredeni
from personalni . models import Osoba
2016-09-29 03:59:28 +02:00
2025-01-24 19:40:54 +01:00
PREDNASKY_PREFIX = " prednasky "
ZNALOSTI_PREFIX = " znalosti "
logger = logging . getLogger ( __name__ )
2025-01-29 01:05:08 +01:00
def newPrednaska ( request : HttpRequest ) - > HttpResponse :
"""
View zobrazující a ukládající účastnické hlasování
( : py : class : ` Hlasování < prednasky . models . Hlasovani > `
a : py : class : ` HlasováníOZnalostech < prednasky . models . HlasovaniOZnalostech > ` )
o : py : class : ` Přednáškách < prednasky . models . Prednaska > `
a : py : class : ` Znalostech < prednasky . models . Znalost > `
"""
2019-05-11 01:15:05 +02:00
# hlasovani se vztahuje k nejnovejsimu soustredeni
2025-01-21 21:43:43 +01:00
sous = Nastaveni . get_solo ( ) . aktualni_sous
2025-01-24 15:36:33 +01:00
seznam = Seznam . objects . filter ( soustredeni = sous , stav = Seznam . Stav . NAVRH ) . first ( )
2025-01-21 21:43:43 +01:00
if sous is None or seznam is None :
return render ( request , ' universal.html ' , {
' title ' : " Nelze hlasovat " ,
' text ' : " Není žádný seznam přednášek, o kterém by se dalo hlasovat. " ,
} , status = http . HTTPStatus . NOT_FOUND )
2025-01-24 19:40:54 +01:00
2020-09-05 20:46:22 +02:00
osoba = Osoba . objects . filter ( user = request . user ) . first ( )
2025-01-24 20:22:38 +01:00
ucastnik = osoba . plne_jmeno ( ) + ' ' + str ( osoba . id ) # id, kvůli kolizi jmen
2025-01-24 19:40:54 +01:00
2025-01-29 01:05:08 +01:00
if request . method == ' POST ' : # Když to byl POST, tak ukládáme.
# Načteme data do formsetů
2025-01-24 19:40:54 +01:00
form_set_prednasky = HlasovaniPrednaskaFormSet ( request . POST , prefix = PREDNASKY_PREFIX )
form_set_znalosti = HlasovaniZnalostiFormSet ( request . POST , prefix = ZNALOSTI_PREFIX )
if form_set_prednasky . is_valid ( ) and form_set_znalosti . is_valid ( ) :
with transaction . atomic ( ) :
2025-01-29 01:05:08 +01:00
# Místo updatování data prostě smažeme a vytvoříme nová
2025-01-24 19:40:54 +01:00
seznam . hlasovani_set . filter ( ucastnik = ucastnik ) . delete ( )
seznam . hlasovanioznalostech_set . filter ( ucastnik = osoba ) . delete ( )
for form in form_set_prednasky :
prednaska_id = form . cleaned_data [ ' prednaska_id ' ]
prednaska = Prednaska . objects . filter ( id = prednaska_id ) . first ( )
if prednaska is None :
logger . error ( f " Účastník { ucastnik } hodnotil neexistující přednášku { prednaska_id } číslem { form . cleaned_data [ ' body ' ] } " )
continue
Hlasovani . objects . create (
prednaska = prednaska ,
body = form . cleaned_data [ ' body ' ] ,
ucastnik = ucastnik ,
2025-02-19 18:38:38 +01:00
ucastnik_osoba = osoba ,
2025-01-24 19:40:54 +01:00
seznam = seznam ,
)
for form in form_set_znalosti :
znalost_id = form . cleaned_data [ ' znalost_id ' ]
znalost = Znalost . objects . filter ( id = znalost_id ) . first ( )
if znalost is None :
logger . error ( f " Účastník { ucastnik } hodnotil neexistující znalost { znalost_id } číslem { form . cleaned_data [ ' odpoved ' ] } " )
continue
HlasovaniOZnalostech . objects . create (
odpoved = form . cleaned_data [ ' odpoved ' ] ,
znalost = znalost ,
ucastnik = osoba ,
seznam = seznam ,
)
2019-05-11 01:15:05 +02:00
2025-01-24 19:40:54 +01:00
return HttpResponseRedirect ( ' ./hotovo ' )
2025-01-29 01:05:08 +01:00
else : # Pokud je nějaký formset nevalidní, vracíme je k přepracování
2025-01-24 19:40:54 +01:00
prednasky = seznam . prednaska_set . all ( )
znalosti = seznam . znalost_set . all ( )
2025-01-29 01:05:08 +01:00
# FIXME Spadnout, pokud nesedí přednáška/znalost s formulářem. (Nějak se mi to nepovedlo.)
# Může se totiž stát, že se mezitím změnily přednášky (nějaká byla přidána/odebrána)
2025-01-24 19:40:54 +01:00
2025-01-29 01:05:08 +01:00
else : # Když to nebyl POST, tak inicializujeme (pokud už o přednášce/znalosti účastník hlasoval, předvyplníme mu to).
def odpoved_prednasky ( p : Prednaska ) - > Hlasovani . Body :
2025-01-24 19:40:54 +01:00
hlasovani = p . hlasovani_set . filter ( ucastnik = ucastnik ) . first ( )
return hlasovani . body if hlasovani else Hlasovani . Body . JEDNO
2025-02-04 20:33:03 +01:00
def odpoved_znalosti ( z : Znalost ) - > HlasovaniOZnalostech . Odpoved :
2025-01-24 19:40:54 +01:00
hlasovani = z . hlasovanioznalostech_set . filter ( ucastnik = osoba ) . first ( )
2025-02-04 20:33:03 +01:00
return hlasovani . odpoved if hlasovani else HlasovaniOZnalostech . Odpoved . CIRCA
2025-01-24 19:40:54 +01:00
prednasky = seznam . prednaska_set . all ( )
znalosti = seznam . znalost_set . all ( )
form_set_prednasky = HlasovaniPrednaskaFormSet ( initial = [
{ " prednaska_id " : p . id , " body " : odpoved_prednasky ( p ) } for p in prednasky
] , prefix = PREDNASKY_PREFIX )
form_set_znalosti = HlasovaniZnalostiFormSet ( initial = [
{ " znalost_id " : z . id , " odpoved " : odpoved_znalosti ( z ) } for z in znalosti
] , prefix = ZNALOSTI_PREFIX )
2019-05-11 01:15:05 +02:00
2025-01-29 01:05:08 +01:00
# V případě nePOSTu nebo chyby při ukládání vracíme hlasování
2019-05-11 01:15:05 +02:00
return render (
request ,
' prednasky/base.html ' ,
2025-01-24 19:40:54 +01:00
{
' form_set_prednasky ' : form_set_prednasky , ' form_set_znalosti ' : form_set_znalosti ,
2025-02-21 16:42:11 +01:00
' formy_a_prednasky ' : list ( zip ( form_set_prednasky , prednasky ) ) ,
' formy_a_znalosti ' : list ( zip ( form_set_znalosti , znalosti ) ) ,
2025-01-24 19:40:54 +01:00
}
2019-05-11 01:15:05 +02:00
)
2017-10-06 01:37:09 +02:00
2016-04-18 01:14:08 +02:00
2025-01-29 01:05:08 +01:00
def Prednaska_hotovo ( request : HttpRequest ) - > HttpResponse :
""" View po vyplnění :py:func:`hlasování <prednasky.views.newPrednaska>` """
2025-01-21 21:14:19 +01:00
return formularOKView ( request , " Děkujeme za vyplnění hlasování o přednáškách a těšíme se na soustředění. " )
2016-04-17 23:48:39 +02:00
2016-10-04 23:53:56 +02:00
class MetaSeznamListView ( generic . ListView ) :
2025-01-29 01:05:08 +01:00
""" Seznam všech :py:class:`Seznamů <prednasky.models.Seznam>` s odkazy na exporty """
2019-05-11 01:15:05 +02:00
model = Seznam
template_name = ' prednasky/metaseznam_prednasek.html '
2016-10-04 23:53:56 +02:00
2017-10-06 01:15:20 +02:00
2025-01-29 01:05:08 +01:00
def PrednaskyExportView ( request : HttpRequest , seznam : int , * * kwargs ) - > HttpResponse :
"""
Vrátí všechna : py : class : ` Hlasování < prednasky . models . Hlasovani > `
i : py : class : ` HlasováníOZnalostech < prednasky . models . HlasovaniOZnalostech > `
v daném : py : class : ` Seznamu < prednasky . models . Seznam > `
jako csv soubor ( řádky = účastníci , sloupce = přednášky & znalosti ) .
: param seznam : ID daného : py : class : ` Seznamu < prednasky . models . Seznam > `
"""
2025-01-24 20:22:38 +01:00
hlasovani = Hlasovani . objects . filter ( seznam = seznam ) . select_related ( " prednaska " )
hlasovani_o_znalostech = HlasovaniOZnalostech . objects . filter ( seznam = seznam ) . select_related ( ' ucastnik ' , ' znalost ' )
2025-01-29 01:05:08 +01:00
# Inicializujeme sloupce
2025-01-24 20:22:38 +01:00
prednasky = list ( Prednaska . objects . filter ( seznamy = seznam ) )
znalosti = list ( Znalost . objects . filter ( seznamy = seznam ) )
prednasky_map : dict [ int , int ] = { p . id : i for i , p in enumerate ( prednasky , 1 ) }
offset = len ( prednasky_map )
znalosti_map : dict [ int , int ] = { z . id : i for i , z in enumerate ( znalosti , offset + 1 ) }
width = offset + len ( znalosti_map )
2025-01-29 01:05:08 +01:00
# A po inicializaci sloupců vyplníme tabulku
2025-01-24 20:22:38 +01:00
table : [ str , list [ str | Prednaska | Znalost , ] ] = { }
2025-02-22 16:38:11 +01:00
errors = [ ]
2025-01-24 20:22:38 +01:00
for h in hlasovani :
2025-01-29 01:05:08 +01:00
if h . ucastnik not in table : # Pokud jsme účastníka ještě neviděli, předgenerujeme si jeho řádek
2025-01-24 20:22:38 +01:00
table [ h . ucastnik ] = [ h . ucastnik ] + ( [ " " ] * width )
if h . prednaska . id in prednasky_map :
table [ h . ucastnik ] [ prednasky_map [ h . prednaska . id ] ] = h . body
else :
2025-02-22 16:38:11 +01:00
errors . append ( f " Přednáška { h . prednaska . id } ( { h . prednaska } ) dostala od Účastníka { h . ucastnik } následující hodnocení: { h . body } " )
2025-01-24 20:22:38 +01:00
for h in hlasovani_o_znalostech :
ucastnik = str ( h . ucastnik ) + ' ' + str ( h . ucastnik . id ) # id, kvůli kolizi jmen
2025-01-29 01:05:08 +01:00
if ucastnik not in table : # Pokud jsme účastníka ještě neviděli, předgenerujeme si jeho řádek
2025-01-24 20:22:38 +01:00
table [ ucastnik ] = [ ucastnik ] + ( [ " " ] * width )
if h . znalost . id in znalosti_map :
table [ ucastnik ] [ znalosti_map [ h . znalost . id ] ] = h . odpoved
else :
2025-02-22 16:38:11 +01:00
errors . append ( f " Znalost { h . znalost . id } ( { h . znalost } ) dostala od Účastníka { h . ucastnik . id } následující odpověď: { h . odpoved } " )
2025-01-24 20:22:38 +01:00
2025-02-22 16:38:11 +01:00
if len ( errors ) > 0 :
2025-02-26 14:25:32 +01:00
logger . error ( " Při exportování hlasování o přednáškách a znalostech se neexportovali hodnocení a přednášky (pravděpodobně se od hlasování vyškrtla nějaká znalost/přednáška ze seznamu): \n " + " \n " . join ( errors ) )
2025-01-24 20:22:38 +01:00
response = HttpResponse ( content_type = " text/csv " , charset = " utf-8 " )
response [ " Content-Disposition " ] = ' attachment; filename= " hlasovani.csv " '
writer = csv . writer ( response )
writer . writerow ( [ " jména \\ přednáška|znalost " ] + list ( map ( str , prednasky + znalosti ) ) )
for row in table . values ( ) :
writer . writerow ( list ( map ( str , row ) ) )
return response