introduce global plugin manager

This commit is contained in:
holger krekel
2020-02-22 22:09:18 +01:00
parent cf6391d51b
commit d3c6f530e2
4 changed files with 47 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
from deltachat import capi, const from . import capi, const
from deltachat.capi import ffi from .capi import ffi
from deltachat.account import Account # noqa from .account import Account # noqa
from pkg_resources import get_distribution, DistributionNotFound from pkg_resources import get_distribution, DistributionNotFound
try: try:

View File

@@ -14,9 +14,12 @@ from .cutil import as_dc_charpointer, from_dc_charpointer, iter_array, DCLot
from .chat import Chat from .chat import Chat
from .message import Message from .message import Message
from .contact import Contact from .contact import Contact
from .eventlogger import EventLogger from . import eventlogger
from .tracker import ImexTracker from .tracker import ImexTracker
from .hookspec import AccountHookSpecs, account_hookimpl from . import hookspec
hookspec.Global._get_plugin_manager().register(eventlogger)
class Account(object): class Account(object):
@@ -36,17 +39,19 @@ class Account(object):
the default internal logging. the default internal logging.
:param os_name: this will be put to the X-Mailer header in outgoing messages :param os_name: this will be put to the X-Mailer header in outgoing messages
""" """
# initialize per-account plugin system
self._pm = hookspec.PerAccount._make_plugin_manager()
self.add_account_plugin(self)
self._dc_context = ffi.gc( self._dc_context = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, as_dc_charpointer(os_name)), lib.dc_context_new(lib.py_dc_callback, ffi.NULL, as_dc_charpointer(os_name)),
_destroy_dc_context, _destroy_dc_context,
) )
self._evlogger = EventLogger(self, logid)
self._threads = IOThreads(self._dc_context, self._evlogger._log_event)
# initialize per-account plugin system hook = hookspec.Global._get_plugin_manager().hook
self._pm = AccountHookSpecs._make_plugin_manager() hook.at_account_init(account=self, db_path=db_path, logid=logid)
self.add_account_plugin(self)
self.add_account_plugin(self._evlogger) self._threads = IOThreads(self._dc_context)
# send all FFI events for this account to a plugin hook # send all FFI events for this account to a plugin hook
def _ll_event(ctx, evt_name, data1, data2): def _ll_event(ctx, evt_name, data1, data2):
@@ -64,7 +69,7 @@ class Account(object):
self._configkeys = self.get_config("sys.config_keys").split() self._configkeys = self.get_config("sys.config_keys").split()
atexit.register(self.shutdown) atexit.register(self.shutdown)
@account_hookimpl @hookspec.account_hookimpl
def process_low_level_event(self, event_name, data1, data2): def process_low_level_event(self, event_name, data1, data2):
if event_name == "DC_EVENT_CONFIGURE_PROGRESS": if event_name == "DC_EVENT_CONFIGURE_PROGRESS":
if data1 == 0 or data1 == 1000: if data1 == 0 or data1 == 1000:

View File

@@ -1,5 +1,10 @@
import time import time
from .hookspec import account_hookimpl from .hookspec import account_hookimpl, global_hookimpl
@global_hookimpl
def at_account_init(account, logid):
account._evlogger = account.add_account_plugin(EventLogger(account, logid=logid))
class EventLogger: class EventLogger:

View File

@@ -2,14 +2,17 @@
import pluggy import pluggy
__all__ = ["account_hookspec", "account_hookimpl", "AccountHookSpecs"]
_account_name = "deltachat-account" _account_name = "deltachat-account"
account_hookspec = pluggy.HookspecMarker(_account_name) account_hookspec = pluggy.HookspecMarker(_account_name)
account_hookimpl = pluggy.HookimplMarker(_account_name) account_hookimpl = pluggy.HookimplMarker(_account_name)
_global_name = "deltachat-global"
global_hookspec = pluggy.HookspecMarker(_global_name)
global_hookimpl = pluggy.HookimplMarker(_global_name)
class AccountHookSpecs:
class PerAccount:
""" per-Account-instance hook specifications. """ per-Account-instance hook specifications.
Account hook implementations need to be registered with an Account instance. Account hook implementations need to be registered with an Account instance.
@@ -27,3 +30,22 @@ class AccountHookSpecs:
@account_hookspec @account_hookspec
def configure_completed(self, success): def configure_completed(self, success):
""" Called when a configure process completed. """ """ Called when a configure process completed. """
class Global:
""" global hook specifications using a per-process singleton plugin manager instance.
"""
_plugin_manager = None
@classmethod
def _get_plugin_manager(cls):
if cls._plugin_manager is None:
cls._plugin_manager = pm = pluggy.PluginManager(_global_name)
pm.add_hookspecs(cls)
return cls._plugin_manager
@global_hookspec
def at_account_init(self, account, logid):
""" called when `Account::__init__()` function starts executing. """