from django.forms import model_to_dict from django.shortcuts import redirect from django.http import JsonResponse from django.views import generic from django.views.generic.edit import CreateView from django.contrib.auth.mixins import LoginRequiredMixin from django.core.exceptions import PermissionDenied from .models import * from seminar.models.pomocne import Text, Obrazek from treenode import treelib import treenode.forms as f import treenode.templatetags as tnltt import treenode.serializers as vr import logging logger = logging.getLogger(__name__) class TNLData(object): def __init__(self,anode,parent=None, index=None): self.node = anode self.sernode = vr.TreeNodeSerializer(anode) self.children = [] self.parent = parent self.tema_in_path = False self.index = index if parent: self.tema_in_path = parent.tema_in_path if isinstance(anode, TemaVCisleNode): self.tema_in_path = True def add_edit_options(self): self.deletable = tnltt.deletable(self) self.editable_siblings = tnltt.editableSiblings(self) self.editable_children = tnltt.editableChildren(self) self.text_only_subtree = tnltt.textOnlySubtree(self) self.can_podvesit_za = tnltt.canPodvesitZa(self) self.can_podvesit_pred = tnltt.canPodvesitPred(self) self.appendable_children = tnltt.appendableChildren(self) print("appChld",self.appendable_children) if self.parent: self.appendable_siblings = tnltt.appendableChildren(self.parent) else: self.appendable_siblings = [] @classmethod def public_above(cls, anode): """ Returns output of verejne for closest Rocnik, Cislo or Problem above. (All of them have method verejne.)""" parent = anode # chceme začít už od konkrétního node včetně while True: rocnik = isinstance(parent, RocnikNode) cislo = isinstance(parent, CisloNode) uloha = (isinstance(parent, UlohaVzorakNode) or isinstance(parent, UlohaZadaniNode)) tema = isinstance(parent, TemaVCisleNode) if (rocnik or cislo or uloha or tema) or parent==None: break else: parent = treelib.get_parent(parent) if rocnik: return parent.rocnik.verejne() elif cislo: return parent.cislo.verejne() elif uloha: return parent.uloha.verejne() elif tema: return parent.tema.verejne() elif None: print("Existuje TreeNode, který není pod číslem, ročníkem, úlohou" "ani tématem. {}".format(anode)) return False @classmethod def all_public_children(cls, anode): for ch in treelib.all_children(anode): if TNLData.public_above(ch): yield ch else: continue @classmethod def from_treenode(cls, anode, user, parent=None, index=None): if TNLData.public_above(anode) or user.has_perm('auth.org'): out = cls(anode,parent,index) else: raise PermissionDenied() if user.has_perm('auth.org'): enum_children = enumerate(treelib.all_children(anode)) else: enum_children = enumerate(TNLData.all_public_children(anode)) for (idx,ch) in enum_children: outitem = cls.from_treenode(ch, user, out, idx) out.children.append(outitem) out.add_edit_options() return out @classmethod def from_tnldata_list(cls, tnllist): """Vyrobíme virtuální TNL, který nemá obsah, ale má za potomky všechna zadaná TNLData""" result = cls(None) for idx, tnl in enumerate(tnllist): result.children.append(tnl) tnl.parent = result tnl.index = idx result.add_edit_options() return result @classmethod def filter_treenode(cls, treenode, predicate): tnll = cls._filter_treenode_recursive(treenode, predicate) # TreeNodeList List :-) return TNLData.from_tnldata_list(tnll) @classmethod def _filter_treenode_recursive(cls, treenode, predicate): if predicate(treenode): return [cls.from_treenode(treenode)] else: found = [] for tn in treelib.all_children(treenode): result = cls.filter_treenode(tn, predicate) # Result by v tuhle chvíli měl být seznam TNLDat odpovídající treenodům, jež matchnuly predikát. for tnl in result: found.append(tnl) return found def to_json(self): #self.node = anode #self.children = [] #self.parent = parent #self.tema_in_path = False #self.index = index out = {} out['node'] = self.sernode.data out['children'] = [n.to_json() for n in self.children] out['tema_in_path'] = self.tema_in_path out['index'] = self.index out['deletable'] = self.deletable out['editable_siblings'] = self.editable_siblings out['editable_children'] = self.editable_children out['text_only_subtree'] = self.text_only_subtree out['can_podvesit_za'] = self.can_podvesit_za out['can_podvesit_pod'] = self.can_podvesit_pred out['appendable_children'] = self.appendable_children out['appendable_siblings'] = self.appendable_siblings return out def __repr__(self): return("TNL({})".format(self.node)) class TreeNodeView(generic.DetailView): model = TreeNode template_name = 'treenode/treenode.html' def get_context_data(self,**kwargs): context = super().get_context_data(**kwargs) context['tnldata'] = TNLData.from_treenode(self.object,self.request.user) return context class TreeNodeJSONView(generic.DetailView): model = TreeNode def get(self,request,*args, **kwargs): self.object = self.get_object() data = TNLData.from_treenode(self.object,self.request.user).to_json() return JsonResponse(data) class TreeNodePridatView(generic.View): type_from_str = { 'rocnikNode': RocnikNode, 'cisloNode': CisloNode, 'castNode': CastNode, 'textNode': TextNode, 'temaVCisleNode': TemaVCisleNode, 'reseniNode': ReseniNode, 'ulohaZadaniNode': UlohaZadaniNode, 'ulohaVzorakNode': UlohaVzorakNode, 'pohadkaNode': PohadkaNode, 'orgText': OrgTextNode, } def post(self, request, *args, **kwargs): ######## FIXME: ROZEPSANE, NEFUNGUJE, DOPSAT !!!!!! ########### node = TreeNode.objects.get(pk=self.kwargs['pk']) kam = self.kwargs['kam'] co = self.kwargs['co'] typ = self.type_from_str[co] raise NotImplementedError('Neni to dopsane, dopis to!') if kam not in ('pred','syn','za'): raise ValidationError('Přidat lze pouze před nebo za node nebo jako syna') if co == TextNode: new_obj = Text() new_obj.save() elif co == CastNode: new_obj = CastNode() new_obj.nadpis = request.POST.get('pridat-castNode-{}-{}'.format(node.id,kam)) new_obj.save() elif co == ReseniNode: new_obj = m pass elif co == UlohaZadaniNode: pass elif co == UlohaReseniNode: pass else: new_obj = None if kam == 'pred': pass if kam == 'syn': if typ == TextNode: text_obj = Text() text_obj.save() node = treelib.create_child(node, typ, text=text_obj) else: node = treelib.create_child(node, typ) if kam == 'za': if typ == TextNode: text_obj = Text() text_obj.save() node = treelib.create_node_after(node, typ, text=text_obj) else: node = treelib.create_node_after(node, typ) return redirect(node.get_admin_url()) class TreeNodeSmazatView(generic.base.View): def post(self, request, *args, **kwargs): node = TreeNode.objects.get(pk=self.kwargs['pk']) if node.first_child: raise NotImplementedError('Mazání TreeNode se syny není zatím podporováno!') treelib.disconnect_node(node) node.delete() return redirect(request.headers.get('referer')) class TreeNodeOdvesitPrycView(generic.base.View): def post(self, request, *args, **kwargs): node = TreeNode.objects.get(pk=self.kwargs['pk']) 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): node = TreeNode.objects.get(pk=self.kwargs['pk']) kam = self.kwargs['kam'] if kam == 'pred': treelib.lower_node(node) elif kam == 'za': raise NotImplementedError('Podvěsit za není zatím podporováno') return redirect(request.headers.get('referer')) class TreeNodeProhoditView(generic.base.View): def post(self, request, *args, **kwargs): node = TreeNode.objects.get(pk=self.kwargs['pk']) treelib.swap_succ(node) return redirect(request.headers.get('referer')) #FIXME ve formulari predat puvodni url a vratit redirect na ni class SirotcinecView(generic.ListView): model = TreeNode template_name = 'treenode/orphanage.html' def get_queryset(self): return TreeNode.objects.not_instance_of(RocnikNode).filter(root=None,prev=None,succ=None,father_of_first=None) # FIXME pouzit Django REST Framework class TextWebView(generic.DetailView): model = Text def get(self,request,*args, **kwargs): self.object = self.get_object() return JsonResponse(model_to_dict(self.object,exclude='do_cisla')) class VueTestView(generic.TemplateView): template_name = 'treenode/vuetest.html' class NahrajObrazekKTreeNoduView(LoginRequiredMixin, CreateView): model = Obrazek form_class = f.NahrajObrazekKTreeNoduForm def get_initial(self): initial = super().get_initial() initial['na_web'] = self.request.FILES['upload'] return initial def form_valid(self,form): print(self.request.headers) print(self.request.headers['Textid']) print(form.instance) print(form) self.object = form.save(commit=False) print(self.object.na_web) self.object.text = Text.objects.get(pk=int(self.request.headers['Textid'])) self.object.save() return JsonResponse({"url":self.object.na_web.url})