mirror of
https://github.com/norohind/jubilant-system-core.git
synced 2025-04-13 10:07:13 +03:00
Introduce hooks support
This commit is contained in:
parent
afdecb4cd8
commit
76ea80b178
@ -1,5 +1,8 @@
|
||||
from . import Queries
|
||||
import DB
|
||||
import HookSystem
|
||||
|
||||
hook_system = HookSystem.HookSystem()
|
||||
|
||||
|
||||
def update_squad(squad_id: int, suppress_absence=False) -> None | int:
|
||||
@ -15,10 +18,12 @@ def update_squad(squad_id: int, suppress_absence=False) -> None | int:
|
||||
# Squad not found FDEV
|
||||
if not suppress_absence:
|
||||
operation_id = DB.delete_squadron(squad_id)
|
||||
hook_system.notify_deleted(operation_id)
|
||||
|
||||
else:
|
||||
# Then we got valid squad_info dict
|
||||
news_info = Queries.get_squad_news(squad_id)
|
||||
operation_id = DB.insert_info_news(news_info, squad_info)
|
||||
hook_system.notify_inserted(operation_id)
|
||||
|
||||
return operation_id
|
||||
|
11
Hook.py
Normal file
11
Hook.py
Normal file
@ -0,0 +1,11 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class Hook(ABC): # See at Hook class as to observer in observer pattern
|
||||
"""
|
||||
In order to implement hook, subclass this class and pass instance to HookSystem.add_hook
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def update(self, operation_id: int) -> None:
|
||||
raise NotImplemented
|
58
HookSystem.py
Normal file
58
HookSystem.py
Normal file
@ -0,0 +1,58 @@
|
||||
import os
|
||||
import functools
|
||||
import threading
|
||||
from Hook import Hook
|
||||
import importlib.machinery
|
||||
|
||||
|
||||
def check_int(func: callable) -> callable:
|
||||
@functools.wraps(func)
|
||||
def decorated(self, operation_id: int | None) -> None:
|
||||
if type(operation_id) == int:
|
||||
return func(self, operation_id)
|
||||
|
||||
return decorated
|
||||
|
||||
|
||||
class HookSystem:
|
||||
hooks_inserted: list[Hook] = list()
|
||||
hooks_deleted: list[Hook] = list()
|
||||
|
||||
def __init__(self):
|
||||
# hooks load
|
||||
for file_name in sorted(os.listdir('hooks')):
|
||||
if file_name.endswith('.py') and not file_name[0] in ['.', '_']:
|
||||
path = os.path.join('hooks', file_name)
|
||||
hook_name = file_name[:-3]
|
||||
module = importlib.machinery.SourceFileLoader(hook_name, path).load_module()
|
||||
setup_func = getattr(module, 'setup', None)
|
||||
if setup_func is not None:
|
||||
setup_func(self)
|
||||
|
||||
else:
|
||||
raise AttributeError(f'No setup method in {file_name} hook')
|
||||
|
||||
def add_on_insert_hook(self, hook: Hook) -> None:
|
||||
self.hooks_inserted.append(hook)
|
||||
|
||||
def remove_on_insert_hook(self, hook: Hook) -> None:
|
||||
self.hooks_inserted.remove(hook)
|
||||
|
||||
def add_on_delete_hook(self, hook: Hook) -> None:
|
||||
self.hooks_deleted.append(hook)
|
||||
|
||||
def remove_on_delete_hook(self, hook: Hook) -> None:
|
||||
self.hooks_deleted.remove(hook)
|
||||
|
||||
@check_int
|
||||
def notify_inserted(self, operation_id: int | None) -> None:
|
||||
self._notify(operation_id, self.hooks_inserted)
|
||||
|
||||
@check_int
|
||||
def notify_deleted(self, operation_id: int) -> None:
|
||||
self._notify(operation_id, self.hooks_deleted)
|
||||
|
||||
@staticmethod
|
||||
def _notify(operation_id, hooks: list[Hook]) -> None:
|
||||
for hook in hooks:
|
||||
threading.Thread(target=hook.update, args=(operation_id,)).start()
|
11
hooks/testHook.py
Normal file
11
hooks/testHook.py
Normal file
@ -0,0 +1,11 @@
|
||||
from HookSystem import HookSystem
|
||||
from Hook import Hook
|
||||
|
||||
|
||||
class testHook(Hook):
|
||||
def update(self, operation_id: int) -> None:
|
||||
print('update')
|
||||
|
||||
|
||||
def setup(hook_system: HookSystem) -> None:
|
||||
hook_system.add_on_insert_hook(testHook())
|
Loading…
x
Reference in New Issue
Block a user