fmartingr
/
jeeves
Archived
1
0
Fork 0
This repository has been archived on 2021-02-14. You can view files and clone it, but cannot push or open issues or pull requests.
jeeves/jeeves/core/models.py

111 lines
2.8 KiB
Python

import copy
import json
from django.db import models
from jeeves.base.models import BaseModel
class DefinitionMixin:
@property
def definition(self):
return json.loads(self._definition)
@definition.setter
def definition(self, value: dict):
self._definition = json.dumps(value)
class Flow(BaseModel, DefinitionMixin):
name = models.CharField(max_length=64)
_definition = models.TextField()
def serialize(self):
definition = copy.deepcopy(self.definition)
definition["tasks"] = [task.serialize() for task in self.tasks]
return {"name": self.name, "definition": definition}
@property
def tasks(self):
for task_ref in self.definition["tasks"]:
yield Task.objects.from_reference(task_ref)
class TaskManager(models.Manager):
def from_reference(self, reference):
return self.get_queryset().get(pk=reference)
class Task(DefinitionMixin, BaseModel):
type = models.CharField(max_length=32)
_definition = models.TextField()
objects = TaskManager()
def serialize(self):
return {"type": self.type, "definition": self.definition}
def run(self, message=None):
from jeeves.tasks.shell import ShellTask
runner = ShellTask(**self.definition)
return Message(error=runner.execute(message))
class Run(DefinitionMixin, BaseModel):
PENDING = "pending"
FINISHED = "finished"
RUN_STATUS = ((PENDING, PENDING.capitalize()), (FINISHED, FINISHED.capitalize()))
status = models.CharField(max_length=32, choices=RUN_STATUS, default=PENDING)
success = models.BooleanField(default=True)
flow = models.ForeignKey(Flow, on_delete=models.CASCADE)
_definition = models.TextField()
_result = models.TextField(default="{}")
@classmethod
def execute_flow(cls, flow: Flow):
run = cls()
run.definition = flow.serialize()
run.flow = flow
message = None
for task in run.flow.tasks:
message = task.run(message=message)
if message.error:
run.success = False
run._result = json.dumps(message.serialize())
break
run.status = Run.FINISHED
run.save()
return run
class Message:
error: bool = False
def __init__(self, error):
self.error = error
def __repr__(self):
return f"<Message error={self.error}>"
def serialize(self):
return {"error": self.error}
class Result:
success: bool = True
last_message: Message
def __init__(self):
self.steps = []
def __repr__(self):
return f"""<Result
success={self.success}
last_message={self.last_message}>
"""
def to_dict(self):
return {"success": self.success, "last_message": self.last_message.to_dict()}