From d84cce71f32fd1a2aaa780b6d4c5b01467696065 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Thu, 19 Mar 2020 00:50:39 +0100 Subject: [PATCH] seminar | Prvni fungujici verze renderovani treenode struktury. --- seminar/templates/seminar/treenode.html | 10 + .../templates/seminar/treenode_recursive.html | 28 +++ seminar/templatetags/treenodes.py | 49 ++++ seminar/urls.py | 8 +- seminar/views/views_all.py | 219 ++++++++---------- 5 files changed, 191 insertions(+), 123 deletions(-) create mode 100644 seminar/templates/seminar/treenode.html create mode 100644 seminar/templates/seminar/treenode_recursive.html create mode 100644 seminar/templatetags/treenodes.py diff --git a/seminar/templates/seminar/treenode.html b/seminar/templates/seminar/treenode.html new file mode 100644 index 00000000..0fd734ef --- /dev/null +++ b/seminar/templates/seminar/treenode.html @@ -0,0 +1,10 @@ +{% extends "seminar/archiv/base_ulohy.html" %} + +{% load comments %} + +{% block content %} + +{%with obj=tnldata depth=1 template_name="seminar/treenode_recursive.html" %} + {%include template_name%} +{%endwith%} +{% endblock content %} diff --git a/seminar/templates/seminar/treenode_recursive.html b/seminar/templates/seminar/treenode_recursive.html new file mode 100644 index 00000000..0cf37d9a --- /dev/null +++ b/seminar/templates/seminar/treenode_recursive.html @@ -0,0 +1,28 @@ +{% load treenodes %} +{# {{depth}} #} +
+{% if obj.node|isRocnik %} + Ročník {{obj.node.rocnik}} +{% elif obj.node|isCislo %} + Číslo {{obj.node.cislo}} +{% elif obj.node|isTemaVCisle %} + Téma {{obj.node.tema.nazev}} +{% elif obj.node|isUlohaZadani %} +Úloha {{obj.node.uloha.kod_v_rocniku}} ({{obj.node.uloha.max_body}} b) +{% elif obj.node|isUlohaVzorak %} +Řešení: {{obj.node.uloha.kod_v_rocniku}} +{% elif obj.node|isText %} +{{obj.node.text.na_web}} +{% else %} +Objekt jiného typu {{obj.node}} +{% endif %} + {%if obj.children %} +
+ {%for ch in obj.children %} + {%with obj=ch depth=depth|add:"1" template_name="seminar/treenode_recursive.html" %} + {%include template_name%} + {%endwith%} + {%endfor%} +
+ {%endif%} +
diff --git a/seminar/templatetags/treenodes.py b/seminar/templatetags/treenodes.py new file mode 100644 index 00000000..0d60765e --- /dev/null +++ b/seminar/templatetags/treenodes.py @@ -0,0 +1,49 @@ +from django import template +import seminar.models as m + +register = template.Library() + +@register.filter +def isRocnik(value): + return isinstance(value, m.RocnikNode) + +@register.filter +def isCislo(value): + return isinstance(value, m.CisloNode) + +@register.filter +def isCast(value): + return isinstance(value, m.CastNode) + +@register.filter +def isText(value): + return isinstance(value, m.TextNode) + +@register.filter +def isTemaVCisle(value): + return isinstance(value, m.TemaVCisleNode) + +@register.filter +def isKonfera(value): + return isinstance(value, m.KonferaNode) + +@register.filter +def isClanek(value): + return isinstance(value, m.ClanekNode) + +@register.filter +def isUlohaVzorak(value): + return isinstance(value, m.UlohaVzorakNode) + +@register.filter +def isUlohaZadani(value): + return isinstance(value, m.UlohaZadaniNode) + +@register.filter +def isPohadka(value): + return isinstance(value, m.PohadkaNode) + +#@register.filter +#def isOtisteneReseniNode(value): +# return isinstance(value, m.OtisteneReseniNode) + diff --git a/seminar/urls.py b/seminar/urls.py index 1d5348da..002170c4 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -25,6 +25,7 @@ urlpatterns = [ path('rocnik//', views.RocnikView.as_view(), name='seminar_rocnik'), #path('cislo/./', views.CisloView.as_view(), name='seminar_cislo'), path('problem//', views.ProblemView.as_view(), name='seminar_problem'), + path('treenode//', views.TreeNodeView.as_view(), name='seminar_treenode'), #path('problem/(?P\d+)/(?P\d+)/', views.PrispevekView.as_view(), name='seminar_problem_prispevek'), # Soustredeni @@ -107,9 +108,6 @@ urlpatterns = [ path('auth/login/', views.LoginView.as_view(), name='login'), path('auth/logout/', views.LogoutView.as_view(), name='logout'), path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), - path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), - path('autocomplete/resitel/',views.ResitelAutocomplete.as_view(), name='autocomplete_resitel'), - path('autocomplete/problem/odevzdatelny',views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'), path('auth/reset_password/', views.PasswordResetView.as_view(), name='reset_password'), path('auth/change_password/', views.PasswordChangeView.as_view(), name='change_password'), path('auth/reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), @@ -117,6 +115,10 @@ urlpatterns = [ path('auth/reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), + # Autocomplete + path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), + path('autocomplete/resitel/',views.ResitelAutocomplete.as_view(), name='autocomplete_resitel'), + path('autocomplete/problem/odevzdatelny',views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'), path('temp/add_solution', views.AddSolutionView.as_view(),name='seminar_vloz_reseni'), path('temp/submit_solution', views.SubmitSolutionView.as_view(),name='seminar_nahraj_reseni'), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 3cfb0535..40357769 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -19,7 +19,7 @@ from django.db import transaction import seminar.models as s from seminar.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 seminar import utils +from seminar import utils,treelib from .unicodecsv import UnicodeWriter from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm import seminar.forms as f @@ -83,131 +83,110 @@ class ObalkovaniView(generic.ListView): context['cislo'] = self.cislo return context +class TNLData(object): + def __init__(self,anode): + self.node = anode + self.children = [] +def treenode_strom_na_seznamy(node): + out = TNLData(node) + for ch in treelib.all_children(node): + outitem = treenode_strom_na_seznamy(ch) + out.children.append(outitem) + return out -def AktualniZadaniView(request): - nastaveni = get_object_or_404(Nastaveni) - verejne = nastaveni.aktualni_cislo.verejne() - problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany') - ulohy = problemy.filter(typ = 'uloha').order_by('kod') - serialy = problemy.filter(typ = 'serial').order_by('kod') - jednorazove_problemy = [ulohy, serialy] - return render(request, 'seminar/zadani/AktualniZadani.html', - {'nastaveni': nastaveni, - 'jednorazove_problemy': jednorazove_problemy, - 'temata': verejna_temata(nastaveni.aktualni_rocnik), - 'verejne': verejne, - }, - ) - -def ZadaniTemataView(request): - nastaveni = get_object_or_404(Nastaveni) - temata = verejna_temata(nastaveni.aktualni_rocnik) - for t in temata: - if request.user.is_staff: - t.prispevky = t.prispevek_set.filter(problem=t) - else: - t.prispevky = t.prispevek_set.filter(problem=t, zverejnit=True) - return render(request, 'seminar/zadani/Temata.html', - { - 'temata': temata, - } - ) +class TreeNodeView(generic.DetailView): + model = s.TreeNode + template_name = 'seminar/treenode.html' -# 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 get_context_data(self,**kwargs): + context = super().get_context_data(**kwargs) + context['tnldata'] = treenode_strom_na_seznamy(self.object) + return context -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 AktualniZadaniView(request): +# nastaveni = get_object_or_404(Nastaveni) +# verejne = nastaveni.aktualni_cislo.verejne() +# problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany') +# ulohy = problemy.filter(typ = 'uloha').order_by('kod') +# serialy = problemy.filter(typ = 'serial').order_by('kod') +# jednorazove_problemy = [ulohy, serialy] +# return render(request, 'seminar/zadani/AktualniZadani.html', +# {'nastaveni': nastaveni, +# 'jednorazove_problemy': jednorazove_problemy, +# 'temata': verejna_temata(nastaveni.aktualni_rocnik), +# 'verejne': verejne, +# }, +# ) +# +#def ZadaniTemataView(request): +# nastaveni = get_object_or_404(Nastaveni) +# temata = verejna_temata(nastaveni.aktualni_rocnik) +# for t in temata: +# if request.user.is_staff: +# t.prispevky = t.prispevek_set.filter(problem=t) +# else: +# t.prispevky = t.prispevek_set.filter(problem=t, zverejnit=True) +# return render(request, 'seminar/zadani/Temata.html', +# { +# 'temata': temata, +# } +# ) +# +# +# +#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)