Compare commits
2 commits
9c830e4f6c
...
4c42320c7c
Author | SHA1 | Date | |
---|---|---|---|
4c42320c7c | |||
f593db112c |
5 changed files with 43 additions and 24 deletions
|
@ -131,7 +131,6 @@ class MainProcess:
|
|||
if e.fatal:
|
||||
self._unload_plugin(e.source)
|
||||
except Exception as e:
|
||||
self._plugin_error
|
||||
logger.critical(f'Failure when processing {plugin_name} ({e}) - disabling...')
|
||||
logger.debug(format_exception(e))
|
||||
self._unload_plugin(plugin_name)
|
||||
|
@ -239,10 +238,7 @@ class MainProcess:
|
|||
if plugin_module is None:
|
||||
logger.error(f'Unknown plugin: {node.name}')
|
||||
else:
|
||||
res = await plugin_module._call(node.sub, node.tag, *node.args, **node.props, _ctx=global_ctx, _children=node.nodes)
|
||||
if node.alias:
|
||||
global_ctx[node.alias] = res
|
||||
|
||||
await plugin_module._kdl_call(node, global_ctx)
|
||||
|
||||
async def user_shutdown(self):
|
||||
for process_name, process in list(reversed(self.chat_processes.items())):
|
||||
|
|
|
@ -9,6 +9,8 @@ import kdl
|
|||
import quart
|
||||
|
||||
from ovtk_audiencekit.core.Config import kdl_parse_config, compute_dynamic
|
||||
from ovtk_audiencekit.utils import format_exception
|
||||
|
||||
|
||||
|
||||
class PluginError(Exception):
|
||||
|
@ -30,6 +32,7 @@ class OvtkBlueprint(quart.Blueprint):
|
|||
|
||||
class PluginBase(ABC):
|
||||
plugins = {}
|
||||
hooks = {} # the hookerrrrrrrr
|
||||
|
||||
def __init__(self, chat_processes, event_queue, name, global_ctx, _children=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
@ -56,24 +59,41 @@ class PluginBase(ABC):
|
|||
def __del__(self):
|
||||
if self.plugins.get(self._name) == self:
|
||||
del self.plugins[self._name]
|
||||
if self._name in self.hooks:
|
||||
del self.hooks[self._name]
|
||||
|
||||
async def _kdl_call(self, node, _ctx):
|
||||
args, props = compute_dynamic(node, _ctx=_ctx)
|
||||
subroutine = node.sub
|
||||
|
||||
if subroutine:
|
||||
func = self
|
||||
for accessor in subroutine:
|
||||
func = getattr(func, accessor)
|
||||
else:
|
||||
func = self.run
|
||||
|
||||
for hook in self.hooks.values():
|
||||
try:
|
||||
res = hook(self._name, node, _ctx)
|
||||
if asyncio.iscoroutinefunction(hook):
|
||||
await res
|
||||
except Exception as e:
|
||||
self.logger.warning(f'Failed to run plugin hook: {e}')
|
||||
self.logger.debug(format_exception(e))
|
||||
|
||||
async def _call(self, subroutine, tag, *args, **kwargs):
|
||||
try:
|
||||
if subroutine:
|
||||
func = self
|
||||
for accessor in subroutine:
|
||||
func = getattr(func, accessor)
|
||||
else:
|
||||
func = self.run
|
||||
res = func(*args, **kwargs)
|
||||
result = func(*args, _children=node.nodes, _ctx=_ctx, **props)
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
res = await res
|
||||
return res
|
||||
result = await result
|
||||
except Exception as e:
|
||||
if isinstance(e, KeyboardInterrupt):
|
||||
raise e
|
||||
raise PluginError(self._name, str(e)) from e
|
||||
|
||||
if node.alias:
|
||||
_ctx[node.alias] = result
|
||||
|
||||
async def _tick(self, *args, **kwargs):
|
||||
try:
|
||||
res = self.tick(*args, **kwargs)
|
||||
|
@ -98,6 +118,7 @@ class PluginBase(ABC):
|
|||
raise e
|
||||
raise PluginError(self._name, str(e)) from e
|
||||
|
||||
|
||||
# Base class helpers
|
||||
def broadcast(self, event):
|
||||
"""Send event to every active chat"""
|
||||
|
@ -106,7 +127,10 @@ class PluginBase(ABC):
|
|||
continue
|
||||
proc.control_pipe.send(event)
|
||||
|
||||
async def execute_kdl(self, nodes, *py_args, _ctx={}, **py_props):
|
||||
def register_hook(self, hook):
|
||||
self.hooks[self._name] = hook
|
||||
|
||||
async def execute_kdl(self, nodes, _ctx={}):
|
||||
"""
|
||||
Run other plugins as configured by the passed KDL nodes collection
|
||||
If this was done in response to an event, pass it as 'event' in _ctx!
|
||||
|
@ -114,16 +138,14 @@ class PluginBase(ABC):
|
|||
_ctx = copy.deepcopy({**self._global_ctx, **_ctx})
|
||||
for node in nodes:
|
||||
try:
|
||||
args, props = compute_dynamic(node, _ctx=_ctx)
|
||||
target = self.plugins.get(node.name)
|
||||
if target is None:
|
||||
self.logger.warning(f'Could not find plugin or builtin with name {node.name}')
|
||||
break
|
||||
result = await target._call(node.sub, node.tag, *args, *py_args, **props, _ctx=_ctx, **py_props, _children=node.nodes)
|
||||
if node.alias:
|
||||
_ctx[node.alias] = result
|
||||
await target._kdl_call(node, _ctx)
|
||||
except Exception as e:
|
||||
self.logger.warning(f'Failed to execute defered KDL: {e}')
|
||||
self.logger.debug(format_exception(e))
|
||||
break
|
||||
|
||||
|
||||
|
@ -134,6 +156,7 @@ class PluginBase(ABC):
|
|||
"""
|
||||
self._event_queue.put_nowait(event)
|
||||
|
||||
|
||||
# User-defined
|
||||
async def setup(self, *args, **kwargs):
|
||||
"""Called when plugin is being loaded."""
|
||||
|
|
|
@ -87,7 +87,7 @@ class JailPlugin(PluginBase):
|
|||
if isinstance(event, Message):
|
||||
if self.jail_command.invoked(event):
|
||||
try:
|
||||
args = self.jail_command.parse(event.text)
|
||||
args, _ = self.jail_command.parse(event.text)
|
||||
end_date = maya.when(args['length'], prefer_dates_from='future')
|
||||
deets = self.chats[event.via].shared.api.get_user_details(args['username'])
|
||||
if deets is None:
|
||||
|
@ -117,7 +117,7 @@ class JailPlugin(PluginBase):
|
|||
self.send_to_bus(weewoo)
|
||||
elif self.unjail_command.invoked(event):
|
||||
try:
|
||||
args = self.jail_command.parse(event.text)
|
||||
args, _ = self.jail_command.parse(event.text)
|
||||
deets = self.chats[event.via].shared.api.get_user_details(args['username'])
|
||||
if deets is None:
|
||||
raise ValueError()
|
||||
|
|
|
@ -47,7 +47,7 @@ class ShoutoutPlugin(PluginBase):
|
|||
if isinstance(event, Message):
|
||||
if self.command and self.command.invoked(event):
|
||||
try:
|
||||
args = self.command.parse(event.text)
|
||||
args, _ = self.command.parse(event.text)
|
||||
except ArgumentError as e:
|
||||
msg = SysMessage(self._name, str(e), replies_to=event)
|
||||
self.chats[event.via].send(msg)
|
||||
|
|
|
@ -139,7 +139,7 @@ class CommandPlugin(PluginBase):
|
|||
|
||||
if self.help_cmd.invoked(event):
|
||||
try:
|
||||
args = self.help_cmd.parse(event.text)
|
||||
args, _ = self.help_cmd.parse(event.text)
|
||||
except argparse.ArgumentError as e:
|
||||
msg = SysMessage(self._name, f"{e}. See !help {self.help_cmd.name}", replies_to=event)
|
||||
self.chats[event.via].send(msg)
|
||||
|
|
Loading…
Add table
Reference in a new issue