From 6eff05ed83e358f276ee51a26aafa8d9ce8fc2a2 Mon Sep 17 00:00:00 2001 From: Benjamin Braatz Date: Wed, 24 Feb 2021 10:04:23 +0100 Subject: [PATCH] Unregister, aliases and some other improvements --- controlpi/main.py | 68 +++++++++++++++++++++++++------------- controlpi/plugins/alias.py | 21 ++++++++++++ controlpi/plugins/delay.py | 10 +++--- controlpi/plugins/log.py | 4 +-- 4 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 controlpi/plugins/alias.py diff --git a/controlpi/main.py b/controlpi/main.py index 1c2d6bc..76081c8 100644 --- a/controlpi/main.py +++ b/controlpi/main.py @@ -7,23 +7,14 @@ import importlib import controlpi.plugins -def get_triggered(message, triggers): - result = [] - for key in triggers: - if key == '*': - result.extend(triggers[key]) - elif key in message: - value = message[key] - if value in triggers[key]: - result.extend(get_triggered(message, triggers[key][value])) - return result - - class ControlPi: def __init__(self): self._queue = asyncio.Queue() self._triggers = {} + async def send(self, message): + await self._queue.put(message) + def register(self, message_template, async_callback): current = self._triggers for key in message_template: @@ -37,30 +28,55 @@ class ControlPi: current['*'] = [] current['*'].append(async_callback) - async def send(self, message): - await self._queue.put(message) + def _unregister(self, async_callback, triggers): + for key in triggers: + if key == '*': + while True: + try: + triggers[key].remove(async_callback) + except ValueError: + break + else: + for value in triggers[key]: + self._unregister(async_callback, triggers[key][value]) + + def unregister(self, async_callback): + self._unregister(async_callback, self._triggers) + + def _get_triggered(self, message, triggers): + result = [] + for key in triggers: + if key == '*': + result.extend(triggers[key]) + elif key in message: + value = message[key] + if value in triggers[key]: + result.extend(self._get_triggered(message, + triggers[key][value])) + return result async def run(self): while True: message = await self._queue.get() - for async_callback in get_triggered(message, self._triggers): + for async_callback in self._get_triggered(message, + self._triggers): asyncio.create_task(async_callback(message)) self._queue.task_done() async def main(): - plugins = {name: importlib.import_module(name) + plugins = {name: importlib.import_module(controlpi.plugins.__name__ + + '.' + name) for finder, name, ispkg - in pkgutil.iter_modules(controlpi.plugins.__path__, - controlpi.plugins.__name__ + ".")} - control_pi = ControlPi() - coros = [control_pi.run()] + in pkgutil.iter_modules(controlpi.plugins.__path__)} + coros = [] with open(sys.argv[1]) as json_data: conf = json.load(json_data) + control_pi = ControlPi() + coros.append(control_pi.run()) for plugin_name in conf: - full_plugin_name = 'controlpi.plugins.' + plugin_name - if full_plugin_name in plugins: - module = plugins[full_plugin_name] + if plugin_name in plugins: + module = plugins[plugin_name] plugin_confs = conf[plugin_name] for plugin_conf in plugin_confs: coros.append(module.init(control_pi, plugin_conf)) @@ -72,3 +88,9 @@ if __name__ == '__main__': asyncio.run(main()) except KeyboardInterrupt: pass + except IndexError: + print("Path to configuration JSON file has to be given!") + except FileNotFoundError: + print("Given path to configuration JSON file is not a file!") + except json.decoder.JSONDecodeError: + print("Given configuration JSON file is not a JSON file!") diff --git a/controlpi/plugins/alias.py b/controlpi/plugins/alias.py new file mode 100644 index 0000000..56131e7 --- /dev/null +++ b/controlpi/plugins/alias.py @@ -0,0 +1,21 @@ +import asyncio +import functools + + +async def alias(control_pi, name, aliasfor, message): + alias_message = {"name": name} + for key in message: + if key not in aliasfor: + alias_message[key] = message[key] + await control_pi.send(alias_message) + + +async def init_finished(name): + print(f"{name} initialised") + + +def init(control_pi, conf): + callback = functools.partial(alias, control_pi, + conf['name'], conf['aliasfor']) + control_pi.register(conf['aliasfor'], callback) + return init_finished(conf['name']) diff --git a/controlpi/plugins/delay.py b/controlpi/plugins/delay.py index 95e02eb..3138b54 100644 --- a/controlpi/plugins/delay.py +++ b/controlpi/plugins/delay.py @@ -4,7 +4,7 @@ import functools async def waiter(control_pi, name, seconds, message): await asyncio.sleep(seconds) - await control_pi.send({"name": name, "event": "delay finished"}) + await control_pi.send({"name": name, "event": "finished"}) async def init_finished(name): @@ -12,9 +12,7 @@ async def init_finished(name): def init(control_pi, conf): - control_pi.register({"name": conf['name'], "command": "start"}, - functools.partial(waiter, - control_pi, - conf['name'], - conf['seconds'])) + callback = functools.partial(waiter, control_pi, + conf['name'], conf['seconds']) + control_pi.register({"name": conf['name'], "command": "start"}, callback) return init_finished(conf['name']) diff --git a/controlpi/plugins/log.py b/controlpi/plugins/log.py index 2b54318..7f3aa37 100644 --- a/controlpi/plugins/log.py +++ b/controlpi/plugins/log.py @@ -10,6 +10,6 @@ async def init_finished(name): def init(control_pi, conf): - control_pi.register(conf['filter'], - functools.partial(logger, conf['name'])) + callback = functools.partial(logger, conf['name']) + control_pi.register(conf['filter'], callback) return init_finished(conf['name']) -- 2.34.1