From c2483289fe89450411e464eb9692c335788c6018 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Wed, 3 Jun 2020 23:50:55 +0200 Subject: [PATCH] seminar | TreeNode editor ++ | Pridano odveseni a sirotcinec - doplneno nastavovani root u TreeNodu do testdat a treelib - pridana podpora odveseni do sirotcince - pridany funkce na smazani / nastaveni root u podstromu --- seminar/templates/seminar/orphanage.html | 23 ++++++++++ .../templates/seminar/treenode_recursive.html | 2 +- seminar/testutils.py | 46 +++++++++---------- seminar/treelib.py | 35 ++++++++++---- seminar/urls.py | 3 +- seminar/views/views_all.py | 18 ++++++-- 6 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 seminar/templates/seminar/orphanage.html diff --git a/seminar/templates/seminar/orphanage.html b/seminar/templates/seminar/orphanage.html new file mode 100644 index 00000000..8732b394 --- /dev/null +++ b/seminar/templates/seminar/orphanage.html @@ -0,0 +1,23 @@ +{% extends "seminar/archiv/base.html" %} +{% load staticfiles %} +{% load sekizai_tags %} + +{# toto z nejakeho duvodu nefunguje #} +{% addtoblock css %} +dfsdfs + +{% endaddtoblock "css" %} + +{% block custom_css %} + +{% endblock custom_css %} + +{% load comments %} + +{% block content %} + +{% endblock content %} diff --git a/seminar/templates/seminar/treenode_recursive.html b/seminar/templates/seminar/treenode_recursive.html index 89dfb594..6da7a96f 100644 --- a/seminar/templates/seminar/treenode_recursive.html +++ b/seminar/templates/seminar/treenode_recursive.html @@ -8,7 +8,7 @@ {% endif %} {% if obj.parent and obj.parent|editableSiblings %} - + {% endif %} {% if obj|canPodvesitPred %} - nejsou testovací data diff --git a/seminar/testutils.py b/seminar/testutils.py index 3c4356a2..0dc4782d 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -219,8 +219,8 @@ def gen_zadani_ulohy(rnd, cisla, organizatori, pocet_oboru, poradi_cisla, poradi na_web = text, do_cisla = text, ) - zad = TextNode.objects.create(text = text_zadani) - uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad) + zad = TextNode.objects.create(text = text_zadani, root = p.cislo_zadani.rocnik.rocniknode) + uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad, root = p.cislo_zadani.rocnik.rocniknode) p.ulohazadaninode = uloha_zadani otec_syn(cisla[poradi_cisla-2-1].cislonode, uloha_zadani) @@ -241,8 +241,8 @@ def gen_vzoroveho_reseni_ulohy(rnd, organizatori, uloha, pocet_opravovatelu): na_web = obsah, do_cisla = obsah ) - vzorak = TextNode.objects.create(text = text_vzoraku) - uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak) + vzorak = TextNode.objects.create(text = text_vzoraku, root = uloha.cislo_zadani.rocnik.rocniknode) + uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak, root = uloha.cislo_zadani.rocnik.rocniknode) uloha.ulohavzoraknode = uloha_vzorak uloha.opravovatele.set(rnd.sample(organizatori, pocet_opravovatelu)) @@ -409,7 +409,7 @@ def gen_cisla(rnd, rocniky): datum_deadline=deadline, verejne_db=True ) - node2 = CisloNode.objects.create(cislo = cislo, succ = node) + node2 = CisloNode.objects.create(cislo = cislo, succ = node, root=rocnik.rocniknode) cislo.save() node = node2 if otec: @@ -448,54 +448,54 @@ def gen_dlouhe_tema(rnd, organizatori, rocnik, nazev, obor, kod): for cislo in cisla: # Přidáme TemaVCisleNode do daného čísla cislo_node = cislo.cislonode - tema_cislo_node = TemaVCisleNode.objects.create(tema = tema) + tema_cislo_node = TemaVCisleNode.objects.create(tema = tema, root = cislo_node.root) insert_last_child(cislo_node, tema_cislo_node) # Přidávání obsahu do čísla - cast_node = m.CastNode.objects.create(nadpis = "Příspěvek k číslu {}".format(cislo.kod)) + cast_node = m.CastNode.objects.create(nadpis = "Příspěvek k číslu {}".format(cislo.kod), root=cislo_node.root) add_first_child(tema_cislo_node, cast_node) - text_node = TextNode.objects.create(text = get_text()) + text_node = TextNode.objects.create(text = get_text(), root=cislo_node.root) add_first_child(cast_node, text_node) - cast_node2 = m.CastNode.objects.create(nadpis = "První podproblém") + cast_node2 = m.CastNode.objects.create(nadpis = "První podproblém", root=cislo_node.root) add_first_child(text_node, cast_node2) - text_node2 = TextNode.objects.create(text = get_text()) + text_node2 = TextNode.objects.create(text = get_text(), root=cislo_node.root) add_first_child(cast_node2, text_node2) - cast_node3 = m.CastNode.objects.create(nadpis = "Druhý podproblém") + cast_node3 = m.CastNode.objects.create(nadpis = "Druhý podproblém", root=cislo_node.root) add_first_child(text_node2, cast_node3) - text_node3 = TextNode.objects.create(text = get_text()) + text_node3 = TextNode.objects.create(text = get_text(), root=cislo_node.root) add_first_child(cast_node3, text_node3) - cast_node4 = m.CastNode.objects.create(nadpis = "Třetí podproblém") + cast_node4 = m.CastNode.objects.create(nadpis = "Třetí podproblém", root=cislo_node.root) add_first_child(text_node3, cast_node4) - text_node4 = TextNode.objects.create(text = get_text()) + text_node4 = TextNode.objects.create(text = get_text(), root=cislo_node.root) add_first_child(cast_node3, text_node4) cast_node3a = m.CastNode.objects.create(nadpis = "Podproblém paralelní s " - "druhým podproblémem") + "druhým podproblémem", root=cislo_node.root) cast_node3.succ = cast_node3a cast_node3.save() - text_node3a = TextNode.objects.create(text = get_text()) + text_node3a = TextNode.objects.create(text = get_text(), root=cislo_node.root) add_first_child(cast_node3a, text_node3a) # Občas přidáme mezičíslo if rnd.randint(1, 3) == 1: - create_node_after(cislo_node, m.MezicisloNode) + create_node_after(cislo_node, m.MezicisloNode, root=cislo_node.root) mezicislo_node = cislo_node.succ cast_node_mezicislo = m.CastNode.objects.create( - nadpis = "Příspěvek k mezičíslu".format(cislo.kod)) + nadpis = "Příspěvek k mezičíslu".format(cislo.kod), root=cislo_node.root) add_first_child(mezicislo_node, cast_node_mezicislo) odstavec = lorem.paragraph() - text_mezicislo = Text.objects.create(na_web = odstavec, do_cisla = odstavec) - text_node_mezicislo = TextNode.objects.create(text = text_mezicislo) + text_mezicislo = Text.objects.create(na_web = odstavec, do_cisla = odstavec) + text_node_mezicislo = TextNode.objects.create(text = text_mezicislo, root=cislo_node.root) add_first_child(cast_node_mezicislo, text_node_mezicislo) return tema @@ -539,7 +539,7 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): # Vyrobíme TemaVCisleNody pro obsah for i in range(zacatek_tematu, konec_tematu+1): - node = TemaVCisleNode.objects.create(tema = t) + node = TemaVCisleNode.objects.create(tema = t,root=rocnik.rocniknode) # FIXME: Není to off-by-one? otec = cisla[i-1].cislonode otec_syn(otec, node) @@ -596,8 +596,8 @@ def gen_ulohy_tematu(rnd, organizatori, tema, kod, cislo, cislo_se_vzorakem): na_web = obsah, do_cisla = obsah, ) - zad = TextNode.objects.create(text = text_zadani) - uloha_zadani = UlohaZadaniNode.objects.create(uloha=uloha, first_child = zad) + zad = TextNode.objects.create(text = text_zadani, root=tema.temavcislenode_set.first().root) + uloha_zadani = UlohaZadaniNode.objects.create(uloha=uloha, first_child = zad, root=tema.temavcislenode_set.first().root) uloha.ulohazadaninode = uloha_zadani return uloha, uloha_zadani diff --git a/seminar/treelib.py b/seminar/treelib.py index b57b3459..03613d05 100644 --- a/seminar/treelib.py +++ b/seminar/treelib.py @@ -181,6 +181,7 @@ def get_prev_node_of_type(node, type): # Editace stromu: def create_node_after(predecessor, type, **kwargs): new_node = type.objects.create(**kwargs) + new_node.root = predecessor.root new_node.save() succ = predecessor.succ predecessor.succ = new_node @@ -192,6 +193,7 @@ def create_node_after(predecessor, type, **kwargs): # Vyrábí prvního syna, ostatní nalepí za (existují-li) def create_child(parent, type, **kwargs): new_node = type.objects.create(**kwargs) + new_node.root = parent.root new_node.save() orig_child = parent.first_child parent.first_child = new_node @@ -231,6 +233,7 @@ def create_node_before(successor, type, **kwargs): create_child(successor.father_of_first, type, **kwargs) # Teď už easy: Jsme sirotci, takže se vyrobíme a našeho následníka si přidáme jako succ new = type.objects.create(**kwargs) + new.root = successor.root new.succ = successor new.save() return new @@ -247,7 +250,6 @@ class TreeLibError(RuntimeError): @transaction.atomic -#FIXME Neřeší father-of-first! def swap_succ(node): if node is None: raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.") @@ -339,22 +341,20 @@ def lower_node(node): # To by mělo být všechno... -def delete_node(node): +def disconnect_node(node): + #FIXME: dodělat odstranění roota všem potomkům if node is None: - raise TreeLibError("Nelze smazat None. Tohle by se nemělo stát.") - if node.first_child: - raise TreeLibError("Mazání TreeNode s potomky není podporováno.") + raise TreeLibError("Nelze odpojit None. Tohle by se nemělo stát.") print(f'My:{node}, predchudce:{safe_pred(node)}, naslednik:{safe_succ(node)}, otec:{safe_father_of_first(node)}') # Jsme prvnim synem if safe_pred(node) is None: - if safe_succ(node) is None: # Jsme jedinym synem - upravime otce (pokud mame) a smazeme se + if safe_succ(node) is None: # Jsme jedinym synem - upravime otce (pokud mame) a odpojime se father = safe_father_of_first(node) if father is not None: father.first_child = None father.save() - node.delete() return else: # mame bratra @@ -363,5 +363,24 @@ def delete_node(node): # Jsme neprvním synem prev = node.prev prev.succ = node.succ - node.delete() + node.prev = None + node.succ = None + node.save() + clear_root(node) prev.save() + +def clear_root(node): + node.root = None + node.save() + if node.first_child: + clear_root(node.first_child) + if node.succ: + clear_root(node.succ) + +def set_root(node,root): + node.root = root + node.save() + if node.first_child: + clear_root(node.first_child) + if node.succ: + clear_root(node.succ) diff --git a/seminar/urls.py b/seminar/urls.py index e4655b99..fcaf8144 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -28,9 +28,10 @@ urlpatterns = [ path('treenode//', views.TreeNodeView.as_view(), name='seminar_treenode'), path('treenode/editor/pridat///', views.TreeNodePridatView.as_view(), name='treenode_pridat'), path('treenode/editor/smazat//', views.TreeNodeSmazatView.as_view(), name='treenode_smazat'), - path('treenode/editor/odvesit//', views.TreeNodeOdvesitView.as_view(), name='treenode_odvesit'), + path('treenode/editor/odvesitpryc//', views.TreeNodeOdvesitPrycView.as_view(), name='treenode_odvesitpryc'), path('treenode/editor/podvesit///', views.TreeNodePodvesitView.as_view(), name='treenode_podvesit'), path('treenode/editor/prohodit//', views.TreeNodeProhoditView.as_view(), name='treenode_prohodit'), + path('treenode/sirotcinec/', views.SirotcinecView.as_view(), name='seminar_treenode_sirotcinec'), #path('problem/(?P\d+)/(?P\d+)/', views.PrispevekView.as_view(), name='seminar_problem_prispevek'), # Soustredeni diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index e5aef445..746b1642 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -191,14 +191,18 @@ class TreeNodeSmazatView(generic.base.View): node = s.TreeNode.objects.get(pk=self.kwargs['pk']) if node.first_child: raise NotImplementedError('Mazání TreeNode se syny není zatím podporováno!') - treelib.delete_node(node) + treelib.disconnect_node(node) + node.delete() return redirect(request.headers.get('referer')) -class TreeNodeOdvesitView(generic.base.View): +class TreeNodeOdvesitPrycView(generic.base.View): def post(self, request, *args, **kwargs): node = s.TreeNode.objects.get(pk=self.kwargs['pk']) - pass - pass + treelib.disconnect_node(node) + node.root = None + node.save() + return redirect(request.headers.get('referer')) + class TreeNodePodvesitView(generic.base.View): def post(self, request, *args, **kwargs): @@ -217,6 +221,12 @@ class TreeNodeProhoditView(generic.base.View): return redirect(request.headers.get('referer')) #FIXME ve formulari predat puvodni url a vratit redirect na ni +class SirotcinecView(generic.ListView): + model = s.TreeNode + template_name = 'seminar/orphanage.html' + + def get_queryset(self): + return s.TreeNode.objects.not_instance_of(s.RocnikNode).filter(root=None) class ProblemView(generic.DetailView): model = s.Problem