83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
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)
|
|
|
|
|