From 645163cec83d96d70f7396a4d0d605c65284c5c8 Mon Sep 17 00:00:00 2001 From: Anet Date: Sun, 23 Aug 2020 18:46:47 +0200 Subject: [PATCH 1/5] =?UTF-8?q?views:=20zprovozn=C4=9Bn=C3=AD=20views=20?= =?UTF-8?q?=C5=99e=C5=A1itelsk=C3=BDch=20=C4=8Dl=C3=A1nk=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views/views_all.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 87c7dbe5..af34e69e 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -951,12 +951,41 @@ def soustredeniUcastniciExportView(request,soustredeni): ### Č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.''' + 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 class ClankyResitelView(generic.ListView): model = Problem 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) + #XXX + + #zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') # FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit #class ClankyOrganizatorView(generic.ListView): From ab4148e2e271c7bd1a936e5ba7f4c3adfb01970a Mon Sep 17 00:00:00 2001 From: Anet Date: Sun, 23 Aug 2020 23:22:17 +0200 Subject: [PATCH 2/5] orgorozcestnik: nabuseni statickych odkazu, pokus o nejake lehke dynamicke veci - rozdelane --- .../templates/seminar/clanky/resitelske_clanky.html | 2 +- seminar/urls.py | 3 +++ seminar/views/views_all.py | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/seminar/templates/seminar/clanky/resitelske_clanky.html b/seminar/templates/seminar/clanky/resitelske_clanky.html index 1e15fcbc..84089753 100644 --- a/seminar/templates/seminar/clanky/resitelske_clanky.html +++ b/seminar/templates/seminar/clanky/resitelske_clanky.html @@ -17,7 +17,7 @@ {% for clanek in object_list %} -{% with clanek.cislo_zadani.rocnik.rocnik as rocnik %} +{% with clanek.cislo.rocnik.rocnik as rocnik %} {% ifchanged rocnik %} {% if not forloop.first %}{% endif %}

{{ rocnik }}. ročník

diff --git a/seminar/urls.py b/seminar/urls.py index df2e1435..9c72717e 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -90,6 +90,9 @@ urlpatterns = [ path('org/vloz_body//', 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('login/', views.LoginView.as_view(), name='login'), path('logout/', views.LogoutView.as_view(), name='logout'), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index af34e69e..a80623d7 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -873,6 +873,16 @@ def oldObalkovaniView(request, rocnik, cislo): {'cislo': cislo, 'problemy': problemy, 'reseni': reseni} ) +### Orgostránky + +def OrgoRozcestnikView(request): + ''' Zobrazí organizátorský rozcestník.''' + posledni_soustredeni = Soustredeni.objects.order_by('-datum_konce').first() + + template_name = 'seminar/orgorozcestnik.html' + content_type = 'text/plain; charset=UTF8' + #XXX + ### Tituly def TitulyView(request, rocnik, cislo): @@ -983,7 +993,6 @@ class ClankyResitelView(generic.ListView): skupina.sort(key=lambda clanek: clanek.kod_v_rocniku()) for clanek in skupina: queryset.append(clanek) - #XXX #zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') From 64777359142862f3bab94724e9a50b6562415f11 Mon Sep 17 00:00:00 2001 From: Anet Date: Tue, 1 Sep 2020 23:04:19 +0200 Subject: [PATCH 3/5] =?UTF-8?q?orgorozhrani=20verze=20-1:=20z=C3=A1kladn?= =?UTF-8?q?=C3=AD=20v=C4=9Bci,=20u=20probl=C3=A9m=C5=AF=20je=20pot=C5=99eb?= =?UTF-8?q?a=20vymyslet,=20kam=20to=20m=C3=A1=20sm=C4=9Brovat,=20asi=20odk?= =?UTF-8?q?az=20na=20treenode=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/templates/seminar/orgorozcestnik.html | 86 +++++++++++ seminar/urls.py | 2 +- seminar/views/views_all.py | 138 +++++++++++------- 3 files changed, 170 insertions(+), 56 deletions(-) create mode 100644 seminar/templates/seminar/orgorozcestnik.html diff --git a/seminar/templates/seminar/orgorozcestnik.html b/seminar/templates/seminar/orgorozcestnik.html new file mode 100644 index 00000000..5bd75403 --- /dev/null +++ b/seminar/templates/seminar/orgorozcestnik.html @@ -0,0 +1,86 @@ +{% extends "base.html" %} + +{% block content %} +

Informace, komunikace

+ +
    +
  • wiki obsahuje různé návody a know-how
  • +
  • Riot chatování s dalšími orgy
  • +
  • Kanboard správa TODO + +
  • +
  • přidat novinku na web
  • +
+ +
+

Tvorba čísla

+ + +
+ +

Moje problémy

+ +

Témata

+
    +{% for t in temata %} +
  • {{ t }}
  • +{% endfor %} +
+ +

Úlohy

+
    +{% for u in ulohy %} +
  • {{ u }}
  • +{% endfor %} +
+ +

Články

+
    +{% for c in clanky %} +
  • {{ c }}
  • +{% endfor %} +
+ +
+

Soustředění

+ + + +
+

Můj profil

+ + + +
+

Nemůžeš najít, co hledáš? Může to být v administračním rozhraní webu.

+{% endblock content %} + diff --git a/seminar/urls.py b/seminar/urls.py index 9c72717e..ed42a7f8 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -91,7 +91,7 @@ urlpatterns = [ path('org/vloz_body//', staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'), # příprava na nestatický orgorozcestník - path('org/rozcestnik', + path('org/rozcestnik/', staff_member_required(views.OrgoRozcestnikView.as_view()),name='seminar_org_rozcestnik'), path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), path('login/', views.LoginView.as_view(), name='login'), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index a80623d7..242c4962 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q, Sum, Count from django.views.decorators.csrf import ensure_csrf_cookie 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 views as auth_views from django.contrib.auth.models import User @@ -200,7 +201,7 @@ class AktualniZadaniView(TreeNodeView): # "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) @@ -875,12 +876,39 @@ def oldObalkovaniView(request, rocnik, cislo): ### Orgostránky -def OrgoRozcestnikView(request): +class OrgoRozcestnikView(TemplateView): ''' Zobrazí organizátorský rozcestník.''' - posledni_soustredeni = Soustredeni.objects.order_by('-datum_konce').first() template_name = 'seminar/orgorozcestnik.html' - content_type = 'text/plain; charset=UTF8' + + 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 @@ -1109,57 +1137,57 @@ def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, 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 = ProfileEditForm(initial=prefill_1) - ## Změna údajů a jejich uložení - if request.method == 'POST': - form = ProfileEditForm(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/profil/edit.html', {'form': form}) + 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 = ProfileEditForm(initial=prefill_1) + ## Změna údajů a jejich uložení + if request.method == 'POST': + form = ProfileEditForm(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/profil/edit.html', {'form': form}) def prihlaskaView(request): generic_logger = logging.getLogger('seminar.prihlaska') From 80d608eb53c8acc9763b9b90068aa33489326df9 Mon Sep 17 00:00:00 2001 From: Jonas Havelka Date: Thu, 3 Sep 2020 16:07:52 +0200 Subject: [PATCH 4/5] =?UTF-8?q?Fix=20o=C5=A1et=C5=99en=C3=AD=20pr=C3=A1zdn?= =?UTF-8?q?=C3=A9ho=20seznamu=20a=20chybn=C3=A9ho=20logov=C3=A1n=C3=AD=20r?= =?UTF-8?q?egistrace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit = pád webu = nemožnost registrace --- seminar/views/views_all.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 242c4962..0144854a 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -992,6 +992,8 @@ def soustredeniUcastniciExportView(request,soustredeni): 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 = [] @@ -1131,7 +1133,7 @@ def logoutView(request): 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) gdpr_logger.warn(msg+", form:{}".format(form_data)) @@ -1199,8 +1201,8 @@ def prihlaskaView(request): if form.is_valid(): generic_logger.info("Form valid") fcd = form.cleaned_data - form_hash = hash(fcd) - form_logger.info(fcd,form_hash=form_hash) + form_hash = hash(frozenset(fcd.items())) + form_logger.info(fcd,form_hash) # TODO takhle log nefunguje, ale ta předchozí varianta dokonce padala with transaction.atomic(): u = User.objects.create_user( @@ -1230,7 +1232,7 @@ def prihlaskaView(request): else: # Unknown country - log it 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.user = u @@ -1248,7 +1250,7 @@ def prihlaskaView(request): else: # Unknown school - log it 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() From 6491d63714283df6147d61c0964e24bee67d1159 Mon Sep 17 00:00:00 2001 From: Jonas Havelka Date: Thu, 3 Sep 2020 16:12:50 +0200 Subject: [PATCH 5/5] =?UTF-8?q?Fix=20organiz=C3=A1tor=20musel=20m=C3=ADt?= =?UTF-8?q?=20vypln=C4=9Bn=C3=A9=20organizuje=20od=20/=20do,=20jinak=20vyh?= =?UTF-8?q?azovalo=20chybnou=20chybu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index deb0c9b9..79d08eae 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -582,7 +582,7 @@ class Organizator(SeminarModelBase): "školu, ale jen obor, možnost zobrazit zvlášť") 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!") super().clean()