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)