Scheduler first commit

This commit is contained in:
robbe 2025-04-24 12:23:07 +02:00
parent 70c53a9aef
commit 2c64ebda67
24 changed files with 880 additions and 0 deletions

View file

@ -0,0 +1,129 @@
import sys
import os
import json
from uuid import UUID
from jinja2.runtime import Macro
from api.od import ODAPI
from jinja2 import Environment, FileSystemLoader, meta
class schedule_generator:
def __init__(self, odApi:ODAPI):
self.env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
self.env.trim_blocks = True
self.env.lstrip_blocks = True
self.template = self.env.get_template('schedule_template.j2')
self.template_wrap = self.env.get_template('schedule_template_wrap.j2')
self.api = odApi
def get_slot_value_default(item: UUID, slot:str, default):
if slot in self.api.get_slots(item):
return self.api.get_slot_value(item, slot)
return default
name_dict = lambda item: {"name": self.api.get_name(item)}
conn_dict = lambda item: {"name_from": self.api.get_name(self.api.get_source(item)),
"name_to": self.api.get_name(self.api.get_target(item)),
"gate_from": self.api.get_slot_value(item, "gate_from"),
"gate_to": self.api.get_slot_value(item, "gate_to"),
}
conn_data_event = {"Match": lambda item: False,
"Rewrite": lambda item: False,
"Data_modify": lambda item: True,
"Loop": lambda item: True,
"Print": lambda item: get_slot_value_default(item, "event", False)
}
conn_data_dict = lambda item: {"name_from": self.api.get_name(self.api.get_source(item)),
"name_to": self.api.get_name(self.api.get_target(item)),
"event": conn_data_event[self.api.get_type_name(target := self.api.get_target(item))](target)
}
rewrite_dict = lambda item: {"name": self.api.get_name(item),
"file": self.api.get_slot_value(item, "file"),
}
match_dict = lambda item: {"name": self.api.get_name(item),
"file": self.api.get_slot_value(item, "file"),
"n": self.api.get_slot_value(item, "n") \
if "n" in self.api.get_slots(item) else 'float("inf")'
}
data_modify_dict = lambda item: {"name": self.api.get_name(item),
"dict": json.loads(self.api.get_slot_value(item, "modify_dict"))
}
loop_dict = lambda item: {"name": self.api.get_name(item),
"choise": get_slot_value_default(item, "choise", False)}
print_dict = lambda item: {"name": self.api.get_name(item),
"label": get_slot_value_default(item, "label", "")}
arg_map = {"Start": name_dict, "End": name_dict,
"Match": match_dict, "Rewrite": rewrite_dict,
"Data_modify": data_modify_dict, "Loop": loop_dict,
"Exec_con": conn_dict, "Data_con": conn_data_dict,
"Print": print_dict}
self.macro_args = {tp: (macro, arg_map.get(tp)) for tp, macro in self.template.module.__dict__.items()
if type(macro) == Macro}
def _render(self, item):
type_name = self.api.get_type_name(item)
macro, arg_gen = self.macro_args[type_name]
return macro(**arg_gen(item))
def generate_schedule(self, stream = sys.stdout):
start = self.api.get_all_instances("Start")[0][1]
stack = [start]
out = {"blocks":[], "exec_conn":[], "data_conn":[], "match_files":set(), "matchers":[], "start":self.api.get_name(start)}
execBlocks = set()
exec_conn = list()
while len(stack) > 0:
exec_obj = stack.pop()
if exec_obj in execBlocks:
continue
execBlocks.add(exec_obj)
for conn in self.api.get_outgoing(exec_obj, "Exec_con"):
exec_conn.append(conn)
stack.append(self.api.get_target(conn))
stack = list(execBlocks)
data_blocks = set()
for name, p in self.api.get_all_instances("Print"):
if "event" in (event := self.api.get_slots(p)) and event:
stack.append(p)
execBlocks.add(p)
data_conn = set()
while len(stack) > 0:
obj = stack.pop()
for data_c in self.api.get_incoming(obj, "Data_con"):
data_conn.add(data_c)
source = self.api.get_source(data_c)
if not self.api.is_instance(source, "Exec") and \
source not in execBlocks and \
source not in data_blocks:
stack.append(source)
data_blocks.add(source)
for exec_item in execBlocks:
out["blocks"].append(self._render(exec_item))
if self.api.is_instance(exec_item, "Rule"):
d = self.macro_args[self.api.get_type_name(exec_item)][1](exec_item)
out["match_files"].add(d["file"])
out["matchers"].append(d)
for exec_c in exec_conn:
out["exec_conn"].append(self._render(exec_c))
for data_c in data_conn:
out["data_conn"].append(self._render(data_c))
for data_b in data_blocks:
out["blocks"].append(self._render(data_b))
print(self.template_wrap.render(out), file=stream)
# print("with open('test.dot', 'w') as f:", file=stream)
# print(f"\tf.write({self.api.get_name(start)}.generate_dot())", file=stream)