Merge branch 'data_migrations' into test
This commit is contained in:
commit
af803ddfb7
5 changed files with 216 additions and 59 deletions
|
@ -582,7 +582,7 @@ class Organizator(SeminarModelBase):
|
||||||
"školu, ale jen obor, možnost zobrazit zvlášť")
|
"školu, ale jen obor, možnost zobrazit zvlášť")
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if self.organizuje_od > self.organizuje_do:
|
if self.organizuje_od and self.organizuje_do and (self.organizuje_od > self.organizuje_do):
|
||||||
raise ValidationError("Organizátor nemůže skončit s organizováním dříve než začal!")
|
raise ValidationError("Organizátor nemůže skončit s organizováním dříve než začal!")
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{% for clanek in object_list %}
|
{% for clanek in object_list %}
|
||||||
{% with clanek.cislo_zadani.rocnik.rocnik as rocnik %}
|
{% with clanek.cislo.rocnik.rocnik as rocnik %}
|
||||||
{% ifchanged rocnik %}
|
{% ifchanged rocnik %}
|
||||||
{% if not forloop.first %}</ul>{% endif %}
|
{% if not forloop.first %}</ul>{% endif %}
|
||||||
<h2>{{ rocnik }}. ročník</h2>
|
<h2>{{ rocnik }}. ročník</h2>
|
||||||
|
|
86
seminar/templates/seminar/orgorozcestnik.html
Normal file
86
seminar/templates/seminar/orgorozcestnik.html
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2><strong>Informace, komunikace</strong></h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong><a href="https://wiki.mam.bezva.org/">wiki</a> </strong>obsahuje různé návody a know-how</li>
|
||||||
|
<li><strong><a href="https://riot.im/app/#/room/#orgovna:dolujeme.eu">Riot</a> </strong>chatování s dalšími orgy</li>
|
||||||
|
<li><strong>Kanboard </strong>správa TODO
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://kanboard.ledoian.cz/?controller=BoardViewController&action=show&project_id=10">webařský</a></li>
|
||||||
|
<li>soustředění</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/admin/seminar/novinky/add/"><strong>přidat novinku</strong></a> na web</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2><strong>Tvorba čísla</strong></h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/admin/seminar/problemnavrh/add/"><strong>přidat téma</strong></a></li>
|
||||||
|
<li><strong>korektury</strong>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/korektury/">korekturování</a></li>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href='{{ posledni_cislo_url }}'><strong>poslední vydané číslo </strong></a></li>
|
||||||
|
</ul>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h2><strong>Moje problémy</strong></h2>
|
||||||
|
|
||||||
|
<h3> Témata </h3>
|
||||||
|
<ul>
|
||||||
|
{% for t in temata %}
|
||||||
|
<li> {{ t }} </li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3> Úlohy </h3>
|
||||||
|
<ul>
|
||||||
|
{% for u in ulohy %}
|
||||||
|
<li> {{ u }} </li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3> Články </h3>
|
||||||
|
<ul>
|
||||||
|
{% for c in clanky %}
|
||||||
|
<li> {{ c }} </li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2><strong>Soustředění</strong></h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>přednášky</strong>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/admin/prednasky/prednaska/">vypisování přednášek</a></li>
|
||||||
|
<li>hlasování o přednáškách</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://mam.mff.cuni.cz/soustredeni/probehlo/">proběhlá soustředění</a>
|
||||||
|
<ul>
|
||||||
|
<li>vytvoření galerie</li>
|
||||||
|
<li>stažení seznamu účastníků</li>
|
||||||
|
<li>obálky</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2><strong>Můj profil</strong></h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://127.0.0.1:8000/admin/seminar/organizator/{{ organizator.id }}/change/"><strong>upravit </strong></a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<p>Nemůžeš najít, co hledáš? Může to být v <a href="https://mam.mff.cuni.cz/admin/">administračním rozhraní webu</a>.</p>
|
||||||
|
{% endblock content %}
|
||||||
|
|
|
@ -90,6 +90,9 @@ urlpatterns = [
|
||||||
|
|
||||||
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'),
|
||||||
|
# příprava na nestatický orgorozcestník
|
||||||
|
path('org/rozcestnik/',
|
||||||
|
staff_member_required(views.OrgoRozcestnikView.as_view()),name='seminar_org_rozcestnik'),
|
||||||
path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
|
path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
|
||||||
path('login/', views.LoginView.as_view(), name='login'),
|
path('login/', views.LoginView.as_view(), name='login'),
|
||||||
path('logout/', views.LogoutView.as_view(), name='logout'),
|
path('logout/', views.LogoutView.as_view(), name='logout'),
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect
|
||||||
from django.db.models import Q, Sum, Count
|
from django.db.models import Q, Sum, Count
|
||||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||||
from django.views.generic.edit import FormView, CreateView
|
from django.views.generic.edit import FormView, CreateView
|
||||||
|
from django.views.generic.base import TemplateView
|
||||||
from django.contrib.auth import authenticate, login, get_user_model, logout
|
from django.contrib.auth import authenticate, login, get_user_model, logout
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
@ -200,7 +201,7 @@ class AktualniZadaniView(TreeNodeView):
|
||||||
# "cisla" : cisla
|
# "cisla" : cisla
|
||||||
# })
|
# })
|
||||||
# return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka, "rocnik" : nastaveni.aktualni_rocnik().rocnik})
|
# return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka, "rocnik" : nastaveni.aktualni_rocnik().rocnik})
|
||||||
#
|
#
|
||||||
|
|
||||||
#def ZadaniAktualniVysledkovkaView(request):
|
#def ZadaniAktualniVysledkovkaView(request):
|
||||||
# nastaveni = get_object_or_404(Nastaveni)
|
# nastaveni = get_object_or_404(Nastaveni)
|
||||||
|
@ -873,6 +874,43 @@ def oldObalkovaniView(request, rocnik, cislo):
|
||||||
{'cislo': cislo, 'problemy': problemy, 'reseni': reseni}
|
{'cislo': cislo, 'problemy': problemy, 'reseni': reseni}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
### Orgostránky
|
||||||
|
|
||||||
|
class OrgoRozcestnikView(TemplateView):
|
||||||
|
''' Zobrazí organizátorský rozcestník.'''
|
||||||
|
|
||||||
|
template_name = 'seminar/orgorozcestnik.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['posledni_soustredeni'] = Soustredeni.objects.order_by('-datum_konce').first()
|
||||||
|
nastaveni = Nastaveni.objects.first()
|
||||||
|
aktualni_rocnik = nastaveni.aktualni_rocnik
|
||||||
|
context['posledni_cislo_url'] = nastaveni.aktualni_cislo.verejne_url()
|
||||||
|
# TODO možná chceme odkazovat na právě rozpracované číslo, a ne to poslední vydané
|
||||||
|
# pokud nechceme haluzit kód (= poradi) dalšího čísla, bude asi potřeba jít
|
||||||
|
# přes treenody (a dát si přitom pozor na MezicisloNode)
|
||||||
|
|
||||||
|
u = self.request.user
|
||||||
|
os = s.Osoba.objects.get(user=u)
|
||||||
|
organizator = s.Organizator.objects.get(osoba=os)
|
||||||
|
temata_garant = s.Tema.objects.filter(garant=organizator,
|
||||||
|
rocnik=aktualni_rocnik)
|
||||||
|
#FIXME: přidat opravovatel, stav='STAV_ZADANY'
|
||||||
|
ulohy_garant = s.Uloha.objects.filter(garant=organizator,
|
||||||
|
cislo_zadani__rocnik=aktualni_rocnik)
|
||||||
|
clanky_garant = s.Clanek.objects.filter(garant=organizator,
|
||||||
|
cislo__rocnik=aktualni_rocnik)
|
||||||
|
|
||||||
|
context['temata'] = temata_garant
|
||||||
|
context['ulohy'] = ulohy_garant
|
||||||
|
context['clanky'] = clanky_garant
|
||||||
|
context['organizator'] = organizator
|
||||||
|
return context
|
||||||
|
|
||||||
|
#content_type = 'text/plain; charset=UTF8'
|
||||||
|
#XXX
|
||||||
|
|
||||||
### Tituly
|
### Tituly
|
||||||
|
|
||||||
def TitulyView(request, rocnik, cislo):
|
def TitulyView(request, rocnik, cislo):
|
||||||
|
@ -951,12 +989,42 @@ def soustredeniUcastniciExportView(request,soustredeni):
|
||||||
|
|
||||||
|
|
||||||
### Články
|
### Články
|
||||||
|
def group_by_rocnik(clanky):
|
||||||
|
''' Vezme zadaný seznam článků a seskupí je podle ročníku.
|
||||||
|
Vrátí seznam seznamů článků ze stejného ročníku.'''
|
||||||
|
if len(clanky) == 0:
|
||||||
|
return clanky
|
||||||
|
clanky.order_by('cislo__rocnik__rocnik')
|
||||||
|
skupiny_clanku = []
|
||||||
|
skupina = []
|
||||||
|
|
||||||
|
rocnik = clanky.first().cislo.rocnik.rocnik # první ročník
|
||||||
|
for clanek in clanky:
|
||||||
|
if clanek.cislo.rocnik.rocnik == rocnik:
|
||||||
|
skupina.append(clanek)
|
||||||
|
else:
|
||||||
|
skupiny_clanku.append(skupina)
|
||||||
|
skupina = []
|
||||||
|
skupina.append(clanek)
|
||||||
|
rocnik = clanek.cislo.rocnik.rocnik
|
||||||
|
skupiny_clanku.append(skupina)
|
||||||
|
return skupiny_clanku
|
||||||
|
|
||||||
|
|
||||||
# FIXME: clanky jsou vsechny, pokud budou i neresitelske, tak se take zobrazi
|
# FIXME: clanky jsou vsechny, pokud budou i neresitelske, tak se take zobrazi
|
||||||
class ClankyResitelView(generic.ListView):
|
class ClankyResitelView(generic.ListView):
|
||||||
model = Problem
|
model = Problem
|
||||||
template_name = 'seminar/clanky/resitelske_clanky.html'
|
template_name = 'seminar/clanky/resitelske_clanky.html'
|
||||||
queryset = Clanek.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod')
|
#queryset
|
||||||
|
clanky = Clanek.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo__rocnik').order_by('-cislo__rocnik__rocnik')
|
||||||
|
queryset = []
|
||||||
|
skupiny_clanku = group_by_rocnik(clanky)
|
||||||
|
for skupina in skupiny_clanku:
|
||||||
|
skupina.sort(key=lambda clanek: clanek.kod_v_rocniku())
|
||||||
|
for clanek in skupina:
|
||||||
|
queryset.append(clanek)
|
||||||
|
|
||||||
|
#zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod')
|
||||||
|
|
||||||
# FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit
|
# FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit
|
||||||
#class ClankyOrganizatorView(generic.ListView)<F12>:
|
#class ClankyOrganizatorView(generic.ListView)<F12>:
|
||||||
|
@ -1065,63 +1133,63 @@ def logoutView(request):
|
||||||
|
|
||||||
|
|
||||||
def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data):
|
def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data):
|
||||||
msg = "{}, form_hash:{}".format(msg,hash(form_data))
|
msg = "{}, form_hash:{}".format(msg,hash(frozenset(form_data.items)))
|
||||||
logger.warn(msg)
|
logger.warn(msg)
|
||||||
gdpr_logger.warn(msg+", form:{}".format(form_data))
|
gdpr_logger.warn(msg+", form:{}".format(form_data))
|
||||||
|
|
||||||
from django.forms.models import model_to_dict
|
from django.forms.models import model_to_dict
|
||||||
def resitelEditView(request):
|
def resitelEditView(request):
|
||||||
err_logger = logging.getLogger('seminar.prihlaska.problem')
|
err_logger = logging.getLogger('seminar.prihlaska.problem')
|
||||||
## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately
|
## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately
|
||||||
u = request.user
|
u = request.user
|
||||||
osoba_edit = Osoba.objects.get(user=u)
|
osoba_edit = Osoba.objects.get(user=u)
|
||||||
resitel_edit = osoba_edit.resitel
|
resitel_edit = osoba_edit.resitel
|
||||||
user_edit = osoba_edit.user
|
user_edit = osoba_edit.user
|
||||||
## Vytvoření slovníku, kterým předvyplním formulář
|
## Vytvoření slovníku, kterým předvyplním formulář
|
||||||
prefill_1=model_to_dict(user_edit)
|
prefill_1=model_to_dict(user_edit)
|
||||||
prefill_2=model_to_dict(resitel_edit)
|
prefill_2=model_to_dict(resitel_edit)
|
||||||
prefill_3=model_to_dict(osoba_edit)
|
prefill_3=model_to_dict(osoba_edit)
|
||||||
prefill_1.update(prefill_2)
|
prefill_1.update(prefill_2)
|
||||||
prefill_1.update(prefill_3)
|
prefill_1.update(prefill_3)
|
||||||
form = ProfileEditForm(initial=prefill_1)
|
form = ProfileEditForm(initial=prefill_1)
|
||||||
## Změna údajů a jejich uložení
|
## Změna údajů a jejich uložení
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ProfileEditForm(request.POST)
|
form = ProfileEditForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
## Změny v osobě
|
## Změny v osobě
|
||||||
fcd = form.cleaned_data
|
fcd = form.cleaned_data
|
||||||
osoba_edit.jmeno = fcd['jmeno']
|
osoba_edit.jmeno = fcd['jmeno']
|
||||||
osoba_edit.prijmeni = fcd['prijmeni']
|
osoba_edit.prijmeni = fcd['prijmeni']
|
||||||
osoba_edit.pohlavi_muz = fcd['pohlavi_muz']
|
osoba_edit.pohlavi_muz = fcd['pohlavi_muz']
|
||||||
osoba_edit.email = fcd['email']
|
osoba_edit.email = fcd['email']
|
||||||
osoba_edit.telefon = fcd['telefon']
|
osoba_edit.telefon = fcd['telefon']
|
||||||
osoba_edit.ulice = fcd['ulice']
|
osoba_edit.ulice = fcd['ulice']
|
||||||
osoba_edit.mesto = fcd['mesto']
|
osoba_edit.mesto = fcd['mesto']
|
||||||
osoba_edit.psc = fcd['psc']
|
osoba_edit.psc = fcd['psc']
|
||||||
## Změny v osobě s podmínkami
|
## Změny v osobě s podmínkami
|
||||||
if fcd.get('spam',False):
|
if fcd.get('spam',False):
|
||||||
osoba_edit.datum_souhlasu_zasilani = date.today()
|
osoba_edit.datum_souhlasu_zasilani = date.today()
|
||||||
if fcd.get('stat','') in ('CZ','SK'):
|
if fcd.get('stat','') in ('CZ','SK'):
|
||||||
osoba_edit.stat = fcd['stat']
|
osoba_edit.stat = fcd['stat']
|
||||||
else:
|
else:
|
||||||
## Neznámá země
|
## Neznámá země
|
||||||
msg = "Unknown country {}".format(fcd['stat_text'])
|
msg = "Unknown country {}".format(fcd['stat_text'])
|
||||||
|
|
||||||
## Změny v řešiteli
|
## Změny v řešiteli
|
||||||
resitel_edit.skola = fcd['skola']
|
resitel_edit.skola = fcd['skola']
|
||||||
resitel_edit.rok_maturity = fcd['rok_maturity']
|
resitel_edit.rok_maturity = fcd['rok_maturity']
|
||||||
resitel_edit.zasilat = fcd['zasilat']
|
resitel_edit.zasilat = fcd['zasilat']
|
||||||
if fcd.get('skola'):
|
if fcd.get('skola'):
|
||||||
resitel_edit.skola = fcd['skola']
|
resitel_edit.skola = fcd['skola']
|
||||||
else:
|
else:
|
||||||
# Unknown school - log it
|
# Unknown school - log it
|
||||||
msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa'])
|
msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa'])
|
||||||
resitel_edit.save()
|
resitel_edit.save()
|
||||||
osoba_edit.save()
|
osoba_edit.save()
|
||||||
return HttpResponseRedirect('/thanks/')
|
return HttpResponseRedirect('/thanks/')
|
||||||
else:
|
else:
|
||||||
## Stránka před odeslaním formuláře = předvyplněný formulář
|
## Stránka před odeslaním formuláře = předvyplněný formulář
|
||||||
return render(request, 'seminar/profil/edit.html', {'form': form})
|
return render(request, 'seminar/profil/edit.html', {'form': form})
|
||||||
|
|
||||||
def prihlaskaView(request):
|
def prihlaskaView(request):
|
||||||
generic_logger = logging.getLogger('seminar.prihlaska')
|
generic_logger = logging.getLogger('seminar.prihlaska')
|
||||||
|
@ -1133,8 +1201,8 @@ def prihlaskaView(request):
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
generic_logger.info("Form valid")
|
generic_logger.info("Form valid")
|
||||||
fcd = form.cleaned_data
|
fcd = form.cleaned_data
|
||||||
form_hash = hash(fcd)
|
form_hash = hash(frozenset(fcd.items()))
|
||||||
form_logger.info(fcd,form_hash=form_hash)
|
form_logger.info(fcd,form_hash) # TODO takhle log nefunguje, ale ta předchozí varianta dokonce padala
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
u = User.objects.create_user(
|
u = User.objects.create_user(
|
||||||
|
@ -1164,7 +1232,7 @@ def prihlaskaView(request):
|
||||||
else:
|
else:
|
||||||
# Unknown country - log it
|
# Unknown country - log it
|
||||||
msg = "Unknown country {}".format(fcd['stat_text'])
|
msg = "Unknown country {}".format(fcd['stat_text'])
|
||||||
err_logger.warn(msg,form_hash=form_hash)
|
err_logger.warn(msg,form_hash) # TODO viz výše
|
||||||
|
|
||||||
o.save()
|
o.save()
|
||||||
o.user = u
|
o.user = u
|
||||||
|
@ -1182,7 +1250,7 @@ def prihlaskaView(request):
|
||||||
else:
|
else:
|
||||||
# Unknown school - log it
|
# Unknown school - log it
|
||||||
msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa'])
|
msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa'])
|
||||||
err_logger.warn(msg,form_hash=form_hash)
|
err_logger.warn(msg,form_hash) # TODO viz výše
|
||||||
r.save()
|
r.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue