79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
from abc import ABCMeta, abstractmethod
|
|
import json
|
|
from website_generator.utils import Registry
|
|
|
|
|
|
class ActionMetaclass(ABCMeta):
|
|
|
|
def __new__(cls, name, *args, **kwargs):
|
|
newclass = ABCMeta.__new__(cls, name, *args, **kwargs)
|
|
if name != 'Action':
|
|
register(newclass)
|
|
return newclass
|
|
|
|
|
|
class Action(metaclass=ActionMetaclass):
|
|
|
|
def __init__(self, **params):
|
|
for name, value in params.items():
|
|
setattr(self, name, value)
|
|
|
|
@abstractmethod
|
|
def __call__(self):
|
|
pass
|
|
|
|
|
|
class ActionRegistry(Registry):
|
|
|
|
def check_key(self, key):
|
|
assert isinstance(key, str), 'Action type must be a string.'
|
|
|
|
def check_value(self, value):
|
|
assert callable(value), 'Action must be a callable.'
|
|
|
|
def register(self, key, value=None):
|
|
"""
|
|
Register a generator action.
|
|
May be used a register(action) if the action has a defined type
|
|
(using the action.type attribute), or as register(type, action)
|
|
or register(action, type) to set a custom type.
|
|
"""
|
|
if value:
|
|
try:
|
|
# Try register(type, action)
|
|
return super().register(key, value)
|
|
except (KeyError, ValueError):
|
|
# Try register(action, type)
|
|
try:
|
|
return super().register(value, key)
|
|
except (KeyError, ValueError):
|
|
pass
|
|
raise
|
|
|
|
if not getattr(key, 'type', None):
|
|
raise KeyError(
|
|
'Action does not have a type. '
|
|
'Set the type attribute or use register(type, action)'
|
|
)
|
|
|
|
return super().register(key.type, key)
|
|
|
|
|
|
registry = ActionRegistry()
|
|
register = registry.register
|
|
unregister = registry.unregister
|
|
|
|
|
|
class DebugAction(Action):
|
|
type = 'debug'
|
|
|
|
def __call__(self):
|
|
def _default(obj):
|
|
if hasattr(obj, '__dict__'):
|
|
return vars(obj)
|
|
try:
|
|
return dict(obj)
|
|
except Exception:
|
|
return str(obj)
|
|
print(json.dumps(vars(self), default=_default, indent=4))
|