Files
Sheerka-Old/src/sheerkapickle/sheerka_handlers.py
T
2021-01-11 15:36:03 +01:00

224 lines
7.5 KiB
Python

import core.utils
from core.builtin_concepts import UserInputConcept, ReturnValueConcept, BuiltinConcepts
from core.concept import Concept, PROPERTIES_TO_SERIALIZE as CONCEPT_PROPERTIES_TO_SERIALIZE
from core.global_symbols import NotInit
from core.rule import Rule
from core.sheerka.ExecutionContext import ExecutionContext, PROPERTIES_TO_SERIALIZE as CONTEXT_PROPERTIES_TO_SERIALIZE
from core.sheerka.Sheerka import Sheerka
from core.sheerka.services.SheerkaExecute import ParserInput
from evaluators.BaseEvaluator import BaseEvaluator
from parsers.BaseParser import BaseParser
from parsers.PythonParser import PythonNode
from sheerkapickle.handlers import BaseHandler, registry
default_concept = Concept()
default_concept_values = default_concept.values()
CONCEPT_ID = "concept/id"
RULE_ID = "rule/id"
class ConceptHandler(BaseHandler):
def flatten(self, obj: Concept, data):
pickler = self.context
sheerka = self.sheerka
if obj.get_metadata().full_serialization:
ref = default_concept
ref_values = default_concept_values
else:
ref = sheerka.get_by_id(obj.id)
ref_values = ref.values()
data[CONCEPT_ID] = (obj.key, obj.id)
# transform metadata
for name in CONCEPT_PROPERTIES_TO_SERIALIZE:
value = getattr(obj.get_metadata(), name)
ref_value = getattr(ref.get_metadata(), name)
if value != ref_value:
value_to_use = [list(t) for t in value] if name == "variables" else value
data["meta." + name] = pickler.flatten(value_to_use)
# # transform values
for name, value in obj.values().items():
if name not in ref_values or value != ref_values[name]:
if "values" not in data:
data["values"] = []
data["values"].append((pickler.flatten(name), pickler.flatten(value)))
return data
def new(self, data):
sheerka = self.sheerka
return sheerka.new(tuple(data[CONCEPT_ID])) if CONCEPT_ID in data else Concept()
def restore(self, data, instance):
pickler = self.context
for key, value in data.items():
if key.startswith("_sheerka/") or key == CONCEPT_ID:
continue
resolved_value = pickler.restore(data[key])
if key.startswith("meta."):
# get metadata
resolved_prop = key[5:]
if resolved_prop == "variables":
for prop_name, prop_value in resolved_value:
instance.def_var(prop_name, prop_value)
else:
setattr(instance.get_metadata(), resolved_prop, resolved_value)
elif key == "values":
# get properties
for prop_name, prop_value in resolved_value:
instance.set_value(prop_name, NotInit if prop_value is None else prop_value)
else:
raise Exception("Sanity check as it's not possible yet")
# instance.freeze_definition_hash()
return instance
class UserInputHandler(ConceptHandler):
def flatten(self, obj: UserInputConcept, data):
data[CONCEPT_ID] = (obj.key, obj.id)
data["user_name"] = obj.user_name
data["text"] = core.utils.get_text_from_tokens(obj.text) if isinstance(obj.text, list) else \
obj.text.as_text() if isinstance(obj.text, ParserInput) else \
obj.text
return data
def new(self, data):
return UserInputConcept.__new__(UserInputConcept)
def restore(self, data, instance):
instance.__init__(data["text"], data["user_name"])
instance.get_metadata().key = data[CONCEPT_ID][0]
instance.get_metadata().id = data[CONCEPT_ID][1]
instance.freeze_definition_hash()
return instance
class ReturnValueHandler(BaseHandler):
def flatten(self, obj: ReturnValueConcept, data):
pickler = self.context
data[CONCEPT_ID] = (obj.key, obj.id)
data["who"] = f"c:{obj.who.id}:" if isinstance(obj.who, Concept) else \
obj.who.name if isinstance(obj.who, (BaseParser, BaseEvaluator)) else \
obj.who
data["status"] = obj.status
data["value"] = pickler.flatten(obj.value)
if obj.parents:
data["parents"] = pickler.flatten(obj.parents)
return data
def new(self, data):
return ReturnValueConcept.__new__(ReturnValueConcept)
def restore(self, data, instance):
pickler = self.context
instance.__init__(data["who"], data["status"], pickler.restore(data["value"]))
if "parents" in data:
instance.parents = pickler.restore(data["parents"])
instance.get_metadata().key = data[CONCEPT_ID][0]
instance.get_metadata().id = data[CONCEPT_ID][1]
instance.freeze_definition_hash()
return instance
class SheerkaHandler(ConceptHandler):
# def flatten(self, obj: BuiltinConcepts, data):
# return ConceptHandler().flatten()data
def new(self, data):
return self.sheerka
# def restore(self, data, instance):
# return instance
class ExecutionContextHandler(BaseHandler):
def flatten(self, obj, data):
pickler = self.context
for prop in CONTEXT_PROPERTIES_TO_SERIALIZE:
if prop in ("who", "action", "action_context"):
value = str(getattr(obj, prop))
else:
value = getattr(obj, prop)
if value is not None:
data[prop] = pickler.flatten(value)
return data
def new(self, data):
return ExecutionContext(data["who"], None, self.sheerka, BuiltinConcepts.NOP, None)
def restore(self, data, instance):
pickler = self.context
for prop in CONTEXT_PROPERTIES_TO_SERIALIZE:
if prop not in data or prop == "who":
continue
setattr(instance, prop, pickler.restore(data[prop]))
return instance
class RuleContextHandler(BaseHandler):
def flatten(self, obj, data):
data[RULE_ID] = obj.id
data["name"] = obj.metadata.name
data["predicate"] = obj.metadata.predicate
data["action_type"] = obj.metadata.action_type
data["action"] = obj.metadata.action
return data
def new(self, data):
return Rule(data["action_type"], data["name"], data["predicate"], data["action"])
def restore(self, data, instance):
instance.metadata.id = data[RULE_ID]
return instance
class PythonNodeHandler(BaseHandler):
def flatten(self, obj, data):
pickler = self.context
data["source"] = obj.source
data["ast_str"] = obj.ast_str
data["objects"] = pickler.flatten(obj.objects)
return data
def new(self, data):
return PythonNode.__new__(PythonNode)
def restore(self, data, instance):
pickler = self.context
instance.__init__(data["source"], objects=pickler.restore(data["objects"]))
instance.ast_str = data["ast_str"]
return instance
def initialize_pickle_handlers():
registry.register(Concept, ConceptHandler, True)
registry.register(UserInputConcept, UserInputHandler, True)
registry.register(ReturnValueConcept, ReturnValueHandler, True)
registry.register(Sheerka, SheerkaHandler, True)
registry.register(ExecutionContext, ExecutionContextHandler, True)
registry.register(Rule, RuleContextHandler, True)
registry.register(PythonNode, PythonNodeHandler, True)