...
This commit is contained in:
82
herolib/core/heroscript/mixin.py
Normal file
82
herolib/core/heroscript/mixin.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Dict, Any, Type, TypeVar
|
||||
import re
|
||||
from colorama import Fore, Style
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from types import List
|
||||
from heroscript.heroaction import HeroAction
|
||||
from heroscript.tools import format_multiline_text
|
||||
|
||||
class HeroScriptMixin:
|
||||
|
||||
def heroscript(self) -> HeroAction:
|
||||
class_name = self.__class__.__name__.lower()
|
||||
prop_order = ["id", "oid", "name", "title", "description", "content"]
|
||||
|
||||
# Get all the properties of the object
|
||||
props = list(self.__fields__.keys())
|
||||
|
||||
# Separate properties into those in prop_order and the rest
|
||||
ordered_props = [prop for prop in prop_order if prop in props]
|
||||
remaining_props = [prop for prop in props if prop not in prop_order]
|
||||
|
||||
# Sort the remaining properties
|
||||
sorted_remaining_props = sorted(remaining_props)
|
||||
|
||||
# Combine the ordered properties and sorted remaining properties
|
||||
sorted_props = ordered_props + sorted_remaining_props
|
||||
|
||||
lines = [f"!!{class_name}.define"]
|
||||
for prop in sorted_props:
|
||||
if prop in self.__fields__:
|
||||
val = getattr(self, prop)
|
||||
if isinstance(val, str):
|
||||
if "\n" in val:
|
||||
val = format_multiline_text(text=val)
|
||||
elif any(c.isspace() for c in val):
|
||||
val = f"'{val}'"
|
||||
lines.append(f" {prop}:{val}")
|
||||
|
||||
result = "\n".join(lines)
|
||||
|
||||
return HeroAction(content=result)
|
||||
|
||||
@classmethod
|
||||
def from_heroscript(cls, heroscript: str):
|
||||
lines = heroscript.strip().split("\n")
|
||||
class_name = lines[0].split("!!")[1].split(".")[0]
|
||||
|
||||
props = {}
|
||||
multiline_prop = None
|
||||
multiline_value = List(str)
|
||||
|
||||
for line in lines[1:]:
|
||||
if multiline_prop:
|
||||
if line.strip() == "'":
|
||||
# End of multiline text
|
||||
min_indent = min(len(ml) - len(ml.lstrip()) for ml in multiline_value if ml.strip())
|
||||
unindented_lines = [ml[min_indent:] for ml in multiline_value]
|
||||
props[multiline_prop] = "\n".join(unindented_lines)
|
||||
multiline_prop = None
|
||||
multiline_value = []
|
||||
else:
|
||||
multiline_value.append(line)
|
||||
else:
|
||||
if ":" in line:
|
||||
prop, value = line.split(":", 1)
|
||||
prop = prop.strip()
|
||||
value = value.strip()
|
||||
|
||||
if value == "'":
|
||||
# Start of multiline text
|
||||
multiline_prop = prop
|
||||
else:
|
||||
if value.startswith("'") and value.endswith("'"):
|
||||
value = value[1:-1]
|
||||
props[prop] = value
|
||||
|
||||
return cls(**props)
|
||||
|
||||
|
Reference in New Issue
Block a user