102 lines
2.4 KiB
Python
102 lines
2.4 KiB
Python
import importlib, json
|
|
|
|
from typing import Any, List
|
|
|
|
class Message():
|
|
|
|
_USM_AGENT_CODE = "CZDygPSF2HJTLKVIqys1";
|
|
|
|
_ATTRIBUTES = { # * in name -> optional
|
|
"id" : str,
|
|
"sub_ids*" : List[str],
|
|
"riddle" : "ums.messages.specials.Riddle",
|
|
"solution*" : "ums.messages.specials.Solution",
|
|
"data" : "ums.messages.specials.RiddleData",
|
|
"status" : "ums.messages.specials.RiddleStatus"
|
|
}
|
|
|
|
_DEFAULTS = {
|
|
"data" : ("ums.messages.specials", "RiddleData"),
|
|
"status" : ("ums.messages.specials", "RiddleStatus")
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
if len(args) > 0:
|
|
self.__dict__['items'] = list(args)
|
|
elif len(kwargs) > 0:
|
|
self.__dict__['items'] = kwargs
|
|
else:
|
|
self.__dict__['items'] = self._DEFAULTS
|
|
|
|
self._check_attr()
|
|
|
|
def __getattr__(self, name: str) -> Any:
|
|
if 'items' in self.__dict__ and isinstance(self.items, dict) and name in self.items:
|
|
return self.items[name]
|
|
|
|
def __setattr__(self, name: str, value: Any) -> None:
|
|
if hasattr(self, name):
|
|
setattr(self, name, value)
|
|
elif isinstance(self.items, dict):
|
|
self.items[name] = value
|
|
self._check_attr()
|
|
|
|
def _check_attr(self):
|
|
if isinstance(self._ATTRIBUTES, list):
|
|
assert isinstance(self.items, list), \
|
|
"{} content must be a list and not a dict!".format(self.__class__.__name__)
|
|
|
|
elif isinstance(self._ATTRIBUTES, dict):
|
|
assert isinstance(self.items, dict), \
|
|
"{} content must be a dict and not a list!".format(self.__class__.__name__)
|
|
|
|
for k,v in self._ATTRIBUTES.items():
|
|
if not k.endswith('*') and not k in self.items:
|
|
if k in self._DEFAULTS:
|
|
if isinstance(self._DEFAULTS[k], tuple):
|
|
def_class = getattr(
|
|
importlib.import_module(self._DEFAULTS[k][0]),
|
|
self._DEFAULTS[k][1]
|
|
)
|
|
self.items[k] = def_class()
|
|
else:
|
|
self.items[k] = self._DEFAULTS[k]
|
|
else:
|
|
raise ValueError("Message requires field {}, but not set (and no default)!".format(k))
|
|
|
|
if isinstance(v, str):
|
|
# a class name
|
|
pass
|
|
|
|
elif isinstance(v, dict):
|
|
# a sub structure
|
|
pass
|
|
|
|
else: # a type
|
|
pass
|
|
|
|
|
|
def _to_json(self):
|
|
return self.items
|
|
|
|
def to_json(self) -> str:
|
|
return json.dumps(
|
|
self._to_json(),
|
|
indent=2,
|
|
cls=JSONEncodeHelper,
|
|
sort_keys=True
|
|
)
|
|
|
|
|
|
def from_json(json:str):
|
|
# TODO
|
|
|
|
pass
|
|
|
|
class JSONEncodeHelper(json.JSONEncoder):
|
|
def default(self, o):
|
|
|
|
if isinstance(o, Message):
|
|
return o._to_json()
|
|
|
|
return super().default(o) |