You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
9.2 KiB

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})