322 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			322 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 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 TemaVCisleNode, RocnikNode, CisloNode, UlohaVzorakNode, UlohaZadaniNode, TreeNode, CastNode, TextNode, ReseniNode, PohadkaNode, OrgTextNode
 | |
| from .models 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})
 | 
