+class NodeQuerySet(CachedQuerySet):\r
+ def obj_from_datadict(self, datadict):\r
+ cls = NodeMetaClass.types.get(datadict.get("node_type", ""), None)\r
+ if cls:\r
+ obj = cls()\r
+ obj.__dict__.update(datadict)\r
+ return obj\r
+ else:\r
+ return super(NodeQuerySet, self).obj_from_datadict(datadict)\r
+\r
+ def get(self, *args, **kwargs):\r
+ return super(NodeQuerySet, self).get(*args, **kwargs).leaf\r
+\r
+ def filter_state(self, **kwargs):\r
+ apply_bool = lambda q, b: b and q or ~q\r
+ return self.filter(*[apply_bool(models.Q(state_string__contains="(%s)" % s), b) for s, b in kwargs.items()])\r
+\r
+\r
+class NodeManager(CachedManager):\r
+ use_for_related_fields = True\r
+\r
+ def get_query_set(self):\r
+ qs = NodeQuerySet(self.model)\r
+\r
+ if self.model is not Node:\r
+ return qs.filter(node_type=self.model.get_type())\r
+ else:\r
+ return qs\r
+\r
+ def get_for_types(self, types, *args, **kwargs):\r
+ kwargs['node_type__in'] = [t.get_type() for t in types]\r
+ return self.get(*args, **kwargs)\r
+\r
+ def filter_state(self, **kwargs):\r
+ return self.all().filter_state(**kwargs)\r
+\r
+\r
+class NodeStateDict(object):\r
+ def __init__(self, node):\r
+ self.__dict__['_node'] = node\r
+\r
+ def __getattr__(self, name):\r
+ if self.__dict__.get(name, None):\r
+ return self.__dict__[name]\r
+\r
+ try:\r
+ node = self.__dict__['_node']\r
+ action = NodeState.objects.get(node=node, state_type=name).action\r
+ self.__dict__[name] = action\r
+ return action\r
+ except:\r
+ return None\r
+\r
+ def __setattr__(self, name, value):\r
+ current = self.__getattr__(name)\r
+\r
+ if value:\r
+ if current:\r
+ current.action = value\r
+ current.save()\r
+ else:\r
+ node = self.__dict__['_node']\r
+ state = NodeState(node=node, action=value, state_type=name)\r
+ state.save()\r
+ self.__dict__[name] = value\r
+\r
+ if not "(%s)" % name in node.state_string:\r
+ node.state_string = "%s(%s)" % (node.state_string, name)\r
+ node.save()\r
+ else:\r
+ if current:\r
+ node = self.__dict__['_node']\r
+ node.state_string = "".join("(%s)" % s for s in re.findall('\w+', node.state_string) if s != name)\r
+ node.save()\r
+ current.node_state.delete()\r
+ del self.__dict__[name]\r
+\r
+\r
+class NodeStateQuery(object):\r
+ def __init__(self, node):\r
+ self.__dict__['_node'] = node\r
+\r
+ def __getattr__(self, name):\r
+ node = self.__dict__['_node']\r
+ return "(%s)" % name in node.state_string\r
+\r
+\r
+\r
+class Node(BaseModel, NodeContent):\r